Friday, March 17, 2017

Making Antlr4 fail on a syntax error

When Antlr4 encounter a syntax error, it emits an error message and then attempts to recover and continue parsing.  This default strategy is good for normal use but does not work for unit testing where we want the parser to throw an exception on syntax error so that the unit test actually fails.

To make Antlr4 fail on syntax error, we need to extend BaseErrorListener as follows:

class FailingErrorListener extends BaseErrorListener {
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
            Object offendingSymbol, int line,
            int charPositionInLine, String msg,
            RecognitionException e)
            throws ParseCancellationException {
        throw new ParseCancellationException("line " + line + 
            ":" + charPositionInLine + " " + msg);
    }
}

Then, we need to add this error listener to both a lexer and a parser:

final ANTLRInputStream input = new ANTLRInputStream(stream);
final FailingErrorListener errorListener = new FailingErrorListener();

final MyLexer lexer = new MyLexer(input);
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);

final CommonTokenStream tokens = new CommonTokenStream(lexer);

final MyParser parser = new MyParser(tokens);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);

After these changes the parser starts failing on as soon as it encounters a syntax error.

No comments:

Post a Comment