Search code examples
javascriptparser-generatorjison

How to avoid conflicts in grammar


I have a grammar file — https://github.com/itrelease/fubar-script/blob/jsast/src/grammar.js but I get conflicts and I don't really know how to solve this. If someone could explain me it would be helpful.

This rules produce conflicts:

ParamVar: [
  ['Identifier', '$$ = $Identifier;'],
  ['THIS', '$$ = new yy.ThisExpression();']
],

PrimaryExpression: [
  ['THIS', '$$ = new yy.ThisExpression();'],
  ['Literal', '$$ = $Literal;'],
  ['ArrayLiteral', '$$ = $ArrayLiteral;'],
  ['Identifier', '$$ = $Identifier;'],
  ['ObjectLiteral', '$$ = $ObjectLiteral;'],
  ['( Expression )', '$$ = $Expression;']
],

Solution

  • Your current grammar does not have a PrimaryExpressionNoBrace, but I presume that the problem occurred with this older version of the grammar.

    The conflict is caused by this production:

    MemberExpression: [
          ['PrimaryExpression', '$$ = $PrimaryExpression;'],
          ['ArrowFunctionExpression', '$$ = $ArrowFunctionExpression'],
          ...
    

    where

    • a PrimaryExpression derives to a PrimaryExpressionNoBrace which has '( Expression )'

    • Expression again derives to PrimaryExpressionNoBrace which has IDENTIFIER or THIS alternatives

    • an ArrowFunctionExpression has '( FormalParameterList ) => Block'

    • FormalParameterList has IDENTIFIER or THIS alternatives, too.

    Thus the input of a left parenthesis, followed by an IDENTIFIER or THIS takes us into an LR-state that cannot decide between reducing to PrimaryExpressionNoBrace or to FormalParameterList, i.e. it has reduce-reduce conflicts on common legal followers (e.g. a right parenthesis). A single token lookahead is not suffient here, and there is no support for more.