1

我有这样的规则:

declaration returns [RuntimeObject obj]: 
    DECLARE label value { $obj = new RuntimeObject($label.text, $value.text); };

RuntimeObject不幸的是,它在构造函数中抛出异常,因为$label.text它是 null。检查调试输出和其他一些事情表明与“标签”的匹配实际上失败了,但 Antlr 运行时“有用地”继续匹配以提供更有用的错误消息(http://www.antlr.org /blog/antlr3/error.handling.tml)。

好的,我可以看到这在某些情况下是如何有用的,但是我怎样才能告诉 Antlr 停止这样做呢?v2的defaultErrorHandler=false选项似乎消失了。

4

3 回答 3

2

我对 Antlr 了解不多,所以这可能有点离谱,但是这个迁移页面上标题为“错误处理”的部分看起来很有帮助。

它建议您可以使用@rulecatch { }完全禁用错误处理,或者使用您自己的实现覆盖该mismatch()方法,该BaseRecogniser实现不会尝试恢复。从您的问题描述来看,该页面上的示例似乎完全符合您的要求。

于 2009-09-08T18:14:30.983 回答
0

您还可以覆盖 reportError(RecognitionException) 方法,使其重新抛出异常而不是打印异常,如下所示:

@parser::members {
    @Override
    public void reportError(RecognitionException e) {
        throw new RuntimeException(e);
    }
}

但是,我不确定你是否想要这个(或 ire_and_curses 的解决方案),因为每次解析尝试只会得到一个错误,然后你可以修复它,只是为了找到下一个错误。如果您尝试恢复(ANTLR 没问题),您可能会在一次尝试中遇到多个错误,并修复所有错误。

于 2009-09-09T08:14:49.667 回答
0

您需要重写mismatchandrecoverFromMismatchedSet方法以确保立即引发异常(示例用于 Java):

@members {
    protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException {
        throw new MismatchedTokenException(ttype, input);
    }

    public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
        throw e;
    }
}

那么您需要更改解析器处理这些异常的方式,以免它们被吞没:

@rulecatch {
    catch (RecognitionException e) {
        throw e;
    }
}

(解析器中所有规则匹配方法的主体都将包含在try块中,并以此作为catch块。)


为了比较,recoverFromMismatchedSet继承自的默认实现BaseRecognizer

public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)  throws RecognitionException {
    if (mismatchIsMissingToken(input, follow)) {
        reportError(e);
        return getMissingSymbol(input, e, Token.INVALID_TOKEN_TYPE, follow);
    }

    throw e;
}

和默认规则捕获:

catch (RecognitionException re) {
    reportError(re);
    recover(input,re);
}
于 2012-05-18T18:16:40.570 回答