ANTLR4自定义Hello语法无法正确解析含'-' '.'的括号字符串问题求解
ANTLR4 语法匹配冲突修复方案
问题根源
报错本质是ANTLR4的词法规则优先级逻辑导致的匹配歧义:
- ANTLR4词法分析阶段会优先匹配最长输入序列,长度相同时写在前面的规则优先级更高
- 你当前的语法将单个字符
-.数字等都定义为独立词法规则,同时这些字符既属于数字的组成部分,也属于字符串允许的内部字符,词法分析器在解析(后的-时,无法判断该将其归类为字符串内部字符,还是等待后续字符匹配数字规则,最终导致语法匹配失败。
修复方案
核心思路是将字符串、数字都直接定义为独立的词法规则,让词法分析阶段就能直接区分两种元素,从根源上消除匹配歧义:
- 直接定义STRING词法规则:匹配以
(开头、非转义)结尾的完整序列,内部直接包含所有允许的字符(含转义括号、-、.) - 直接定义NUMBER词法规则:覆盖你需要的整数、正负浮点数格式,不需要拆分digit、integer等零散语法规则
- 去掉原来分散的Charactor、D0-D9等冗余词法规则,避免优先级混乱
修复后的完整Hello.g4代码
// Define a grammar called Hello grammar Hello; r : element* ; element : NUMBER Whitespace | STRING Whitespace ; // 字符串词法规则:(开头,)结尾,内部()需要转义,支持所有要求的字符 STRING : '(' ( '\\(' | '\\)' | [a-zA-Z!#$%&'*+,-./:;<=>?@\[\]\\^_`{|}~"] )* ')' ; // 数字词法规则:支持正负整数、正负浮点数 NUMBER : '-'? [0-9]+ ( '.' [0-9]+ )? ; Whitespace : ' ' | '\n' ; // 如果需要忽略空白符可以启用下面的规则替换上面的Whitespace //WS : [ \t\r\n]+ -> skip ;
修复说明
- 词法分析器遇到
(开头的序列会直接匹配完整的STRING词法单元,不会和数字规则产生任何冲突,字符串内部的-.都会被正确识别为字符串的一部分 - 数字规则直接在词法阶段完成匹配,格式完全符合你要求的1.1、-1.2、-222、222等格式
- 你之前报错的测试用例
1.1 -1.2 333 -222 (-.#$?)可正常解析,原有正常用例也不受影响
内容的提问来源于stack exchange,提问作者Kevin Lu
相关产品推荐
相关产品推荐

