Search code examples
javascriptparsingbisonshift-reduce-conflictjison

Empty blocks and empty objects grammar conflict warnings


I'm trying to implement a parser in Jison. The parser has support for both JSON objects: { a: 1 } and blocks: if (true) { statement(); }.

My grammar looks like:

block:
  : '{' '}'
  | '{' statementList '}'
  ;

objectExpression:
  : '{' '}'
  | '{' properties '}'
  ;

There's a {} rule in both block and objectExpression because I need to support both empty objects and empty blocks.

It works, but it outputs lots of warnings such as:

Conflict in grammar: multiple actions possible when lookahead token is ; in state 52
- reduce by rule: objectExpression -> { }
- reduce by rule: block -> { }

How can I fix or suppress these warnings?


Solution

  • The string {} could be parsed either as a block, or as an objectExpression. You have a few choices.

    In Javascript parsers, if there is an ambiguity between block and objectExpression, it will choose the one that comes first in the parent rule. In the following expression, the empty block will be preferred over the empty object.

    expression:
        : block
        | objectExpression
        ;
    

    The parser will complain about any ambiguity (also known as shift/reduce conflict), but it will still work. Assuming the Jison parser is compatible with the Bison parser, use the expect declaration to suppress the warning.

    You could also make blocks and objectExpressions only appear in different contexts (e.g. blocks can only appear after if statements or for statements). A third choice would be to remove support for empty objects.