Search code examples
if-statementcompiler-constructiongrammarbison

Bison dangling else


I have the following rule in my grammar:

block:                  TLBRACE statements TRBRACE
                        | TLBRACE TRBRACE
                        ;


statements:             statement 
                        | statements statement 
                        ;

statement:              TIF TLPAREN expression TRPAREN TTHEN statement
                        | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement
                        | TWHILE TLPAREN expression TRPAREN statement 
                        | TDO statement TLPAREN expression TRPAREN 
                        | TFOR TLPAREN forinits TSEMICOLON expression TSEMICOLON expressions TRPAREN statement 
                        | block 
                        | declaration TSEMICOLON
                        | expression TSEMICOLON
                        ;

I'm aware of the dangling else problem. That's why I specified "%left TELSE" at the top of the grammar file. Anyway, even if I instructed Bison to give precedence to TELSE token a shift/reduce conflict is generated. I tried also to remove the "%left TELSE" command (just to see if it makes any difference) and nothing changes. I always have the same shift/reduce conflict.

The output I get with the --verbose flag to Bison is:

State 117

   32 statement: "if" "(" expression ")" "then" statement .  ["identifier", "string value", "double", "int", "lint", "message", "string", "double value", "int value", "(", "{", "}", "-", "do", "else", "for", "if", "while", "binary not"]
   33          | "if" "(" expression ")" "then" statement . "else" statement

    "else"  shift and going to state 122

    "else"    [reducing with rule 32 (statement)]
    $default  reducing with rule 32 (statement) 

Solution

  • I got rid of the conflict when declaring %left TTHEN. I can't give you a full explanation but operator precedence has something to do with comparing operators after one and another.