私は 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
しかし、乗算が 2 番目に発生すると、間違った答えが得られます。
> ./foo
4 + 5 * 2
= 18
%left '+' '-'
行をyacc ファイルに追加すると%left '*' '/'
、これが修正されるはずでしたが、修正されませんでした。誰でも理由を教えてもらえますか?