Reputation: 94
I am working with lex and yacc. following is the program for lex and yacc calculator. while excuting yacc file. Please help me soving this problem . i am getting following errors:
This is the error:
conflicts: 20 shift/reduce
//YACC program
%{
#include<stdio.h>
#include<math.h>
extern void printsymbol();
struct symboltable
{
char name[20];
double value;
}ST[20];
%}
%union
{
double p;
}
%token <p> NUM
%token <p> IDENTIFIER
%token SIN COS TAN ROOT
%left '+' '-'
%left '*' '/'
%type <p> E
%%
Edash:E';'{printf("\n=%f",$1);printsymbol();}
|Edash E';'{printf("\n=%f",$2);printsymbol();}
E: E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|NUM {$$=$1;}
|IDENTIFIER {$$=ST[(int)]$1.value;}
|'('E')' {$$=$2;}
|IDENTIFIER'='E {$$=ST[(int)]$1.value=$3;}
|SIN E {$$=sin($2*3.141/180);}
|COS E {$$=sin($2*3.141/180);}
|TAN E {$$=sin($2*3.141/180);}
|ROOT E {$$=sqrt($2);}
%%
int main()
{
yyparse();
}
yyerror()
{
printf("Error Found..!");
}
Upvotes: 0
Views: 615
Reputation: 126203
Your conflicts come from the rules:
|IDENTIFIER '=' E
|SIN E
|COS E
|TAN E
|ROOT E
Because none of these rules have precedences set for them (not set on any of the tokens in these rules), when you get an input like SIN X + Y
, the parser doesn't know whether to
parse it as(SIN X) + Y
or SIN (X + Y)
You can fix it by setting precedences for all these rules, which is most easily done by adding a line
%nonassoc '=' SIN COS TAN ROOT
setting precedence values for all of those tokens, which will be inherited by the rules. Its up to you whether they should be higher or lower precedence than the binary operators. For normal conventions, you probably want =
as lower precedence and the functions as higher precedence (which means you actually need two new lines rather than having them all in one line)
Upvotes: 3
Reputation: 58578
You must run yacc
with the -v
option to generate a file called y.output
. There you can find clues about the conflicts. The file shows the detailed states of the generated parser, and which states have conflicts in them between shifting a particular token or reducing via some rule.
A possible issue with your grammar is this:
E : IDENTIFIER '=' E
Suppose you have you have
X = 3 + 5
what is the precedence of =
versus +
? If the parser has just seen X = 3
and the next lookahead token is +
, what should it do? Should it reduce X = 3
to E
by the rule E : IDENTIFIER '=' E
or should it shift the +
and continue scanning a longer right-hand-side E
?
Look at y.output
and see if it confirms this hypothesis.
Upvotes: 2