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中重新调用它。然后将其包装。有什么问题吗?