rahuldeshmaane
rahuldeshmaane

Reputation: 94

Shift Reduce Error In YACC

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

Answers (2)

Chris Dodd
Chris Dodd

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

Kaz
Kaz

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

Related Questions