Reputation: 716
This is my flex 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 input 4 + 5 * 2 it give the output as 18. But the correct answer should be 14. Where am i getting it wrong ?
Upvotes: 4
Views: 4006
Reputation: 25
Consider for instance 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 "("
^^^
One would get the exact same parser with the following directives instead:
%left "+"
%precedence "*"
please try this you will get right answer.....
Upvotes: -2
Reputation: 91
Your problem is that you have expr OP INTEGER
for each rule.
The way you have it bison parses it as:
expr * 2 -> (4 + 5) * 2
It forces precedence to go to the left instead of precedence being determined by your precedence rules.
Precedence only applies when there is more than one way to parse the text, instead of what you have, try
expr : expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| INTEGER {$$ = $1;}
;
That way 5 + 4 * 2
can be parsed as either ((5 + 4) * 2)
or (5 + (4 * 2))
, and bison will consult precedence to determine the correct parse.
Upvotes: 9
Reputation: 151
I think all rules have precedence of 'INTEGER' since it is the last terminal
Upvotes: 0
Reputation: 34652
You can force precedence using reduction:
expr : sum ; sum : sum '+' product {$$ = $1 + $3;} | product ; product : number '*' product {$$ = $1 * $3;} | number ; number : INTEGER ;
That way, product
is reduced before sum
.
Upvotes: 2