ANTLR4自定义语法解析报mismatched input词法匹配错误
问题根因
错误和你排查的INT/DECIMAL/DATE_TIME规则冲突无关,核心触发原因是FIELD_IDENTIFIER词法规则设计不符合ANTLR4的词法匹配逻辑:
- ANTLR4词法分析独立于解析规则运行,遵循最长匹配优先原则:对同一段输入,永远优先选择能匹配最长字符序列的规则;仅当多个规则匹配长度完全相同时,才会选择在语法文件中定义位置更靠前的规则。
- 你定义的
FIELD_IDENTIFIER规则为(LETTER|DIGIT)(LETTER|DIGIT|' ')*,允许标识符内部包含空格,直接导致异常匹配:
当词法分析器处理>=后的15片段时:INT规则最多仅能匹配2个字符(即15本身),遇到后续空格就无法继续延伸匹配FIELD_IDENTIFIER规则允许数字开头,还能继续匹配后续的空格,最终可以覆盖15(数字15+末尾空格)共3个字符,匹配长度比INT规则更长,因此会被优先选中,这段内容会被识别为FIELD_IDENTIFIER类型的token,而非你期望的INT。
错误提示中显示待匹配输入为'15 '(末尾自带空格),就是该问题的直接佐证。
修复方案
按以下两点调整语法规则即可解决问题:
- 修正
FIELD_IDENTIFIER规则,移除其中允许匹配空格的逻辑,空格统一交给已有的WS规则处理,修改后规则如下:FIELD_IDENTIFIER : (LETTER|DIGIT)(LETTER|DIGIT)*; - 修复比较运算符的规则定义:你当前写的
>/<是HTML转义字符,仅能匹配字面量字符串>/<,无法识别测试输入中的原生>/<符号;同时注意将双字符运算符放在单字符运算符之前,避免最长匹配逻辑提前截断双字符符号:GE : '>=' ; GT : '>' ; LE : '<=' ; LT : '<' ; EQ : '=' ;
验证说明
调整完成后,输入$IF >=15 $FROM AgeInYears $THEN会被正确拆分为IF、GE、INT(15)、FROM、FIELD_IDENTIFIER(AgeInYears)、THEN的token序列,可正常完成解析,不会再抛出匹配错误。
内容的提问来源于stack exchange,提问作者avs099
相关产品推荐
相关产品推荐

