YACC 解析器中 YYEOF 的正确用法

问题描述 投票:0回答:1

我一直在尝试编写一个解析器来评估单个文件中的多个算术运算。每个表达式都会计算并且工作正常,除了最后我打印出这个

Error
yyeerror()
正在被调用)。因此,我试图在遇到
EOF
字符时立即终止并实现此预定义宏
YYEOF
。我仍然打印了最后一行多余的行。

莱克斯:

%{

#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"

void yyerror();
extern int yylval;

%}

%%

[ \t] ;

[0-9]+ {yylval = atoi(yytext); return INTEGER;}

[\-\+\*\/\n\(\)] return *yytext;

<<EOF>> return YYEOF;

. yyerror();

%%

int yywrap() {
    return 1;
}

yacc:

%{

#include <stdio.h>
#include <stdlib.h>

int yylex();
void yyerror();
extern FILE* yyin;

%}

%start A
%token INTEGER
%left '+' '-'
%left '*' '/'

%%

A : A B '\n' {printf("%d\n", $2);}
  | YYEOF {exit(0);}
  |
  ;

B : B '+' B {$$ = $1 + $3;}
  | B '-' B {$$ = $1 - $3;}
  | B '*' B {$$ = $1 * $3;}
  | B '/' B {$$ = $1 / $3;}
  | '+' B {$$ = $2;}
  | '-' B {$$ = -$2;}
  | '(' B ')' {$$ = $2;}
  | INTEGER
  ;

%%

void yyerror() {
    fprintf(stderr, "Error\n");
    exit(0);
}

int main(int argc, char** argv) {
    yyin = fopen(argv[1], "r");
    yyparse();
}

输入:

输出:

t0000@TTTT:~/practice$ ./parser input.txt
63
55
40
0
Error
parsing flex-lexer yacc
1个回答
0
投票

认为问题不在于 EOF,而在于事实上你的解析器没有处理空行的情况。它可以完美地处理文件而没有空行!

this 放入 yacc 文件中可以与您的输入一起使用(当它遇到一个时,这将打印一个空行,仅作为示例):

A : A B '\n' {printf("%d\n", $2);}
  | A '\n' {printf("\n");}
  |
  ;

因此,您根本不需要显式解析 EOF。

© www.soinside.com 2019 - 2024. All rights reserved.