我有以下简单的语法:
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'}
我做错了什么?
答案 0 :(得分:1)
因为ID
的词法规则优先于E_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]
请记住,对于词法分析器,最长的匹配会获胜,但在平局的情况下,首先出现的匹配胜利。这就是为什么你想要在词法分析器令牌列表顶部使用更具体的词法分析器标记,以及更常见的词法分析器标记(如标识符,字符串等)。