[antlr-interest] Use of Syntactic Predicates

Chris Shoemaker c.shoemaker at cox.net
Fri Oct 27 20:13:19 PDT 2006


Hi,
    I'm new to antlr, and am having trouble with syntactic predicates.

I want a lexer rule that matches exactly two digits optionally
followed by a format specifier, but never by a third digit.

First attempt, using syntactic predicate:

protected
SUFFIX: (WS)* ("pa"|"aa") WS
   ;

FIELD
   : (DIGIT DIGIT ~('0'..'9')) => DIGIT DIGIT (SUFFIX)?
   ;

Here's a table showing how I intend for strings to be tokenized (where
quoted strings in the Tokens column mean not-yet-tokenized)

  String       Tokens 

  "41 pa"      FIELD
  "41 pq.."    FIELD " pq.."
  "411"        -rejected-

I _thought_ that the rules above expressed what I want. However, I'm
getting: warning:Syntactic predicate ignored for single alternative

Q1) Is it really valid to ignore a single alternative synpred for a
lexical rule?  Isn't there an implicit "exit" alternative?  IOW, I
just want the token to never match if the synpred fails.

I've tried many different ways to reformulate this, and have run into
other interesting problems.

For example, I thought I would try pushing the synpred further right:

protected
SUFFIX
   :  (~('0'..'9')) => (WS)* ("pa"|"aa") WS
   | 'Q' /* This is to avoid the "Syntactic predicate ignored for
            single alternative" warning.  I know it's a little "wrong" 
            but I'm willing to work with it for now. */
   ;

FIELD
   : DIGIT DIGIT (SUFFIX)?
   ;

AFAICT, this just generates wrong code.  For example, when scanning
"41paX", it matches the digits, matches the synpred, matches the "pa",
but when it gets to the 'X', I think it should not create SUFFIX, but
still create FIELD, since SUFFIX was optional.  Instead, it throws an
exception that's caught by another synpred way above mFIELD(), so it
doesn't create FIELD.

Q2) Is this a bug or am I just abusing the tool?

Thanks in advance for any help and, remember, I'm new at this. ;)

-chris


More information about the antlr-interest mailing list