You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改ANTLR解析器错误位置:将缺失分号报错定位至前一Token末尾

问题

我自定义的语法规则中,流程语句外的语言语句格式为<expression>;。当前ANTLR解析时,如果发现缺失分号;,错误位置会被定位到下一个Token的起始位置(通常是下一行开头),但合理的错误位置应该是前一个Token的末尾。

我理解解析器的判定逻辑,但这种错误定位方式会给新手开发者造成困惑。我正在GUI编辑器项目中使用自定义IAntlrErrorListener<IToken>收集错误信息,希望能在解析器规则层面通过简单配置实现修正错误位置的需求,以此提升开发与学习体验。

解决方案

ANTLR本身没有直接的规则层面配置项修改这种错误定位逻辑,但可以通过两种实用方式实现需求:

1. 自定义错误监听器调整位置

在你已实现的IAntlrErrorListener<IToken>中,捕获到缺失分号的语法错误时,手动修正错误位置:

  • 先判断错误类型(比如通过错误消息包含"missing ';'"或预期Token类型)
  • 获取当前错误位置的前一个有效Token,将错误的起始/结束位置替换为该Token的末尾位置

示例C#代码片段:

public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
    if (msg.Contains("missing ';'") && offendingSymbol != null)
    {
        var tokenStream = ((Parser)recognizer).InputStream;
        var prevToken = tokenStream.Get(offendingSymbol.TokenIndex - 1);
        if (prevToken != null && prevToken.Type != TokenConstants.EOF)
        {
            // 替换错误位置为前一个Token的末尾
            line = prevToken.Line;
            charPositionInLine = prevToken.Column + prevToken.Text.Length;
            offendingSymbol = new CommonToken(prevToken.TokenSource, prevToken.Type, prevToken.Channel, prevToken.StartIndex, prevToken.StopIndex);
        }
    }
    // 后续错误信息收集逻辑
}

2. 修改语法规则主动指定错误位置

在语法规则中为语句末尾添加自定义错误处理,直接将错误定位到前一个Token:
把原规则:

statement : expression ';' ;

修改为:

statement : expression ( ';' | { NotifyErrorListeners("Missing ';' after expression", _input.LT(-1), null); } ) ;

这里通过_input.LT(-1)获取表达式的最后一个Token,让ANTLR将错误位置绑定到该Token上。这种方式需要逐个修改需要分号的规则,但能在解析阶段就输出正确的错误位置。

内容的提问来源于stack exchange,提问作者WiredWiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:45:43