2014-01-30 2 views
1

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

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

Извините, что добавили: ** КАРТА, СТРОКИ, UNARYOPS, ARITHEMATICOPS, MATHLOGICALOP, LOGICALOP, OP1, OP2, OP3, OP4 ** –

ответ

2

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

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

+1

Спасибо, что помогает. Хотя я хотел, чтобы он был настолько модульным, насколько это возможно, но я буду работать над его улучшением. –