tags:

views:

74

answers:

1

I have the following lexer rules in my grammar file:

   LINE    :    'F' | 'G';
RULE    :    (('->' ('F' | 'G')) => 'F' | 'G' )
                | LINE LINE + | LINE * (ROTATE + LINE+)+ ;
fragment ROTATE    :    ('/' | '\\');

I'm basically trying to match productions that look like F -> F/F\F\F/F. It successfully matches stuff like the above, but I'm guessing there's a problem with my syntactic predicate, since G -> G produces a MismatchedTokenException. The predicate serves to disambiguate between single letters on the lhs of '->', which I want to be recognized as the LINE token, and those on the rhs, which should be RULEs.

Any idea what I'm doing wrong?

+1  A: 

Note that the rule:

RULE
  :  (('->' ('F' | 'G')) => 'F' | 'G')
  |  LINE LINE + 
  |  LINE * (ROTATE + LINE+)+ 
  ;

matches a single G without the predicate. The rule above could be rewritten as:

RULE
  :  ( ('->' ('F' | 'G')) => 'F' 
     | 'G'
     )
  |  LINE LINE + 
  |  LINE * (ROTATE + LINE+)+ 
  ;

which in its turn equals:

RULE
  :  ('->' ('F' | 'G')) => 'F' 
  |  'G'
  |  LINE LINE + 
  |  LINE * (ROTATE + LINE+)+ 
  ;

Perhaps you meant to do something like this:

RULE
  :  ('->' ('F' | 'G')) => ('F' | 'G')
  |  LINE LINE + 
  |  LINE * (ROTATE + LINE+)+ 
  ;
Bart Kiers
You're right with the parantheses, but that didn't help. I reworked the grammar by matching 'G' or 'F' with the LINE token and leaving the latter two alternatives for RULE, then defining my parser rule for productions as either LINE '->' RULE or LINE '->' LINE.
varzan
Okay. Good to hear you solved it!
Bart Kiers