我正在研究 ANTLR-Parser,现在正在为解析器编写测试。我已经找到了一种“肯定”的方法——测试解析器,但现在还想测试解析器在输入错误时也会失败(否定测试?)。我想要的是一种使用 JUnits 的方法Assertions.assertThrows(),例如NoViableAltException解析器抛出的一个或任何其他异常。我已经查看了ANTLRErrorListener及其实现,但还没有找到解决方案。到目前为止,这是我的测试用例:@Test public void test_short_negative() { String[] string_values = new String[]{"{", "<EOF>"}; int[] id_values = new int[]{MyLexer.CBRACKET_OPEN, MyLexer.EOF}; ArrayList<TestToken> tokens = new ArrayList<>(); for (int i = 0; i < id_values.length; i++) tokens.add(new TestToken(string_values[i], id_values[i])); ListTokenSource source = new ListTokenSource(tokens); for(TestToken t: tokens) t.setTokenSource(source); TestErrorListener errorListener = new TestErrorListener(true); MyParser pars = createParser(new ListTokenSource(tokens), errorListener); pars.stmt_block(); }public class TestErrorListener extends BaseErrorListener { private boolean hadError = false; private TestToken lastOffendingSymbol; private boolean doPrint; public TestErrorListener(boolean doPrint){ this.doPrint = doPrint; } public boolean hadError() { return hadError; } public TestToken getLastOffendingSymbol() { return lastOffendingSymbol; } @Override public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { if(doPrint) System.out.println("Syntax error at " + line + ":" + charPositionInLine + ". Symbol: '" + ((TestToken) offendingSymbol).getText() + "' could not be parsed."); hadError = true; lastOffendingSymbol = (TestToken) offendingSymbol; } @Override public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, ATNConfigSet configs) { if(doPrint) System.out.println("Ambiguity found at [" + startIndex + ":" + stopIndex + "]!"); }}
1 回答

UYOU
TA贡献1878条经验 获得超4个赞
还想测试解析器在提供错误输入时是否也会失败
在这种情况下,您所说的“失败”是什么意思尚不清楚,但我假设您的意思是“我怎么知道发生了语法错误?”。因为 ANTLR 解析器可以从一些语法错误中恢复,所以跳过一些标记并继续解析。
每次遇到语法错误时,都会调用syntaxError()
your 的方法。TestErrorListener
根据您的示例代码,hadError
每次发生错误时都将标志设置为 true,这意味着,在解析完成后,您可以测试该标志是真还是假,与您的输入令牌有关。
此外,您可以通过提供错误处理程序使 ANTLR 立即抛出异常并在发生错误时停止解析,即:
pars.setErrorHandler(new BailErrorStrategy());
从现在开始,您的解析器将抛出ParseCancellationException
. 抓住它并使用getCause()
方法,您可以获得导致解析器停止的真正原因,包括NoViableAltException
.
在后一种情况下,您所要做的就是pars.stmt_block();
结合运行assertThrows()
并检查ParseCancellationException
是否抛出。
添加回答
举报
0/150
提交
取消