我正在使用ANTLR来解析我正在编写的Java工具中的逻辑表达式,我遇到了问题,因为将无效的输入字符串传递给生成的ANTLR词法分析器并且解析器不会导致任何异常。生成的文件不是像我期望的那样抛出RecognitionException,而是将错误消息打印到控制台并返回,好像没有发生错误,导致我的程序在以后遇到空数据时崩溃。
我使用ANTLRWorks版本1.4.3生成文件,似乎应该有某种选项让它实际抛出错误而不是打印到控制台,但我还没有找到任何东西。有谁知道如何让ANTLR实际抛出错误信息?我看到使用旧版本的ANTLR解决了C#中同样的问题,这是我需要做的吗?
编辑:在Bart指出我正在寻找的方向之后,我找到了这个页面https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Migrating+from+ANTLR+2+to+ANTLR+3
其“错误处理”部分的代码完全符合我的要求。要更改ANTLR捕获异常的方式,可以在语法文件中说明这一点:
@rulecatch {
catch (RecognitionException e) {
throw e;
}
}
这会强制ANTLR抛出异常而不是处理它并恢复。该部分还有一些关于覆盖不匹配和恢复功能的内容,以确保抛出所有可能的异常。
答案 0 :(得分:17)
一个简单的解决方法是覆盖你的词法分析器和解析器的reportError(...)
并抛出你自己的异常,而不是让ANTLR试图从错误的语法/输入中恢复:
grammar YourGrammar;
// options/header/tokens
@parser::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("I quit!\n" + e.getMessage());
}
}
@lexer::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("I quit!\n" + e.getMessage());
}
}
// lexer & parser rules
有关错误报告(和恢复)的更多信息:https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Error+reporting+and+recovery
答案 1 :(得分:1)
您应该使用建议的in this answer
错误监听器但是,要快速从antlr3迁移到antlr4 / antlr v4,您可以将其用作语法:
@parser::members
{
private final Logger log = LogManager.getLogger(this.getClass().getName());
public java.util.HashMap<String, Double> memory = new java.util.HashMap<String, Double>();
@Override
public void notifyErrorListeners(Token offendingToken, String msg, RecognitionException ex)
{
throw new RuntimeException(msg);
}
}
@lexer::members
{
@Override
public void recover(RecognitionException ex)
{
throw new RuntimeException(ex.getMessage());
}
}