0

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

programming
  • 51
  • 1
  • 5

1 Answers1

1

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.

Community
  • 1
  • 1
Theodore Norvell
  • 15,366
  • 6
  • 31
  • 45
  • Thank you for your answer. However would you mind giving me a more specific fix for this question? My full code is a bit different that that question which you linked. I have an attempt and it seems to work `void condition() :{}{ (|)(expression2()| (|||||||)expression2()) }` this is probably wrong though in terms of left factoring...rest of the code is as above and I have added parentheses where you mentioned – programming Dec 17 '14 at 00:05
  • Well I guess I'd wonder why `` is an alternative for condition. The usual answer is that you have Boolean variables in your language. In that case the usual approach is to make no syntactic distinction between conditions and other expressions. See the Java Language Specification for a typical example. But it is largely a matter of language design. I'd suggest discussing the matter with your instructor. – Theodore Norvell Dec 17 '14 at 00:35