Error handling 当规则失败时,强制antlr3立即退出
我有这样一条规则:Error handling 当规则失败时,强制antlr3立即退出,error-handling,antlr,antlr3,Error Handling,Antlr,Antlr3,我有这样一条规则: declaration returns [RuntimeObject obj]: DECLARE label value { $obj = new RuntimeObject($label.text, $value.text); }; 不幸的是,它在RuntimeObject构造函数中抛出异常,因为$label.text为空。检查调试输出和其他一些内容可以发现,与“label”的匹配实际上失败了,但是Antlr运行时“有益地”继续匹配,以提供更有用的错误消息()
declaration returns [RuntimeObject obj]:
DECLARE label value { $obj = new RuntimeObject($label.text, $value.text); };
不幸的是,它在RuntimeObject
构造函数中抛出异常,因为$label.text
为空。检查调试输出和其他一些内容可以发现,与“label”的匹配实际上失败了,但是Antlr运行时“有益地”继续匹配,以提供更有用的错误消息()
好吧,我知道这在某些情况下是多么有用,但是我怎么能告诉Antlr停止这样做呢?v2中的
defaultErrorHandler=false
选项似乎不存在了。我对Antlr了解不多,因此这可能有点离谱,但上题为“错误处理”的部分看起来很有帮助
它建议您可以使用
@rulecatch{}
完全禁用错误处理,或者使用您自己的不尝试恢复的实现覆盖BaseRecogniser
的mismatch()
方法。根据您的问题描述,该页面上的示例似乎完全符合您的要求。您还可以覆盖reportError(RecognitionException)方法,使其重新显示异常而不是打印异常,如下所示:
@parser::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException(e);
}
}
但是,我不确定您是否想要这个(或者使用ire_和_curses的解决方案),因为每次解析尝试只会得到一个错误,然后您可以修复这个错误,只是为了找到下一个错误。如果您尝试恢复(ANTLR做得很好),您可以在一次尝试中获得多个错误,并修复所有错误。您需要覆盖
mismatch
和recoverfrommasmatchedset
方法,以确保立即引发异常(示例适用于Java):
@成员{
受保护的无效不匹配(IntStream输入、int ttype、位集跟随)引发识别异常{
抛出新的不匹配的TokenException(t类型,输入);
}
公共对象从不匹配的数据集恢复(IntStream输入、识别异常e、位集跟随)引发识别异常{
投掷e;
}
}
然后,您需要更改解析器处理这些异常的方式,以便它们不会被吞没:
@rulecatch{
捕获(识别异常e){
投掷e;
}
}
(解析器中所有规则匹配方法的主体将包含在try
块中,并将其作为catch
块。)
为了进行比较,从
BaseRecognizer
继承的recoverfrommaschedset
的默认实现:
公共对象从不匹配的数据集恢复(IntStream输入、识别异常e、位集跟随)引发识别异常{
if(不匹配的MissingToken(输入,跟随)){
报告错误(e);
返回getMissingSymbol(输入,e,Token.INVALID_Token_TYPE,follow);
}
投掷e;
}
和默认规则捕获:
catch(识别异常re){
报告错误(re);
恢复(输入、重新输入);
}
RecognitionException不是RuntimeException,因此无法在reportError中重新调用它。然后将其包装。有什么问题吗?