我一直在尝试编写一个解析器来评估单个文件中的多个算术运算。每个表达式都会计算并且工作正常,除了最后我打印出这个
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
我认为问题不在于 EOF,而在于事实上你的解析器没有处理空行的情况。它可以完美地处理文件而没有空行!
将 this 放入 yacc 文件中可以与您的输入一起使用(当它遇到一个时,这将打印一个空行,仅作为示例):
A : A B '\n' {printf("%d\n", $2);}
| A '\n' {printf("\n");}
|
;
因此,您根本不需要显式解析 EOF。