ANTLR4 告诉我:不匹配的输入 'little' 期待 {'big', 'little'}

ANTLR4 tells me: mismatched input 'little' expecting {'big', 'little'}

我有以下简单的语法:

grammar TestG;

p : pDecl+ ;

pDecl : endianDecl
    | dTDecl
    ;

endianType : E_BIG
    | E_LITTLE
    ;

endianDecl : 'endian' '=' endianType ';' ;

dTDecl : 'dT' '[' STRING ']' '=' ID ';' ;

STRING: '"'.*?'"' ;                //Embedded quotes?
COMMENT: '#' .*? [\n\r] -> skip ;  // Discard comments for now
ID :   [a-zA-Z][a-zA-Z0-9_]* ;
WS :   [ \t\n\r]+ -> skip ;
INT : ('0x')?[0-9]+ ;  // How to handle 0xDD and ensure non zero?
E_BIG : 'big' ;
E_LITTLE : 'little' ;

当我运行grun TestG p并输入以下内容时:

endian = little;

我得到以下信息:

line 1:9 mismatched input 'little' expecting {'big', 'little'}

我做错了什么?

因为 ID 的词法分析器规则先于 E_LITTLE,所以您的 'little' 输入被词法分析为 ID

[@0,0:5='endian',<'endian'>,1:0]
[@1,7:7='=',<'='>,1:7]
[@2,9:14='little',<ID>,1:9] <== see here it's being lexed as an ID
[@3,15:15=';',<';'>,1:15]
[@4,18:17='<EOF>',<EOF>,2:0]
line 1:9 mismatched input 'little' expecting {'big', 'little'}

将这些词法分析器标记 移动到 ID 上方,如下所示:

STRING: '"'.*?'"' ;                //Embedded quotes?
COMMENT: '#' .*? [\n\r] -> skip ;  // Discard comments for now
E_BIG : 'big' ;
E_LITTLE : 'little' ;
ID :   [a-zA-Z][a-zA-Z0-9_]* ;
WS :   [ \t\n\r]+ -> skip ;
INT : ('0x')?[0-9]+ ;  // How to handle 0xDD and ensure non zero?

从您的测试输入中产生正确的输出。

[@0,0:5='endian',<'endian'>,1:0]
[@1,7:7='=',<'='>,1:7]
[@2,9:14='little',<'little'>,1:9] <== see here being lexed correctly
[@3,15:15=';',<';'>,1:15]
[@4,18:17='<EOF>',<EOF>,2:0]

请记住,对于词法分析器标记,最长的比赛获胜,但在平局的情况下,先出现的比赛获胜。这就是为什么您希望更具体的词法分析器标记位于词法分析器标记列表的顶部,而更通用的词法分析器标记(如标识符、字符串等)更靠下。