Resolving Bison Shift-Reduce Conflicts for If-Else Statements with Virtual Token Priority

selection_statement
    : IF_P LPAREN expr RPAREN stmt_e ELSE_P stmt_e
    | IF_P LPAREN expr RPAREN stmt_e %prec LOW_PRI
    | SWITCH_P LPAREN expr RPAREN stmt_e
    ;

Bison may flag a shift/reduce conflict on token ELSE_P when parsing nested if-else structures like if (...) if (...) stmt • ELSE stmt. The parser cannot decide whether to shift ELSE_P to complete the inner if-else rule or reduce the inner partial if rule (IF_P LPAREN expr RPAREN stmt) and complete the outer if-else later.

The correct behavior for if-else statements is closest matching, meaning the parser should shift ELSE_P. To enforce this, define a virtual token with lower priority than ELSE_P using Bison precedence directives, then apply it to the single if rule:

bison
%left LOW_PRI
%left ELSE_P

When priorities are compared:

  • If a token’s priority is higher than the rule’s, Bison shifts.
  • If a rule’s priority is higher, Bison reduces.
  • For identical priorities, left associativity reduces, right shifts, and non-associativity erors.

Bison’s nonassoc directive defines non-associative operators that cannot appear consecutively (e.g., a < b < c). This helps eliminate ambiguous grammars upfront by rejecting invalid seuqences.

Tags: bison yacc Shift-Reduce Conflict If-Else Parsing Grammar Precedence

Posted on Sat, 08 Aug 2026 16:27:17 +0000 by sintax63