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

如何在ANTLR4语法规则匹配失败时抛出自定义异常

ANTLR4解析匹配失败抛出自定义异常实现方案

该需求完全可以实现,具体操作流程如下:


前置说明

你给出的示例语法存在基础写法问题:parser规则不能直接写[a-z]+正则匹配,该写法仅适用于词法规则,先修正语法文件的基础逻辑:

grammar Test;

// 语法规则:匹配1个及以上小写字母,加EOF防止匹配到部分内容就判定成功
exampleParserRule : LowercaseLetter+ EOF;

// 词法规则:定义小写字母token
LowercaseLetter : [a-z];

// 兜底词法规则:捕获所有未定义的字符,也可以在此处直接触发异常
ErrorChar : .;

核心实现步骤

ANTLR默认的错误处理逻辑只会把错误信息打印到控制台,不会中断流程抛异常,我们通过替换默认错误监听器实现自定义异常抛出:

  1. 先定义你需要的自定义异常类,比如AntlrParseException继承自对应语言的基础异常类即可
  2. 自定义错误监听器,重写语法错误处理方法,在方法内抛出自定义异常
// Java版本示例,其他语言逻辑完全一致,仅语法稍作调整
public class CustomAntlrErrorListener extends BaseErrorListener {
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
        // 可自行组装错误信息,比如携带行号、列号、错误原因
        String errorMsg = String.format("解析错误:第%d行第%d列,%s", line, charPositionInLine, msg);
        throw new AntlrParseException(errorMsg, e);
    }
}
  1. 初始化解析流程时,移除词法、语法分析器的默认监听器,添加自定义监听器
public static void parse(String inputContent) {
    CharStream input = CharStreams.fromString(inputContent);
    TestLexer lexer = new TestLexer(input);
    // 替换词法分析器的错误监听器
    lexer.removeErrorListeners();
    lexer.addErrorListener(new CustomAntlrErrorListener());
    
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    TestParser parser = new TestParser(tokens);
    // 替换语法分析器的错误监听器
    parser.removeErrorListeners();
    parser.addErrorListener(new CustomAntlrErrorListener());
    
    // 触发解析规则,匹配失败就会直接抛出你的自定义异常
    parser.exampleParserRule();
}

替代兜底方案

如果你不需要逐行收集错误细节,也可以在解析完成后通过错误计数判断是否抛异常:

parser.exampleParserRule();
// 只要语法错误计数大于0就主动抛异常
if (parser.getNumberOfSyntaxErrors() > 0) {
    throw new AntlrParseException("输入内容不符合语法规则");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 09:12:04