识别REAL值遇阻:语法失效,TestRig测试异常求解答
嘿,我来帮你捋捋这个REAL值(比如xxx.xx)识别失效的问题!这种情况在ANTLR里大多是几个容易疏忽的规则细节导致的,我把最可能的原因和解决方法列出来,你可以对照检查:
1. 词法规则优先级搞反了
ANTLR的词法分析器会优先匹配定义在前的规则,如果你先定义了INT规则(比如INT: [0-9]+;),再写REAL,那像123.45这样的输入,会先把123匹配成INT,剩下的.45就无法被正确识别了。
解决方法:把REAL规则放在INT前面,或者直接用一个规则覆盖整数和浮点数的情况:
// 先定义REAL,再定义INT(如果还需要单独识别整数的话) REAL: [0-9]+ '.' [0-9]+; INT: [0-9]+; // 或者更灵活的写法,支持整数、带小数、纯小数的情况 REAL: ([0-9]+ '.' [0-9]*) | ('.' [0-9]+) | ([0-9]+);
如果用第二种写法,INT规则其实可以删掉,因为REAL已经覆盖了整数的场景。
2. REAL规则的格式不完整
很多人一开始会写出不严谨的REAL规则,比如只允许整数.小数的固定格式,却忘了处理.45(纯小数)或者123.(带小数点但无小数部分)的情况,导致这些边缘输入触发错误。
正确的REAL规则示例:
REAL: [0-9]* '.' [0-9]+ // 匹配.45、123.45 | [0-9]+ '.'? [0-9]*; // 匹配123、123.
3. 语法规则里没正确引用REAL
就算词法规则写对了,如果parser规则里没用到REAL,那输入还是会报错。比如你的表达式规则如果只写了:
expr: INT | expr '+' expr;
那输入123.45肯定会触发异常,因为parser不知道怎么处理REAL类型。得改成:
expr: REAL | expr '+' expr;
4. TestRig的命令参数错了
如果你的起始规则指定不对,TestRig也会找不到对应的输入入口。比如你的REAL是在number规则里定义的,那正确的TestRig命令应该是:
java org.antlr.v4.gui.TestRig YourGrammarName number -gui
然后输入测试值123.45,才能正确触发规则匹配。
5. 没处理空白字符
如果你的输入里有空格、换行等空白字符,而词法规则里没加跳过空白的规则,TestRig会把这些空白当成非法字符报错。记得一定要加:
WS: [ \t\r\n]+ -> skip;
完整的测试语法示例
给你一个能直接运行的小例子,你可以对照着改自己的语法:
grammar RealDemo; // 起始规则 start: number EOF; // 引用REAL词法规则 number: REAL; // 支持各种REAL格式 REAL: [0-9]+ '.' [0-9]+ | [0-9]+ | '.' [0-9]+; // 跳过空白字符 WS: [ \t\r\n]+ -> skip;
运行TestRig命令:
java org.antlr.v4.gui.TestRig RealDemo start -gui
输入123.45、.67或者89,都能正确识别了。
如果还是解决不了,你可以把你的语法代码和TestRig抛出的具体错误信息贴出来,我再帮你精准排查~
内容的提问来源于stack exchange,提问作者YaFred

