猿问

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

我正在研究 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 + "]!");

    }



}


白板的微信
浏览 105回答 1
1回答

UYOU

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

相关分类

Java
我要回答