ANTLR меняет тип токена на основе следующего токена
Я прочитал, что тип токена зависит от следующего токена, но в том, что спрашивающий пытался всегда получать один и тот же токен, игнорируя пробел.
У меня другой вопрос: я хотел бы изменить токен в зависимости от контекста. Грамматика - это грамматика поиска в памяти. Вот пример того, что я анализирую:
dog or [Notes] contains cat
Это создает AST как это:
or // OR
dog // WORD
contains // CONTAINS
[Notes] // PROP
cat // WORD
Это говорит поиску "искать ЛЮБЫЕ свойства с" собакой "или те, которые содержат" кошку ", но только в свойстве" Заметки "".
Я хотел бы убрать скобки, которые должны быть напечатаны, чтобы указать свойство, то есть я бы хотел, чтобы это выглядело так:
dog or Notes contains cat
CONTAINS
в данном случае это оператор сравнения, из которого есть обычные: EQ, NEQ и т. д. Так что суть в том, что мне бы хотелось Notes
быть признанным PROP
, Как он сидит, если я оставлю скобки, он будет признан как WORD
,
Есть ли способ сказать "если это WORD
непосредственно сопровождается CONTAINS|EQ|etc...
тогда я хочу, чтобы тип токена был PROP
"?
РЕДАКТИРОВАТЬ (ГРАММАРНЫЙ ФАЙЛ)
grammar Search;
options { language = CSharp3; output = AST; }
tokens { AND; }
@lexer::namespace { Symphony.Collections.Search }
@parser::namespace { Symphony.Collections.Search }
LPAREN : '(';
RPAREN : ')';
AndNode
: ('A'|'a')('N'|'n')('D'|'d')
| '&&'
;
OR
: ('O'|'o')('R'|'r')
| '||'
;
NOT
: ('N'|'n')('O'|'o')('T'|'t')
;
XOR
: ('X'|'x')('O'|'o')('R'|'r')
;
EQ
: '='
;
NEQ
: '!=' | '<>'
;
LT
: '<'
;
GT
: '>'
;
LTE
: '<='
;
GTE
: '>='
;
CONTAINS
: ('C'|'c')('O'|'o')('N'|'n')('T'|'t')('A'|'a')('I'|'i')('N'|'n')('S'|'s')
;
LIKE
: ('L'|'l')('I'|'i')('K'|'k')('E'|'e')
;
PROP
: '[' ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ']'
;
IDENT
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT
: '0'..'9'+
;
FLOAT
: ('0'..'9')+ '.' ('0'..'9')*
| '.' ('0'..'9')+
;
WS
: ( ' ' | '\t' | '\r' | '\n' ) {$channel=Hidden;}
;
PHRASE
: '"' (~('"') )* '"'
| '\'' (~('\'') )* '\''
;
WORD
: ( '!' | '#'..'&' | '*'..'~' | '\u0081'..'\u00FF' )+
;
op
: EQ | NEQ | LT | GT | LTE | GTE | CONTAINS | LIKE
;
startExpression
: andExpression
;
/*
Implicit AND when two expressions are side-by-side
*/
andExpression
: (xorExpression -> xorExpression)
(AndNode? a=xorExpression -> ^(AND $andExpression $a))*
;
xorExpression
: orExpression (XOR^ orExpression)*
;
orExpression
: expression (OR^ expression)*
;
expression
: (NOT^)? atomicExpression
;
atomicExpression
: PHRASE | WORD | IDENT | INT | FLOAT | parenExpression | opExpression
;
parenExpression
: LPAREN! (WS!)* andExpression (WS!)* RPAREN!
;
opExpression
: PROP (WS!)* (op^) (WS!)* (INT|FLOAT|PHRASE|WORD|IDENT|PROP)
;