Java ANTLR未在无效输入上引发错误

Java ANTLR未在无效输入上引发错误,java,exception,antlr,antlrworks,Java,Exception,Antlr,Antlrworks,我正在编写的Java工具中使用ANTLR解析逻辑表达式,我遇到了一些问题,因为将无效的输入字符串传递给生成的ANTLR lexer和解析器不会导致任何异常。生成的文件没有像我预期的那样抛出识别异常,而是将错误消息打印到控制台并返回,就像没有发生错误一样,这会导致我的程序在稍后遇到空数据时崩溃 我使用了AntlWorks 1.4.3版来生成文件,似乎应该有某种选项让它实际抛出错误,而不是打印到控制台,但我没有找到任何东西。有人知道如何让ANTLR实际抛出错误消息吗?我看到C#中的这个问题是通过使用

我正在编写的Java工具中使用ANTLR解析逻辑表达式,我遇到了一些问题,因为将无效的输入字符串传递给生成的ANTLR lexer和解析器不会导致任何异常。生成的文件没有像我预期的那样抛出识别异常,而是将错误消息打印到控制台并返回,就像没有发生错误一样,这会导致我的程序在稍后遇到空数据时崩溃

我使用了AntlWorks 1.4.3版来生成文件,似乎应该有某种选项让它实际抛出错误,而不是打印到控制台,但我没有找到任何东西。有人知道如何让ANTLR实际抛出错误消息吗?我看到C#中的这个问题是通过使用旧版本的ANTLR解决的,这就是我需要做的吗

编辑:巴特给我指了指我要找的方向后,我找到了这一页

其“错误处理”部分的代码更准确地满足了我的要求。要更改ANTLR捕获异常的方式,可以在语法文件中这样说:

@rulecatch {
   catch (RecognitionException e) {
    throw e;
   }
}

这将迫使ANTLR抛出异常,而不是处理它并进行恢复。在该部分中还有一些关于覆盖不匹配和恢复函数的内容,以确保抛出所有可能的异常。

一个简单的修复方法是覆盖lexer和解析器的
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

有关错误报告(和恢复)的更多信息:

您应该按照建议使用错误侦听器

但是,要从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()); 
  }
}
@parser::members
{
私有最终记录器log=LogManager.getLogger(this.getClass().getName());
public java.util.HashMap memory=new java.util.HashMap();
@凌驾
public void notifyErrorListeners(令牌违规、字符串消息、识别异常ex)
{
抛出新的运行时异常(msg);
}
}
@lexer::成员
{
@凌驾
公共无效恢复(识别异常ex)
{
抛出新的RuntimeException(例如getMessage());
}
}

哦,非常感谢,我知道必须有一种简单的方法来编辑语法文件,以实现我的目的,但是ANTLR太大了,我不知道到底要查找什么。