【问题】
antlrworks中调试antlr的语法,相关代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
去匹配内容:
1 | 57 , units_code( 57 ) |
结果出错:
hartEddlTestFile_pos.ddl line 166:25 mismatched character ‘5’ expecting ‘I’ |
【解决过程】
1.折腾了一个下午,最后终于搞懂原因了:
原先是,此语法.g文件的最开始部分,有lexer部分的代码:
1 2 3 4 5 6 7 8 | 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
后续又没有被用到,所以此部分的内容,就被匹配到后,就丢掉了。
导致我后面用正确的语法:
1 2 | 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代码:
1 2 3 4 5 6 7 8 | 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’