The superiority of bison does not work

This is my flexible code.

%{
 #include "fl.tab.h"
%} 
    %% 
    [0-9]+  { yylval = atoi(yytext); 
        return INTEGER; } 
    \n  return 0;   
    [ \t]   ;   
    .   return yytext[0];
    %% 

And my bison code

%{ 
    #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;
}

when I enter 4 + 5 * 2, it gives the result as 18. But the correct answer should be 14. Where am I mistaken?

+3
source share
4 answers

Your problem is what you have expr OP INTEGERfor each rule.

The way you have it, the bison analyzes it as:

expr * 2 -> (4 + 5) * 2

It forces the priority to go left instead of the priority determined by your priority rules.

Priority only applies if there are several ways to analyze the text instead of what you have, try

expr :  expr '+' expr  {$$ = $1 + $3;}
     |  expr '-' expr  {$$ = $1 - $3;}
     |  expr '*' expr  {$$ = $1 * $3;}        
     |  INTEGER {$$ = $1;}
     ;

Thus, it 5 + 4 * 2can be parsed as ((5 + 4) * 2)or (5 + (4 * 2)), and the bison will cope with priority to determine the correct parsing.

+7

:

expr    : sum
        ;

sum     : sum '+' product {$$ = $1 + $3;}
        | product
        ;

product : number '*' product {$$ = $1 * $3;}
        | number
        ;

number  : INTEGER
        ;

, product sum.

+2

I think that all rules have priority "INTEGER", since this is the last terminal

0
source

Consider, for example, the following grammar:

           %nonassoc "="
           %left "+"
           %left "*"
           %precedence "("
           %%
           stmt:
             exp
           | "var" "=" exp
           ;

           exp:
             exp "+" exp
           | exp "*" "num"
           | "(" exp ")"
           | "num"
           ;

Bison Reports:

           warning: useless precedence and associativity for "="
            %nonassoc "="
                      ^^^
           warning: useless associativity for "*", use %precedence
            %left "*"
                  ^^^
           warning: useless precedence for "("
            %precedence "("
                        ^^^

Instead, we would have the same parser with the following directives:

           %left "+"
           %precedence "*"

try this, you will get the correct answer .....

-1
source

Source: https://habr.com/ru/post/1789712/


All Articles