BATMAN
токенизируется как токен LHSOPERAND
.Вы должны понимать, что лексер не учитывает то, что "парсеру" нужно в конкретный момент времени.Лексер просто пытается найти максимально возможное совпадение, и в случае, если 2 (или более) правила соответствуют одинаковому количеству символов (LHSOPERAND
и RHSOPERAND
в вашем случае), правило, определенное первым, будет «выигрывать», чтоLHSOPERAND
правило.
EDIT
Посмотрите на это так: сначала лексер получает поток символов, который он конвертирует в поток токенов.После того, как все токены были созданы, парсер получает эти токены, которые он затем пытается понять.Токены не создаются во время синтаксического анализа (в правилах синтаксического анализа), но перед ним.
Небольшая демонстрация того, как вы могли бы сделать это:
grammar RuleGrammar;
prog
: condition EOF
;
condition
: logical
;
logical
: relational ((AND | OR) relational)*
;
relational
: STRINGVALUE ((GT | GTEQ | LT | LTEQ | EQ | NEQ) term)?
;
term
: STRINGVALUE
| NUMBERVALUE
| '(' condition ')'
;
GT : '>';
GTEQ : '>=';
LT : '<';
LTEQ : '<=';
EQ : '=';
NEQ : '<>';
NUMBERVALUE : '0'..'9'+;
AND : 'AND';
OR : 'OR';
STRINGVALUE : ('a'..'z' | 'A'..'Z' | '_')+;
SPACE : ' ' {skip();};
(обратите внимание, что EQ
и NEQ
на самом деле не являются реляционными операторами ...)
Синтаксический анализ ввода, например:
PERSON_NAME = BATMAN OR age <> 42
теперь приведет к следующему синтаксическому анализу: