1
votes

I am trying to catch syntax errors in ANTLR4 before I visit the ParseTree. Simplified, my grammar for declaring a double is like this:

Grammar for double type (parser rule):

declare_double: DOUBLE_TYPE  WHITESPACE ID WHITESPACE(EQUALS WHITESPACE DOUBLE)? SEMICOLON;

Grammar for double type (lexer rule):

DOUBLE: [0-9]+ '.' [0-9]+ | '.' [0-9]+ | [0-9]+;

Compiler class:

public class Compiler implements ANTLRErrorListener {
    public static void main(String[] args) {

        //CharStream chars = CharStreams.fromString("double a = 3.1415;");
        CharStream chars = CharStreams.fromString("double a = 3;");


        SimpleJavaLexer lexer = new SimpleJavaLexer(chars);
        CommonTokenStream tokens = new CommonTokenStream(lexer);

        SimpleJavaParser parser = new SimpleJavaParser(tokens);

        ANTLRErrorListener errorListener = new BaseErrorListener();

        //parser.removeErrorListeners();

        parser.addErrorListener(errorListener);

        SimpleJavaParser.ProgramContext programTree = parser.program();


        TypeChecker visitor = new TypeChecker();
        visitor.visit(programTree);
    }

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object o, int i, int i1, String s, RecognitionException e) {
        System.out.println("Syntax Error");
    }

    @Override
    public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
        System.out.println("Report ambiguity");
    }

    @Override
    public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
        System.out.println("Report attempting full context");
    }

    @Override
    public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
        System.out.println("Report context sensitivity");
    }
}

If I run this and I do not remove the default listener from the parser, I get the following result:

Default error listener output

    line 1:11 mismatched input '3' expecting DOUBLE
    line 1:12 extraneous input ';' expecting {<EOF>, WHITESPACE, '(', INTEGER,BOOLEAN, DOUBLE, STRING, ID}

The problem that I have is that after this error is displayed, the visitor is instantiated and it will visit the TypeChecker. Whenever a error is found, I don't want to continue. I thought that by implementing an error listener like the way I did, I could create my own error messages and stop running the program. I expected the syntaxError method to be triggered but it does not. I have used this topic for reference.

How do I appropriately listen for errors and manage them accordingly?

Thanks in advance.

1

1 Answers

1
votes

Your Compiler class implements ANTLRErrorListener, but you never use it or even instantiate it, so it doesn't have any effect.

Instead you instantiate BaseErrorListener, which does nothing (in fact, I'm a bit surprised that the code even compiled - I would have expected BaseErrorListener to be an abstract class).

If you replace new BaseErrorListener() with new Compiler(), your syntaxError method will be called.

PS: I would recommend that you rename your class to something including the words ErrorListener because the name Compiler certainly does not make it obvious that it's an error listener.