野牛优先权不起作用

时间:2011-02-03 10:47:14

标签: bison

这是我的灵活代码

%{
 #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.我在哪里弄错了?

4 个答案:

答案 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 "*"

请试试这个你会得到正确答案.....