这是我的灵活代码
%{
#include "fl.tab.h"
%}
%%
[0-9]+ { yylval = atoi(yytext);
return INTEGER; }
\n return 0;
[ \t] ;
. return yytext[0];
%%
我的野牛代码
%{
#include <stdio.h>
%}
%token INTEGER
%left '+' '-'
%left '*'
%%
Statement : expr {printf("%d\n",$1);}
;
expr : expr '+' INTEGER {$$ = $1 + $3;}
| expr '-' INTEGER {$$ = $1 - $3;}
| expr '*' INTEGER {$$ = $1 * $3;}
| INTEGER {$$ = $1;}
;
%%
int main(void){
yyparse();
return 0;
}
当我输入4 + 5 * 2时,它输出为18.但正确的答案应该是14.我在哪里弄错了?
答案 0 :(得分:7)
您的问题是每条规则都有expr OP INTEGER
。
你拥有野牛的方式将其解析为:
expr * 2 -> (4 + 5) * 2
强制优先顺序向左移动而不是优先级由您的优先规则决定。
优先级仅适用于解析文本的方法不止一种,而不是您拥有的方法,请尝试
expr : expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| INTEGER {$$ = $1;}
;
这样5 + 4 * 2
可以解析为((5 + 4) * 2)
或(5 + (4 * 2))
,并且bison将查询优先级以确定正确的解析。
答案 1 :(得分:2)
您可以使用缩小强制优先级:
expr : sum ; sum : sum '+' product {$$ = $1 + $3;} | product ; product : number '*' product {$$ = $1 * $3;} | number ; number : INTEGER ;
这样,product
会在sum
之前缩短。
答案 2 :(得分:0)
我认为所有规则都优先于'INTEGER',因为它是最后一个终端
答案 3 :(得分:-1)
例如考虑以下语法:
%nonassoc "="
%left "+"
%left "*"
%precedence "("
%%
stmt:
exp
| "var" "=" exp
;
exp:
exp "+" exp
| exp "*" "num"
| "(" exp ")"
| "num"
;
Bison报道:
warning: useless precedence and associativity for "="
%nonassoc "="
^^^
warning: useless associativity for "*", use %precedence
%left "*"
^^^
warning: useless precedence for "("
%precedence "("
^^^
将使用以下指令获得完全相同的解析器:
%left "+"
%precedence "*"
请试试这个你会得到正确答案.....