查找下一个预期 token (如果发生错误)ANTLR 3

2020年4月3日 20点热度 0条评论

我正在使用ANTLR 3,我有一个问题是,如果输入中发生任何错误,如何找到下一个预期的令牌。我试图重写解析器的getErrorMessage(RecognitionException e,String [] tokenNames),我会收到错误,但我无法获得“下一个期望的令牌是什么”。如果有人可以帮助。
提前致谢。

解决方案如下:

这听起来并不容易。而且经常没有此类信息。

例如,您的语法可以匹配带括号的表达式,例如:(1+2)

如果您的解析器现在尝试解析"(1+2",则会抛出一个MismatchedTokenException,其expecting属性将是')'的类型。因此,这很容易。

但是,当它尝试解析"1+2)"时,将再次抛出MismatchedTokenException,但是现在解析器会抱怨它期望EOF,因为它希望仅解析像1+2这样的表达式。它不会告诉您“过去”中的某个地方,您忘记了'('

因此,只有少数几种情况可以让您从解析器引发的异常中提取预期的令牌。在大多数情况下,您将需要做很多工作才能自己提取此信息。在解析器中创建有意义的错误消息并非易事! (至少,与简单地为不太复杂的语言编写语法相比)

我建议通过ANTLR's API docs来查看ANTLR抛出了哪些异常,并有意地将解析器的无效输入提供给解析器,并在解析器中覆盖reportError(...)以查看抛出了哪些异常:

@parser::members {

  @Override
  public void reportError(RecognitionException e) {
    // inspect 'e' and handle/report it
  }
}