ОШИБКА 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
вводит в заблуждение. Вам следует обновить правила лексера, чтобы каждая последовательность соответствовала только одному типу токена.