ANTLR — нет жизнеспособной альтернативы на входе

Я получаю сообщение об ошибке: no viable alternative at input 'mult' при попытке проанализировать ввод: div(mean(mult(field_a, field_b)), sum(field_b)).

Вот моя грамматика:

grammar Analytics;

start: expr | stat;

expr
    : UNARY_EXPR '(' (stat | expr | NUMBER ) ')'                                        #unaryExpr
    | BINARY_EXPR '(' (stat | expr | constant) ',' (stat | expr | constant) ')'         #binaryExpr
    | MULTIPLE_EXPR '(' (stat | expr | constant) ',' (stat | expr | constant)+ ')'      #multipleExpr
    ;       

stat
    : UNARY_STAT  '(' (operation | field) ')'                                           #unaryStat
    | BINARY_STAT '(' (operation | field) ',' (operation | field) ')'                   #binaryStat
    ;

operation
    : UNARY_OPERATION '(' operation ')'                                                 #unaryOperation
    | BINARY_OPERATION '(' operation ',' operation ')'                                  #binaryOperation
    | MULTIPLE_OPERATION '(' operation ',' operation+ ')'                               #multipleOperation
    | field                                                                             #fieldOperation
    ;

constant: NUMBER;

field: IDENTIFIER;

UNARY_EXPR: 'neg' | 'const_num' | 'rev' | 'miss' | 'const_date' | 'const_str';
BINARY_EXPR: 'div' | 'pow' | 'log'; 
MULTIPLE_EXPR: 'add' | 'mult' | 'date_math' | 'concat'; 

UNARY_STAT: 'count' | 'missing' | 'min' | 'max' | 'stddev' | 'sum' | 'sumofsquares' | 'mean' | 'unique' | 'median' |
    'const_num' | 'neg' | 'abs';
BINARY_STAT: 'add' | 'mult' | 'div' | 'pow' | 'log';

UNARY_OPERATION: 'neg' | 'rev' | 'const_date' | 'const_str';
BINARY_OPERATION: 'div' | 'pow' | 'log' | 'miss'; 
MULTIPLE_OPERATION: 'add' | 'mult' | 'date_math' | 'concat'; 

OPEN_BRACKET: '(';
CLOSE_BRACKET: ')';
COMMA: ',';

NUMBER: ('0'..'9')+ ('.' ('0'..'9')+)? ;
IDENTIFIER : [a-zA-Z][a-zA-Z0-9_]*;

WS : (' ' | '\t')+ -> skip;

Что я здесь делаю неправильно, из-за чего он не соответствует mult? Есть ли предложенный подход, который я мог бы использовать для отладки этой ошибки?

Кроме того, как я могу проверить, какие альтернативы соответствуют каждому правилу? Например, я получаю вывод toStringTree(): (start (expr div ( (stat mean ( mult ( field) , field ) ) , sum ( field ) ))). Как я мог сказать, что первое правило expr соответствует правилу BINARY_EXPR '(' (stat | expr | constant) ',' (stat | expr | constant) ')', а не UNARY_EXPR '(' (stat | expr | NUMBER ) ')'?


person Corey Wu    schedule 08.06.2015    source источник


Ответы (1)


Всякий раз, когда один или несколько символов могут соответствовать более чем одному правилу лексера, правило, определенное первым, «выигрывает».

Поскольку вход mult может соответствовать этим правилам:

MULTIPLE_EXPR: 'add' | 'mult' | 'date_math' | 'concat'; 
BINARY_STAT: 'add' | 'mult' | 'div' | 'pow' | 'log';
MULTIPLE_OPERATION: 'add' | 'mult' | 'date_math' | 'concat'; 

первое правило, MULTIPLE_EXPR, всегда будет выбрано для ввода mult.

Вместо этого вам придется сделать что-то вроде этого:

multiple_expr      : ADD | MULT | ... ; 
binary_stat        : ADD | MULT | ... ;
multiple_operation : ADD | MULT | ... ; 

ADD  : 'add';
MULT : 'mult';
...
person Bart Kiers    schedule 08.06.2015