1

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.

Mr.Zeus
  • 424
  • 8
  • 25
Niek Jonkman
  • 1,014
  • 2
  • 13
  • 31

1 Answers1

1

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675