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)
    ;

0 ответов

Другие вопросы по тегам