1

我试图重用词法分析器/解析器来顺序解析短文本块。为了确保不会留下以前运行的任何残留物,我总是这样做

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

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

认为无论以前发生什么,这都会完全重置词法分析器和解析器。不幸的是,在解析无效模式时,有些东西仍然存在。

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

      @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”,结果与第一次运行的结果不同。

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

4

2 回答 2

2

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

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

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

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

于 2013-06-13T05:54:13.357 回答
1

结果与第一次运行有何不同

以下是一些一般提示:

  1. 使用BailErrorStrategy而不是创建自己的。它已经包含在 ANTLR 运行时中,并且会抛出 aParseCancelledException而不是RuntimeException. 它还将exception所有相关解析树节点的字段设置为适当的值。

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

于 2013-06-12T13:35:21.913 回答