нет подходящей альтернативы на входе ANTLR4 - PullRequest
0 голосов
/ 03 апреля 2020

Я разрабатываю язык, который позволяет вам делать предикаты для данных, вот мой лексер грамматик.

lexer grammar Studylexer;


fragment LETTER : [A-Za-z];
fragment DIGIT : [0-9];
fragment TWODIGIT : DIGIT DIGIT;
fragment MONTH:  ('0' [1-9] | '1' [0-2]);
fragment DAY: ('0' [1-9] | '1' [1-9] | '2' [1-9] | '3' [0-1]);



TIMESTAMP: TWODIGIT ':' TWODIGIT; // représentation de la timestamp 

DATE : TWODIGIT TWODIGIT MONTH DAY; // représentation de la date


ID : LETTER+; // match identifiers 

STRING : '"' ( ~ '"' )* '"' ; // match string content

NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)

WS  :   [ \t]+ -> skip ; // toss out whitespace 

LIST: ( LISTSTRING | LISTDATE | LISTTIMESTAMP ) ; // list of variabels;

// list of operators

GT: '>';
LT: '<';
GTEQ: '>=';
LTEQ:'<=';
EQ: '=';
IN: 'in';

fragment LISTSTRING: STRING ',' STRING (',' STRING)*; // list of strings
fragment LISTDATE : DATE   ',' DATE   (',' DATE)*;    // list of dates
fragment LISTTIMESTAMP:TIMESTAMP ',' TIMESTAMP (',' TIMESTAMP )*; // list of timestamps

NAMES: 'filename' | 'timestamp' | 'tso' | 'region' | 'processType' | 'businessDate' | 'lastModificationDate'; // name of variables in the where block

KEY: ID '[' NAMES ']' | ID '.' NAMES; // predicat key

и вот часть моего грамматика.

expr: KEY op = ('>' | '<') value = (  DATE  | TIMESTAMP )  NEWLINE          # exprGTORLT
    | KEY op = ('>='| '<=') value = ( DATE  | TIMESTAMP )  NEWLINE          #  exprGTEQORLTEQ
    | KEY  '=' value = ( STRING | DATE      | TIMESTAMP )  NEWLINE          # exprEQ
    | KEY 'in'   LIST                                      NEWLINE          #exprIn

когда я делаю предикат например.

tab [key]  in  "value1", "value2" 

ANTLR генерирует ошибку.

  no viable alternative at input  tab [key]  in  

Я разрабатываю язык, который позволяет вам делать предикаты для данных, вот мой лексер грамматик.

1 Ответ

0 голосов
/ 03 апреля 2020

Первый tab [key] не производит токен KEY, как вы этого хотите, по двум причинам:

  1. Он содержит пробелы, а KEY не допускает пробелов. Лучший способ исправить это - удалить правило KEY из лексера и вместо этого превратить его в правило синтаксического анализатора (то есть вам также необходимо превратить [ и ] в их собственные токены). Тогда пробел в вводе будет между токенами и, следовательно, будет успешно пропущен.
  2. key на самом деле не является одним из слов, перечисленных в NAMES.

Тогда другая проблема является то, что in распознается как ID токен, а не IN токен. Это связано с тем, что и ID, и IN дают совпадение одинаковой длины, и в подобных случаях правило, указанное в списке первым, имеет приоритет. Поэтому вы должны определить ID после всех ключевых слов, потому что иначе ключевые слова никогда не будут совпадать.

...