Bison 野牛优先';行不通

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

这是我的flex代码

%{
 #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)
。这会产生完全不同的结果。关于运算符优先级,它说:不同运算符的相对优先级由它们声明的顺序控制。老实说,我也遇到了这个问题。我想出了上面的例子来规避自发的“优先忽略”。。请参阅“优先级”部分下的警告。这家伙只是复制粘贴了它。