如何更正令牌,然后从ANTLR中的失败谓词中恢复?

时间:2012-05-24 16:19:40

标签: parsing error-handling antlr antlr3

我有一个ANTLR规则,用于使用谓词测试创建AST。它看起来像这样:

checked_rule
  : kwd=keyword name=name nl { noBadChars($name.start.getText()) }?
    -> ^(...)
  ;

如果$name有一些不好的字符,那么我想要出错。我到目前为止这样做:

catch [FailedPredicateException fpe] {
  BadNameException error = new BadNameException(input, $kwd.text, $name.start.getText());
  reportError(error);
  recover(input, error);
  retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), error);
}

最后一位是从ANTLR生成的代码中复制出来的,所以也许这不是正确的方法。

无论如何,我想做的是通过更正名称并再次尝试规则来从错误中恢复。在伪代码中,我想说:

catch [FailedPredicateException fpe] {
  ...
  reportError(...)
  input.LT(-2) = removedBadChars($name.start.getText());
  return checked_rule();
}

因此错误仍然会传达给用户,但我们会尽可能少地中断解析。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

为什么不简单地做:

checked_rule
  : kwd=keyword name=name nl 
    {
      if(!noBadChars($name.start.getText())) {
        // print/report error
        String withoutBadChars = removedBadChars($name.start.getText());
        $name.start.setText(withoutBadChars);
        // and continue happily ever after...
      }
    }
    -> ^(...)
  ;