【问题标题】:ANTLR ERROR : The following token definitions can never be matched because prior tokens match the same inputANTLR 错误:以下标记定义永远无法匹配,因为先前的标记匹配相同的输入
【发布时间】:2014-01-30 11:54:52
【问题描述】:

我是 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))+;

【问题讨论】:

  • 抱歉忘记添加了:MAPPING,STROPS,UNARYOPS,ARITHEMATICOPS,MATHLOGICALOP,LOGICALOP,OP1,OP2,OP3,OP4

标签: antlr ebnf


【解决方案1】:

ANTLR 为输入中每个不重叠的字符序列分配一种且仅一种标记类型(名称以大写字母开头)。在您的情况下,ANY 规则匹配一个序列,并且在它之后定义的MAPPING 规则也被定义为匹配ANY(作为其替代方案之一)。当输入为any 时,您的词法分析器将始终为其分配标记类型ANY,因为该规则是首先定义的。

虽然您允许输入 anyMAPPING,但 ANTLR 警告您它永远不会将类型 MAPPING 分配给此输入,因此 MAPPING 的当前定义具有误导性。您应该更新您的词法分析器规则,以便每个序列只匹配一种标记类型。

【讨论】:

  • 感谢您的帮助。虽然我希望它尽可能模块化,但我会努力改进它。
猜你喜欢
  • 1970-01-01
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多