1

我有一个 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();
}

所以错误仍然会传递给用户,但我们会在尽可能少的干扰下继续解析。我怎样才能做到这一点?

4

1 回答 1

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...
      }
    }
    -> ^(...)
  ;

?

于 2012-05-24T17:55:20.900 回答