【问题】
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’