摆脱令牌识别错误

时间:2014-03-14 20:33:12

标签: antlr4

如何摆脱默认的ANTLR识别错误?

我想使用自己的错误类而不是ANTLR的错误编写另一条消息。

我的意思是,是否有可能扩展某些ANTLR错误类以显示我自己的消息?

更清楚的是,我不希望在我的控制台中看到以下错误消息:

  

令牌识别错误:

2 个答案:

答案 0 :(得分:10)

如果您只想取消消息,可以拨打lexer.removeErrorListeners()。但是,更好的方法是编写词法分析器规则,以便对所有可能的输入进行标记化,并在词法分析器末尾使用以下规则。这将导致所有错误报告都通过解析器而不是解析器和词法分析器。

// handle characters which failed to match any other token
ErrorCharacter : . ;

答案 1 :(得分:1)

为了创建自定义错误处理程序,您可以扩展BaseErrorListener类并覆盖syntaxError方法,例如:

public class MyErrorListener extends BaseErrorListener {
  @Override
  public void syntaxError( Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
                           String msg, RecognitionException e ) {
    // method arguments should be used for more detailed report
    throw new RuntimeException("syntax error occurred");
  }
}

现在,当您创建词法分析器和解析器时,您应该删除默认的错误侦听器并附加自定义错误侦听器:

MyErrorListener errorListener = new MyErrorListener();

Lexer lexer = new MyLexer( ... );
lexer.removeErrorListeners();
lexer.addErrorListener( errorListener );

CommonTokenStream tokens = new CommonTokenStream( lexer );

Parser parser = new MyParser( tokens );
parser.removeErrorListeners();
parser.addErrorListener( errorListener );

默认消息“第x行x:x令牌识别错误:'xxx'”来自默认的ConsoleErrorListener类。如果您不使用lexer/parser.removeErrorListeners()删除它,只添加自定义的,它仍会被触发。

错误处理策略在The Definitive ANTLR4 Reference书的专门章节(ANTLR4 Documentation页面上提到)中有详细描述。我目前无法访问该书本身,如果有人用本书的具体页码编辑这个答案,我将不胜感激。此外,我在ANTLR4文档页面上找不到相关指南,因此如果存在 - 链接也会有所帮助。