ОШИБКА ANTLR: Следующие определения токенов никогда не могут быть сопоставлены, потому что предыдущие токены совпадают с тем же входным

Я новичок в ANTLR и пытаюсь сделать следующее. Из-за ошибки кажется, что я определяю что-то общее, и приведенное ниже правило недостижимо / избыточно. Избыточные, на которые жалуется ANTLR: MAPPING, STROPS, UNARYOPS, ARITHEMATICOPS, MATHLOGICALOP, LOGICALOP, OP1, OP2, OP3, OP4. Я не понимаю, где именно я иду не так. Пожалуйста, дайте мне знать проблему и концепцию, стоящую за ней.

 grammar RA;

options {
  language = Java;
  output = AST;
  k=3;
}



DIVIDE : '/';
PLUS : '+';
MINUS : '-';
STAR : '*';
MOD : '%';
LPAREN : '(';
RPAREN : ')';
COMMA : ',';
COLON : ':';
LANGLEBRACKET : '<';
RANGLEBRACKET : '>';
EQ : '=';
NOT : '!';
UNDERSCORE : '_';
DOT : '.';
GRTRTHANEQTO : RANGLEBRACKET EQ;
LESSTHANEQTO : LANGLEBRACKET EQ;
NOTEQ         : NOT EQ;


fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');

AND     :   A N D;
OR      :   O R;
COUNT       :   C O U N T;
AVG     :   A V G;
COUNTDISTINCT   :   C O U N T D ;
CAST        :   C A S T;
CORRESPONDING   :   C O R R E S P O N D I N G;
ANY     :   A N Y;

MAPPING     :   (CORRESPONDING|ANY);
MATCHCASE       :   I;

EQUALS      :   E Q U A L S;
LIKE        :   L I K E;
NOTEQUALS       :                     N O T E Q U A L S;
NOTLIKE     :   N O T L I K E;
NOTNULL     :   N O T N U L L;

STROPS      :   (EQUALS | LIKE | NOTEQUALS | NOTLIKE | NOTNULL);
UNARYOPS        :   (COUNT | AVG | COUNTDISTINCT);
ARITHEMATICOPS  :   (DIVIDE|PLUS|MINUS|STAR|MOD);
MATHLOGICALOP   :   (LANGLEBRACKET|RANGLEBRACKET|EQ|GRTRTHANEQTO|LESSTHANEQTO|NOTEQ);
LOGICALOP       :   (AND|OR);

SECATTR     :   ('a'..'z' | 'A'..'Z') UNDERSCORE? ('a'..'z' | 'A'..'Z')* DOT ('a'..'z' | 'A'..'Z') UNDERSCORE? ('a'..'z' | 'A'..'Z')*;
BRACEDSECATTR   :   LPAREN SECATTR RPAREN;
UNOPSECATTR :   OP1 BRACEDSECATTR;

OP1     :   (UNARYOPS | CAST) ;
OP2     :   (ARITHEMATICOPS|MATHLOGICALOP|STROPS);
OP3     :   (MAPPING|MATCHCASE);
OP4     :   (LOGICALOP);
//fragment Letter : 'a'..'z' | 'A'..'Z';
//Alphanumeric      :   (('a'..'z' | 'A'..'Z')| '0'..'9')* ('a'..'z' | 'A'..'Z') (('a'..'z' | 'A'..'Z')| '0'..'9')* ;
SINGLERULE      :   (SECATTR|BRACEDSECATTR|UNOPSECATTR) OP2 ((('a'..'z' | 'A'..'Z')| '0'..'9')|SECATTR|BRACEDSECATTR|UNOPSECATTR);
BRACEDSINGLERULE    :   LPAREN SINGLERULE RPAREN;
UNOPSINGLERULE  :   BRACEDSINGLERULE OP3;

Expr        :   SINGLERULE|UNOPSINGLERULE|((SINGLERULE|UNOPSINGLERULE)OP4(SINGLERULE|UNOPSINGLERULE))+;

1 ответ

Решение

ANTLR назначает один и только один тип токена (имя, начинающееся с заглавной буквы) для каждой непересекающейся последовательности символов на входе. В вашем случае ANY правило соответствует последовательности, а MAPPING правило, определенное после того, как оно также определено, чтобы соответствовать ANY (как одна из его альтернатив). Когда вход anyваш лексер всегда будет назначать тип токена ANY к этому, так как это правило определяется первым.

Пока вы разрешили ввод any быть MAPPING, ANTLR предупреждает вас, что он никогда не назначит тип MAPPING на этот вход, поэтому текущее определение MAPPING вводит в заблуждение. Вам следует обновить правила лексера, чтобы каждая последовательность соответствовала только одному типу токена.

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