【问题】
antlrworks中调试antlr的语法,相关代码为:
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
fragment
DIGIT
: '0'..'9';
fragment
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
//fragment
HEX_VALUE : '0x' HEX_DIGIT+;
//fragment
DECIMAL_VALUE : DIGIT+;
direct_value : (DECIMAL_VALUE | HEX_VALUE);
enumarated_desc_help_call
: ID '(' direct_value ')'; // call some variable去匹配内容:
57, units_code(57)
结果出错:
hartEddlTestFile_pos.ddl line 166:25 mismatched character ‘5’ expecting ‘I’ |
【解决过程】
1.折腾了一个下午,最后终于搞懂原因了:
原先是,此语法.g文件的最开始部分,有lexer部分的代码:
fragment
DATA_ITEM_SPECIAL_MASKS
: ID '<' HEX_VALUE '>' ','?;
fragment
DATA_ITEM_SPECIAL_QUALIFIER
: ID '(' 'INFOR'|'INDEX'|'INFOR,INDEX' ')' ','?;
DATA_ITEM_SPECIAL
: DATA_ITEM_SPECIAL_MASKS | DATA_ITEM_SPECIAL_QUALIFIER;其可以匹配到对应的
ID ‘(‘
的内容,所以对于输入内容:
| 57, units_code(57) |
就被匹配到:
| units_code( |
部分的内容,并且由于是lexer部分的定义的token:DATA_ITEM_SPECIAL
后续又没有被用到,所以此部分的内容,就被匹配到后,就丢掉了。
导致我后面用正确的语法:
enumarated_desc_help_call
: ID '(' direct_value ')';去匹配
| 57, units_code(57) |
时,结果会去调用:
| DATA_ITEM_SPECIAL_QUALIFIER |
即:
| ID ‘(‘ ‘INFOR’|’INDEX’|’INFOR,INDEX’ ‘)’ ‘,’?; |
所以才发现,'(‘后面是希望是大写字母’I’,但是结果却是57中的’5’
而对于此5,无法匹配后,结果继续去匹配后面的7,所以此时,内容就变成了:
| 57, 7) |
从图上可以看到这点:
所以,解决办法也很简单,就是把没用的那段Lexer代码:
fragment
DATA_ITEM_SPECIAL_MASKS
: ID '<' HEX_VALUE '>' ','?;
fragment
DATA_ITEM_SPECIAL_QUALIFIER
: ID '(' 'INFOR'|'INDEX'|'INFOR,INDEX' ')' ','?;
DATA_ITEM_SPECIAL
: DATA_ITEM_SPECIAL_MASKS | DATA_ITEM_SPECIAL_QUALIFIER;都去掉,就可以了。
【总结】
如果antlr中,
在你确保自己的语法写的没有任何错误的前提下,
以后再出现莫名其妙的mismatched character的错误的时候,
就可以回去查看一下,是不是你的语法中,
有相关的lexer的token,其中匹配到了此对应的内容,
但是该token很可能没有被后面的,parser中的rule去调用,所以内容就丢掉了
所以,才出现此类错误。
重要心得:
在你的antlr语法中,千万不要随便乱加一些lexer的token,即大写字母开头的那些变量;
否则,会导致你的后续的语法,出现很多其他你所意想不到的问题。
转载请注明:在路上 » 【已解决】antlr调试语法代码时出错:mismatched character ‘5’ expecting ‘I’,no viable alternative at input ‘7’