Im trying to remove a choice conflict from javacc grammar in LL(1) (without look ahead):
I already have grammar defined
I know I have to do some left factoring but im stumped on how to go about doing this one:
Here is some sample code:
void expression2() :{}{
fragment() (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {})
}
void fragment() :{}{
<ID>
|<LEFTPARENTHESES>arg_list()<RIGHTPARENTHESES>
|<TRUE>
|<FALSE>
|<NUM>
|(<PLUS_SIGN>|<MINUS_SIGN>)fragment()
}
void condition() :{}{
<NOT>expression2()|expression2()
(<EQ_SIGN>|<NOT_EQUAL_SIGN>|<LESS_THAN_SIGN>|<GREATER_THAN_SIGN>|<LESS_THAN_OR_EQUAL_SIGN>|<GREATER_THAN_OR_EQUAL_SIGN>|<AND>|<OR>)expression2()
|<ID>
}
the warning is:
Warning: Choice conflict involving two expansions at
line 226, column 20 and line 228, column 2 respectively.
A common prefix is: <ID>
Consider using a lookahead of 2 for earlier expansion.
where:
line 226, column 20 corresponds to the 2nd expression2() in condition() on the first line
line 228, column 2 corresponds to <ID>
in condition() on the last line
Suppose you are parsing condition
and the next token is ID
The following are both possible
condition()
==> 4th choice for condition
<Id>
and
condition()
==> 2nd choice for condition
expression2() (<EQ_SIGN>|...) expression2()
==> the only choice for expression2
fragment() (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {}) (<EQ_SIGN>|...) expression2()
==> the first choice for fragment
<ID> (<MULT_SIGN>|<DIV_SIGN>|<MOD_SIGN> fragment())* (expression2()| {}) (<EQ_SIGN>|...) expression2()
So given that the parser expects to see a condition
and the next token is an <ID>
, both the 2nd or 4th choices for condition
are viable.
As to how to fix it. There is discussion of a similar case at Javacc Unreachable Statement . In fact it is so similar that it makes me wonder if this isn't an assignment for a course that is being reused from year to year. If that's the case be sure to cite the stack overflow exchanges as part of your submission, so as not to commit an academic dishonesty offence.