ANTLR 4.7.1 несоответствие ошибки ввода для операции с датой - PullRequest
1 голос
/ 11 марта 2019

Я пытаюсь добавить операции с датами, используя грамматику ANTLR, я хочу добавить следующую опцию

variable(date) after(date operation) date(value check against)

Я изменил грамматику и попытался проверить следующую строку

"01012010" AFTER date(01012009)

Я получаю следующую ошибку

line 1:5 mismatched input 'AFTER' expecting {<EOF>, AND, OR}

Я все еще учусь работать с ANTLR и не уверен, почему появляется эта ошибка? что не так в файле грамматики.

Ценю помощь.

грамматика, которую я использую

grammar DateRule;

parse: expr EOF
    ;

expr    
 : expr binop expr                  #logicalExpression
 | lhs=VARIABLE compop rhs=VARIABLE #variableExpression
 | lhs=VARIABLE stringop rhs=STRING #stringExpression
 | lhs=VARIABLE compop rhs=NUMBER   #numberExpression
 | lhs=DATEVARIABLE dateop rhs=DATESTR  #dateExpression
 | TRUE                             #booleanTrue
 | FALSE                            #booleanFalse
 | VARIABLE                         #booleanVariable
 | LEFTPAREN expr RIGHTPAREN        #enclosedExpression
 ;

binop : AND | OR 
 ;

compop: EQUAL | LT | GT | LE | GE | NE 
      ;

stringop: CONT | STARTSWITH | EQUAL | ENDSWITH
      ;

dateop : AFTER | BEFORE ;

TRUE:       'true' | 'TRUE'  ;
FALSE:      'false' | 'FALSE';
STRING:     '"'   ~([\t\n\r]| '"')* '"'
     ;

LEFTPAREN:  '(';   
RIGHTPAREN: ')'; 
CONT  : 'CONTAINS' | 'contains';
STARTSWITH: 'STARTSWITH' | 'startswith' | 'sw' | 'SW';
ENDSWITH: 'ENDSWITH' | 'endswith' ;
AFTER:  'AFTER' | 'after';
BEFORE: 'BEFORE' | 'before';
BETWEEN: 'BETWEEN' | 'between';
DATESTR: 'date''('[0-3][1-9][1-12][2][0][0-9][0-9]')';
EQUAL     : '=' | 'EQ';
LT        : '<' | 'LT';
GT        : '>' | 'GT';
LE       : '<=' | 'LE';
GE       : '>=' | 'GE';
NE        : '!=' | 'NE';
AND       : 'AND' | '&' | 'and';
OR        : 'OR' | 'or' | '|';
VARIABLE  : [a-zA-Z]+[a-zA-Z0-9_.-]*;
NUMBER  : [0-9]+ ('.'[0-9]+)?;
DATEVARIABLE :'"'[0-3][1-9][1-12][2][0][0-9][0-9]'"' ;
SPACE     : [ \t\r\n] -> skip;

1 Ответ

1 голос
/ 11 марта 2019

"01012010" маркируется как STRING, а не DATEVARIABLE, потому что STRING появляется первым в лексере.

Вы можете поместить DATEVARIABLE выше STRING:

DATEVARIABLE :'"'[0-3][1-9][1-12][2][0][0-9][0-9]'"' ;
STRING:     '"'   ~([\t\n\r]| '"')* '"';

, чтобы DATEVARIABLE имел приоритет над STRING.

Вам также нужно будет сделатькак то так:

expr    
 : ...
 | lhs=VARIABLE stringop rhs=string #stringExpression
 | ...
 ;

string
 : STRING
 | DATEVARIABLE
 ;
...