Search code examples
csyntaxcompilationbison

Wrong rule used in bison


I am trying to perform a syntax analysis using bison, but it uses the wrong rule at one point and I didn't manage to find how to fix it. I have a few rules but these ones seem to be the source of the problem :

method : vars statements;

vars : //empty
  | vars var;

var : type IDENTIFIER ';';

type : IDENTIFIER;

statements : //empty
  | statements statement;

statement : IDENTIFIER '=' e ';';

e : (...)

With IDENTIFIER being a simple regex matching [a-zA-Z]*

So basically, if I write that :

int myint;
myint = 12;

Since myint is an identifier, bison seems to still try to match it on the second line as a type and then matches the whole thing as a var and not as a statement. So I get this error (knowing that ASSIGN is '=') :

syntax error, unexpected ASSIGN, expecting IDENTIFIER

Edit : Note that bison is indicating that there are shift/reduce errors, so it may be linked (as said in the answers).


Solution

  • The problem you're having is coming from the default resolution of the shift-reduce conflict you have due to the empty statements rule -- it needs to know whether to reduce the empty statement and start matching statements, or shift the IDENTIFIER that might begin another var. So it decides to shift, which puts it down the var path.

    You can avoid this problem by refactoring the grammar to avoid empty productions:

    method: vars | vars statements | statements ;
    vars: var | vars var ;
    statements : statement | statements statement ;
    ... rest the same
    

    which avoids needing to know whether something is var or a statement until after shifting far enough into it to tell.