为何ANTLR4语法中无效token未触发错误监听器?
问题分析与解答
问题描述
给定ANTLR4语法片段:
INT2: INT INT; INT4 : INT INT INT INT; DATE: (INT | INT2) SEP (INT | INT2) SEP (INT2 | INT4); fromdate: DATE; todate: DATE; interval: DATES (fromdate DASH todate); luah: (interval SEMICOLON remainingpart;
输入字符串:
Dates:4/1/2024-4/1/2025 fghyhj
解析后生成的Token在SPACES后停止,未对fghyhj触发错误;但单独输入无效字符串(如asdfsdfsedf)时,错误处理器能捕获mismatched input错误。
原因
ANTLR4解析器默认采用最长有效前缀匹配策略:只要输入的前半部分能匹配语法中的某条规则,解析器就会认为这部分匹配成功,不会自动检查后续是否还有未被消耗的输入。
- 单独输入
asdfsdfsedf时,没有任何规则能匹配这个前缀,直接触发不匹配错误; - 输入
Dates:4/1/2024-4/1/2025 fghyhj时,前半部分完全匹配interval规则,解析器完成这部分匹配后就停止工作,剩余的fghyhj被直接忽略,不会触发错误。
另外你的顶层规则luah存在语法错误(缺少闭合括号),且未强制要求匹配到输入结束,也加剧了这个问题。
解决方案
修改顶层规则,强制要求解析器匹配整个输入,即在规则末尾加上EOF(输入结束标记),同时修正语法错误:
示例修改后的顶层规则:
// 若不允许存在remainingpart,直接匹配到EOF luah: interval SEMICOLON EOF; // 若需要处理remainingpart,同样要加上EOF luah: interval SEMICOLON remainingpart EOF;
这样当输入存在未被规则覆盖的剩余内容时,解析器会触发mismatched input错误,因为它无法将剩余内容匹配到EOF之前的规则中。
内容的提问来源于stack exchange,提问作者Michael EstrinOne
相关产品推荐
相关产品推荐

