由于我对现有的两个答案有些挣扎,所以我想分享一下最终得到的解决方案。
首先,我像SamHarwell建议的那样创建了自己的ErrorListener版本:
public class ThrowingErrorListener extends baseErrorListener { public static final ThrowingErrorListener INSTANCE = new ThrowingErrorListener(); @Override public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) throws ParseCancellationException { throw new ParseCancellationException("line " + line + ":" + charPositionInLine + " " + msg); }}请注意使用a
ParseCancellationException而不是a,
RecognitionException因为DefaultErrorStrategy会捕获后者,并且永远不会到达您自己的代码。
建议不要像BradMace一样创建一个全新的ErrorStrategy,因为DefaultErrorStrategy默认情况下会产生非常好的错误消息。
然后,我在解析函数中使用自定义的ErrorListener:
public static String parse(String text) throws ParseCancellationException { MyLexer lexer = new MyLexer(new ANTLRInputStream(text)); lexer.removeErrorListeners(); lexer.addErrorListener(ThrowingErrorListener.INSTANCE); CommonTokenStream tokens = new CommonTokenStream(lexer); MyParser parser = new MyParser(tokens); parser.removeErrorListeners(); parser.addErrorListener(ThrowingErrorListener.INSTANCE); ParserRuleContext tree = parser.expr(); MyParseRules extractor = new MyParseRules(); return extractor.visit(tree);}这将为您提供与默认情况下打印到控制台相同的错误消息,只是形式为适当的异常。



