compiler-constructionlexical-analysisjavacc

Choice Conflict In JavaCC. Consider Using Lookahead of 3 or more


I am currently trying to build a parser for a simple programming language. The parser generates fine, but it shows this warning:

Warning: Choice conflict involving two expansions at
         line 238, column 7 and line 239, column 7 respectively.
         A common prefix is: "(" "("
         Consider using a lookahead of 3 or more for earlier expansion.

The code where the error is happening is as follows:

void condition(): {}
{
    <NOT> condition() condition_prime()
    | <LPAREN> condition() <RPAREN> condition_prime()
    | expression() compare_ops() expression() condition_prime()
}

void condition_prime(): {}
{
    logical_ops() condition() condition_prime() | {}
}

I did it this way to eliminate left recursion but now that warning occurs. Is there any way this warning can be avoided?

The code that builds the expression() non-terminal is as follows:

void expression(): {}
{
    fragment() expression_prime()
}

void expression_prime(): {}
{
    binary_arith_op() fragment() expression_prime() | {}
}

void fragment(): {}
{
    <ID> (<LPAREN> args_list() <RPAREN>)?
    | <MINUS> <ID> 
    | <NUM> 
    | <DIGIT> 
    | <TRUE> 
    | <FALSE> 
    | <LPAREN> expression() <RPAREN>
}

Solution

  • The reason there is a choice conflict is that in the definition of nonterminal condition there are 3 choices and the second and third can both start with an<LPAREN>. This is because an expression can start with an <LPAREN>.

    The error message suggests using a lookahead of 3 or more. However, changing the amount of lookahead to any finite number will not be sufficient. For example if you change it to 17, that will not be enough if a condition starts with a left parenthesis followed by an expression that is 16 tokens long or more.

    You can solve the problem with syntactic lookahead.