错误后ANTLRv4重置词法分析器和解析器

时间:2013-06-12 12:53:15

标签: antlr4

我试图重复使用词法分析器/解析器来顺序解析短文本块。为了确保以前的运行没有剩余,我总是这样做

    mLexer.reset();
    mLexer.setInputStream(new ANTLRInputStream(data));

    mParser.reset();
    mParser.setTokenStream(new CommonTokenStream(mLexer));

认为这将完全重置lexer和解析器,无论之前发生了什么。不幸的是,解析无效模式时仍然存在一些问题

我的词法分析器无法恢复:

      @Override
        public void recover(final LexerNoViableAltException e) {
            throw new RuntimeException(e);
        }

我的解析器也不会:

private class HexParserErrorStrategy extends org.antlr.v4.runtime.DefaultErrorStrategy {
    @Override
    public void recover(final Parser recognizer, final RecognitionException e) {
        throw new RuntimeException(e);
    }

    @Override
    public Token recoverInline(final Parser recognizer) throws RecognitionException {
        throw new RuntimeException();
    }

    @Override
    public void reportUnwantedToken(final Parser recognizer) {
        throw new RuntimeException();
    }
}

当我解析像“123456”这样的字符串时,这很有效。之后我解析了一个无效模式,这给了我一个RE。如果我再次尝试解析“123456”,则结果与第一次运行的结果不同。

那么如何相应地重置我的解析器/词法分析器呢?

2 个答案:

答案 0 :(得分:1)

的结果与首次运行的结果有何不同?

以下是一些常规提示:

  1. 使用BailErrorStrategy而非创建自己的ParseCancelledException。它已经包含在ANTLR运行时中,将抛出RuntimeException而不是exception。它还将所有相关解析树节点的{{1}}字段设置为正确的值。

  2. 您可以创建新的词法分析器/解析器实例,而不是重复使用前一个。

答案 1 :(得分:1)

似乎setXXStream和reset的顺序很重要。当颠倒订单时,它按预期工作:

mLexer.setInputStream(new ANTLRInputStream(data));
mLexer.reset();

mParser.setTokenStream(new CommonTokenStream(mLexer));
mParser.reset();

可能是文档的东西。最初我希望在设置新流时重置词法分析器/解析器。