Bison 野牛优先';行不通
这是我的flex代码Bison 野牛优先';行不通,bison,Bison,这是我的flex代码 %{ #include "fl.tab.h" %} %% [0-9]+ { yylval = atoi(yytext); return INTEGER; } \n return 0; [ \t] ; . return yytext[0]; %% 还有我的野牛密码 %{ #include <stdio.h> %} %token INTEGER %le
%{
#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;
}
%{
#包括
%}
%令牌整数
%左'+''-'
%左'*'
%%
语句:expr{printf(“%d\n”,$1);}
;
expr:expr'+'整数{$$=$1+$3;}
|expr'-'整数{$$=$1-$3;}
|expr'*'整数{$$=$1*$3;}
|整数{$$=$1;}
;
%%
内部主(空){
yyparse();
返回0;
}
当我输入4+5*2时,输出为18。但正确答案应该是14。我哪里弄错了?您可以使用缩减强制优先级: expr : sum ; sum : sum '+' product {$$ = $1 + $3;} | product ; product : number '*' product {$$ = $1 * $3;} | number ; number : INTEGER ; 表达式:总和 ; sum:sum'+'乘积{$$=$1+$3;} |产品 ; 产品:编号“*”产品{$$=$1*$3;} |数 ; 数字:整数 ;
这样,
product
在sum
之前减少,我认为所有规则都具有“INTEGER”的优先级,因为它是最后一个终端您的问题是每个规则都有expr OP INTEGER
按您的方式,bison将其解析为:
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将参考优先级来确定正确的解析。例如,考虑以下语法:
%nonassoc "="
%left "+"
%left "*"
%precedence "("
%%
stmt:
exp
| "var" "=" exp
;
exp:
exp "+" exp
| exp "*" "num"
| "(" exp ")"
| "num"
;
野牛报告:
warning: useless precedence and associativity for "="
%nonassoc "="
^^^
warning: useless associativity for "*", use %precedence
%left "*"
^^^
warning: useless precedence for "("
%precedence "("
^^^
可以使用以下指令获得完全相同的解析器:
%left "+"
%precedence "*"
请尝试此操作,您将得到正确答案。…否。
%left
表示关联性<代码>1+2+3在左关联时减少为(1+2)+3
。对于正确的关联性,它应该是1+(2+3)
。如果我不定义关联性会发生什么?好问题。我想,它默认为左关联。替换不是您想要的:1-2-3
实际上是右关联的1-(2-3)
。这会产生完全不同的结果。关于运算符优先级,它说:不同运算符的相对优先级由它们声明的顺序控制。老实说,我也遇到了这个问题。我想出了上面的例子来规避自发的“优先忽略”。。请参阅“优先级”部分下的警告。这家伙只是复制粘贴了它。