我试图重复使用词法分析器/解析器来顺序解析短文本块。为了确保以前的运行没有剩余,我总是这样做
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”,则结果与第一次运行的结果不同。
那么如何相应地重置我的解析器/词法分析器呢?
答案 0 :(得分:1)
的结果与首次运行的结果有何不同?
以下是一些常规提示:
使用BailErrorStrategy
而非创建自己的ParseCancelledException
。它已经包含在ANTLR运行时中,将抛出RuntimeException
而不是exception
。它还将所有相关解析树节点的{{1}}字段设置为正确的值。
您可以创建新的词法分析器/解析器实例,而不是重复使用前一个。
答案 1 :(得分:1)
似乎setXXStream和reset的顺序很重要。当颠倒订单时,它按预期工作:
mLexer.setInputStream(new ANTLRInputStream(data));
mLexer.reset();
mParser.setTokenStream(new CommonTokenStream(mLexer));
mParser.reset();
可能是文档的东西。最初我希望在设置新流时重置词法分析器/解析器。