15

How can I get rid of the default ANTLR recognition error?

I want to write another message using my own error class instead of ANTLR's error.

I mean is there any possibility that some ANTLR error classes can be extended in order to display my own message?

More clearly, I do not want to see the following error message in my console :

token recognition error at:

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
Hakan Özler
  • 968
  • 1
  • 10
  • 22

2 Answers2

12

If you simply want to suppress the messages, you can call lexer.removeErrorListeners(). However, a better approach is writing your lexer rules such that all possible input is tokenized, with the following rule at the end of the lexer. This will cause all error reporting to go through the parser instead of both the parser and lexer.

// handle characters which failed to match any other token
ErrorCharacter : . ;
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • Still seems to print the message to System.err, but thanks for this it is helpful – Kip Oct 05 '16 at 19:40
  • 1
    Can't find removeErrorListeners() in lexer generated by ANTLR4 (your C# target). Would you point me where it could be? – tsul Jun 14 '17 at 03:09
7

In order to create a custom error handler you can extend the BaseErrorListener class and override the syntaxError method, e.g.:

public class MyErrorListener extends BaseErrorListener {
  @Override
  public void syntaxError( Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
                           String msg, RecognitionException e ) {
    // method arguments should be used for more detailed report
    throw new RuntimeException("syntax error occurred");
  }
}

Now when you create a lexer and a parser you should remove the default error listeners and attach your custom one:

MyErrorListener errorListener = new MyErrorListener();

Lexer lexer = new MyLexer( ... );
lexer.removeErrorListeners();
lexer.addErrorListener( errorListener );

CommonTokenStream tokens = new CommonTokenStream( lexer );

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

The default message "line x:x token recognition error at: 'xxx'" comes from the default ConsoleErrorListener class. If you don't remove it using lexer/parser.removeErrorListeners() and only add your custom one it will still be triggered.

The error handling strategies are thoroughly described in a dedicated chapter of The Definitive ANTLR4 Reference book (mentioned on the ANTLR4 Documentation page). I currently have no access to the book itself, so would be grateful if someone edits this answer with a concrete page number of the book. Also, I couldn't find a related guide on the ANTLR4 doc page, so if it exists - a link would be helpful, too.

Scadge
  • 9,380
  • 3
  • 30
  • 39
  • This helped. I was trying to figure out why my ErrorListener class (extends from BaseErrorListener) kept emitting errors from syntaxError(...) despite overriding it. Removing the default error listener with removeErrorListeners was what I had to do. – TheProgrammer Dec 18 '20 at 04:10