Question

I'm having trouble with semantic predicates in ANTLR 4. My grammar is syntactically ambiguous, and needs to look ahead one token to resolve the ambiguity.

As an example, I want to parse "Jan 19, 2012 until 9 pm" as the date "Jan 19, 2012" leaving parser's next token at "until". And I want to parse "Jan 19, 7 until 9 pm" as the date "Jan. 19" with parser's next token at "7".

So I need to look at the 3rd token and either take it or leave it.

My grammar fragment is:

date
    :    month d=INTEGER  { isYear(getCurrentToken().getText())}?  y=INTEGER
                                    {//handle date, use $y for year}
    |    month d=INTEGER            {//handle date, use 2013 for year}
    ;                                             

When the parser runs on either sample input, I get this message:

line 1:9 rule date failed predicate: { isYear(getCurrentToken().getText())}?

It never gets to the 2nd rule alternative, because (I'm guessing) it's already read one extra token.

Can someone show me how to accomplish this?

Was it helpful?

Solution

In parser rules, ANTLR 4 only uses predicates on the left edge when making a decision. Inline predicates like the one you showed above are only validated.

The following modification will cause ANTLR to evaluate the predicate while it makes the decision, but obviously you'll need to modify it to use the correct lookahead token instead of calling getCurrentToken().

date
  : {isYear(getCurrentToken().getText())}? month d=INTEGER y=INTEGER
                                {//handle date, use $y for year}
  | month d=INTEGER             {//handle date, use 2013 for year}
  ;

PS: If month is always exactly one token long, then _input.LT(3) should provide the token you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top