By default a org.antlr.v4.runtime.Parser instance, as a subclass of org.antlr.v4.runtime.Recognizer, will have a org.antlr.v4.runtime.ConsoleErrorListener attached to it. Error messages will be piped through this listener and out to System.err, where they will be lost forever.
You can silence this output by calling removeErrorListeners() before parsing, and if you want to capture the error messages for parsing and display, you can add a custom BaseErrorListener implementation.
Here’s a simple one that keeps every error in a List`:
1public class DSLErrorListener extends BaseErrorListener
2{
3 private List<SyntaxErrorItem> items;
4
5 public DSLErrorListener ( )
6 {
7 this.items = new ArrayList<SyntaxErrorItem>();
8 }
9
10 @Override
11 public void syntaxError ( Recognizer<?, ?> recognizer,
12 Object offendingSymbol,
13 int line,
14 int charPositionInLine,
15 String msg,
16 RecognitionException e )
17 {
18 items.add ( new SyntaxErrorItem ( line,
19 charPositionInLine,
20 msg,
21 offendingSymbol,
22 e )
23 );
24 }
25
26 public boolean hasErrors ( )
27 {
28 return this.items.size() > 0;
29 }
30
31 @Override
32 public String toString ( )
33 {
34 if ( !hasErrors() ) return "0 errors";
35 StringBuilder builder = new StringBuilder();
36 for ( SyntaxErrorItem s : items )
37 {
38 builder.append ( String.format ( "%s\n", s ) );
39 }
40 return builder.toString();
41 }
42}
43
44class SyntaxErrorItem
45{
46 private int line;
47
48 private Object offendingSymbol;
49
50 private int column;
51
52 private String msg;
53
54 private RecognitionException oops;
55
56 SyntaxErrorItem ( int line,
57 int column,
58 String msg,
59 Object symbol,
60 RecognitionException oops )
61 {
62 this.line = line;
63 this.column = column;
64 this.msg = msg;
65 this.offendingSymbol = symbol;
66 this.oops = oops;
67 }
68
69 @Override
70 public String toString()
71 {
72 if ( oops == null ) return String.format ( "[%d:%d] %s", line, column, msg );
73 else {
74 StringWriter sw = new StringWriter();
75 PrintWriter pw = new PrintWriter ( sw );
76 oops.printStackTrace(pw);
77 pw.close();
78 return String.format ( "[%d:%d] %s\n%s", line, column, msg, sw.toString() );
79 }
80 }
81}You would add it to a Parser using the addErrorListener method.
Here’s a complete example:
1ANTLRInputStream input = ...;
2Lexer lexer = ...;
3CommonTokenStream tokens = new CommonTokenStream ( lexer );
4DSLErrorListener errorListener = new DSLErrorListener();
5Parser parser = ...;
6parser.removeErrorListeners();
7parser.addErrorListener ( errorListener );
8ParseTree tree = ...; // Usually the parser subclass top-level rule name
9if ( errorListener.hasErrors() ) System.err.printf( "%s\n", errorListener ); // Or parse the errors: up to you
10else {
11 ParseTreeWalker walker = new ParseTreeWalker();
12 // Walk the tree or visit it
13}