我正在学习 yacc,而我从书中得到的这段代码片段似乎没有正确应用优先规则。
这是yacc文件:
%{
#include <stdio.h>
extern int yylex();
void yyerror (char const *msg);
%}
%token NAME NUMBER
%left '+' '-'
%left '*' '/'
%%
statement: NAME '=' expression
| expression { printf("= %d\n", $1); }
;
expression: expression '+' NUMBER { $$ = $1 + $3; }
| expression '-' NUMBER { $$ = $1 - $3; }
| expression '*' NUMBER { $$ = $1 * $3; }
| expression '/' NUMBER { if ($3) $$ = $1 / $3;
else yyerror("divide by zero"); }
| '-' expression { $$ = -$2; }
| '(' expression ')' { $$ = $2; }
| NUMBER { $$ = $1; }
;
%%
这是法例:
%{
#include "y.tab.h"
#include <stdio.h>
extern int yylval;
%}
%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[ \t] { ; }
\n { return 0; }
. { return yytext[0]; }
%%
我编译它:
lex foo.l
yacc -d foo.y
clang -o foo lex.yy.c y.tab.c -ly -ll
运行它乘法优先给出正确的答案:
> ./foo
3 * 2 + 1
= 7
但是当乘法第二次发生时,它给出了错误的答案:
> ./foo
4 + 5 * 2
= 18
%left '+' '-'
在 yacc 文件中添加这些行%left '*' '/'
应该可以解决这个问题,但他们没有。谁能告诉我为什么?