[antlr-interest] disambiguating sempred in a closure?

J Chapman Flack jflack at math.purdue.edu
Fri Dec 21 14:26:36 PST 2007


Harald M. Müller wrote:
> As far I can see, the sempreds ARE at the top of the (inner) rule. Below is
> the code produced by ANTLR 2.7.5 for C# - I did not run it, but it looks
> pretty correct.
> 			for (;;)
> 			{
> 				if (((LA(1)==KERMIT||LA(1)==FOZZIE))&&(
> muppet ))
...
> 				else if
> (((LA(1)==LEONARDO||LA(1)==DONATELLO))&&( turtle )) {
> 				else
> 				{
> 					goto _loop5_breakloop;
> 				}
> 				
> 			}

Ah.  Hmmm.  My bad for sending in a simplified version of my
production without first confirming that it generates the same
code as the one in the real grammar!  I've tried it now and
indeed my simplified snippet produces code that would work.

Now I just have to figure out what I simplified out that makes
the difference in the generated code. One thing that changed is
that the real grammar has k=3. The generated code resembles this:

_loop113: do {
   if ((_tokenSet_30.member(LA(1))) && (_tokenSet_31.member(LA(2)))
   && (_tokenSet_6.member(LA(3)))) {
     if (((LA(1)==KERMIT||LA(1)==FOZZIE))&&
     fireSemanticPredicateEvaluated(
     antlr.debug.SemanticPredicateEvent.PREDICTING,18, muppet )) {
       op=mup();
     }
     else if (((LA(1)==LEONARDO||LA(1)==DONATELLO))&&
     fireSemanticPredicateEvaluated(
     antlr.debug.SemanticPredicateEvent.PREDICTING,19, turtle )) {
       op=tur();
     }
     else {
       throw new NoViableAltException(LT(1), getFilename());
     }
     suf=suffix();
   }
   else {
     break _loop113;
   }
} while (true);

Note that it will only take the exit if LA(1), LA(2), and LA(3)
are not in token sets 30, 31, and 6, respectively; the semantic
predicates only appear with the inner tests on LA(1), where
failure can only cause an exception to be thrown.

Thanks for demonstrating that my snippet was too far
simplified.  Hmmm.  Hmmmm.

-Chap


More information about the antlr-interest mailing list