Default Error Reporting Behavior
Errors encountered during lexing and parsing are passed to the
displayRecognitionError() method. This method has access to the exception that holds information about the error, and uses it to compose an error string that is then passed to the
emitErrorMessage() method. The default behavior of
emitErrorMessage() is to print the error string to
Custom Error Reporting
To change the default error reporting behavior, override either the
displayRecognitionError() or the
emitErrorMessage() methods in the lexer and parser. If you need to change the format of the error message or obtain extra information, such as the error location, then you must override
displayRecognitionError(). If all you need to do is change where errors are reported and are happy to keep the error message itself unchanged, then you can just override
emitErrorMessage() instead. Here is an example of overriding
Rather than simply printing errors to a stream, another common approach is to store them in a data structure for use later in the application. An example of this approach is to append errors to a List within the lexer and parser and to provide a public method to allow access to the list:
A cleaner approach to error handling is to delegate reporting to a separate object using a defined interface. This has the advantage that it is easier to use different error handling strategies with the same lexer and parser. It also allows testing of the error reporting functionality in isolation from other components. Here is an example of an interface to handle errors:
The lexer and parser can then be modified to receive an object that implements this interface and reports errors to it, for example:
And finally you can create a class that implements the error reporting interface and pass an instance of that class to the lexer and parser, for example:
It is generally the case that the destination for errors does not change once lexing and parsing has begun, so a refinement on the above solution is to pass the error reporter object in as an extra parameter to the lexer and parser constructor methods, instead of using a completely separate method.
Single token insertion and deletion
As of v3.1, you can turn on and off single token insertion/deletion error recovery. It is off by default for tree parsers. This happens because
recoverFromMismatchedToken() to do nothing but throw an exception. To illustrate, here is some invalid input for a small C-like programming language:
By default, you get errors and tree output:
(Assuming Main.java prints the tree).
Add the following to your grammar to override the default insert/delete behavior:
and now you get
ANTLR shows the mismatched token in the tree now; it didn't recover as it did before.