如何在ANTLR4语法规则匹配失败时抛出自定义异常
ANTLR4解析匹配失败抛出自定义异常实现方案
该需求完全可以实现,具体操作流程如下:
前置说明
你给出的示例语法存在基础写法问题:parser规则不能直接写[a-z]+正则匹配,该写法仅适用于词法规则,先修正语法文件的基础逻辑:
grammar Test; // 语法规则:匹配1个及以上小写字母,加EOF防止匹配到部分内容就判定成功 exampleParserRule : LowercaseLetter+ EOF; // 词法规则:定义小写字母token LowercaseLetter : [a-z]; // 兜底词法规则:捕获所有未定义的字符,也可以在此处直接触发异常 ErrorChar : .;
核心实现步骤
ANTLR默认的错误处理逻辑只会把错误信息打印到控制台,不会中断流程抛异常,我们通过替换默认错误监听器实现自定义异常抛出:
- 先定义你需要的自定义异常类,比如
AntlrParseException继承自对应语言的基础异常类即可 - 自定义错误监听器,重写语法错误处理方法,在方法内抛出自定义异常
// 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); } }
- 初始化解析流程时,移除词法、语法分析器的默认监听器,添加自定义监听器
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
相关产品推荐
相关产品推荐

