为了账号安全,请及时绑定邮箱和手机立即绑定

ANLTR 4 (Java) 捕获解析器错误/预期以进行测试

ANLTR 4 (Java) 捕获解析器错误/预期以进行测试

白板的微信 2022-10-07 16:41:24
我正在研究 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是否抛出。


查看完整回答
反对 回复 2022-10-07
  • 1 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号