ANTLR4实现URI解析语法运行报词法识别错误排查
问题根因
该报错由两个问题叠加触发,和你观察到的现象完全对应:
- URI语法中的scheme段匹配规则存在笔误:规则实际要求匹配字符
6而非s,也就是当前语法写的是匹配http6://开头,不是预期的https:// - 词法规则集存在缺失:要么没有定义匹配英文字母的通用词法规则,要么Common.g4的通用规则没有被正确导入,导致固定字符串字面量匹配失败时,没有其他规则可以承接单个字母字符。
报错触发逻辑:
- 词法分析器启动后优先尝试匹配最长token,也就是规则中写死的
http6://字面量,读到第5个字符(输入中s的位置)时发现字符不匹配,该token匹配失败- 回溯后词法分析器找不到任何能匹配首字符
h的词法规则,因此依次抛出h、t、t、p、s这几个字符的token识别错误- 跳过上述无法识别的字符后,词法分析器读到位置5的
:,此时解析器仍处于等待http后跟随字符6的状态,因此直接提示在:处缺失token6。
修复步骤
- 检查scheme相关规则笔误
- 排查Uri.g4中所有和协议头相关的规则,确认没有把
'https'手滑写成'http6'(二者在键盘上位置接近,是高频笔误) - 如果用了Unicode转义写法,核对码点:
\u0036对应字符6,\u0073才对应字符s
- 排查Uri.g4中所有和协议头相关的规则,确认没有把
- 核对Common.g4导入配置
- 确认Uri.g4文件开头通过
import Common;正确导入通用词法文件 - 确认Common.g4中存在可匹配英文字母的通用规则,参考写法:
IDENT: [a-zA-Z][a-zA-Z0-9.+-]*; - 检查antlr4-maven-plugin配置,确认两个g4文件都在插件的扫描源码路径下,不会出现Common.g4规则漏编译的问题
- 确认Uri.g4文件开头通过
- 调整词法规则顺序
- 匹配固定协议、关键字的词法规则要写在通用标识符规则之前,避免被通用规则提前截胡
- 不要把协议头这类固定字符串写在parser规则中依赖隐式token生成,最好显式定义为词法规则,优先级更可控,参考写法:
SCHEME: 'http' 's'? '://';
- 重新编译验证
- 执行
mvn clean compile清空之前缓存的旧生成代码,确保最新g4规则被编译为Java类,再运行单元测试即可。
- 执行
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

