ANTLR 4: Avoid error printing to console
Asked Answered
N

4

21

With ANTLR I parse a grammar. The ANTLR errors are indicated in a custom editor for the grammar. However I would like to disable the printing of error messages to a Java console.

I've implemented my own BaseErrorListener and removed the default as described in the ANTLR book:

MyErrorListener errList=new MyErrorListener ();
lexer.removeErrorListeners();
lexer.addErrorListener(errList);
parser.removeErrorListeners();   
parser.addErrorListener(errList);

Still I get printed outputs to my Java console (connected to the Java output and error stream).

How can I disable the printing to the console in ANTLR?

Noami answered 23/9, 2014 at 8:14 Comment(2)
What are you doing in your "MyErrorListener"?Carline
In my listener which extends the BaseErrorListener I collect errors extract the linenumber to mark them in my custom editor. I do not print anything to the standard output.Noami
N
1

I finally found the solution. I have a filter before the grammar:

Filter filter = new Filter(tokens)

where the listener of the filter (a pre parser class) also has to be removed:

filter.removeErrorListeners();
Noami answered 6/10, 2015 at 14:29 Comment(1)
This is wrong answer it will remove all listeners but you want to remove just listener that prints to console. Please see @Silicone answer.Splatter
S
24

By default, ConsoleListener is activated [1].

You can remove it in your code:

lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);

[1] https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java#L56 (see add(ConsoleErrorListener.INSTANCE);)

Silicone answered 9/2, 2016 at 7:53 Comment(3)
For me, removing the listener from the parser worked.Rubbery
Or just parser.removeErrorListeners();Ariannearianrhod
parser.RemoveErrorListeners(); // for c#, case notation :)Legionary
T
3

You can check what listeners you have

for (ANTLRErrorListener listener : parser.getErrorListeners()) {
        System.out.println(listener);
}

Look for ConsoleErrorListener.

Torto answered 13/4, 2015 at 15:32 Comment(1)
Thanks for the answer, I haven't checked this question for a while. I have a custom Listener which extends the BaseErrorListener. This (my listener) is what I get as printed output with the code snippet above.Noami
N
1

I finally found the solution. I have a filter before the grammar:

Filter filter = new Filter(tokens)

where the listener of the filter (a pre parser class) also has to be removed:

filter.removeErrorListeners();
Noami answered 6/10, 2015 at 14:29 Comment(1)
This is wrong answer it will remove all listeners but you want to remove just listener that prints to console. Please see @Silicone answer.Splatter
M
1

ANTLR warnings are printed to os.Stderr. Hence, what you could do is to redirect Stderr, capture all warnings, and decide what to do with them.

Of course, this means your program can not print out anything to Stderr during the parse.

Pseudocode, just to get the gist.

    // redirect stdout - antlr runtime prints to STDOUT on error
    outStream := make(chan string)
    stderr := os.Stdout
    r, w, err := os.Pipe()
    if err != nil {
        return err
    }
    os.Stderr = w

    // capture stderr
    go func() {
        var buf bytes.Buffer
        io.Copy(&buf, r)
        outStream <- buf.String()
    }()

    // run parse with stdout redirected
    go func() {
        // ANTLR can, and WILL panic in a pythonic fashion!
        defer func() {
            if r := recover(); r != nil {
                listener.err = errors.Append(listener.err, errors.E(r.(string)).WithOperation("ParseString"))
            }
        }()
        stream := antlr.NewInputStream(ddl)
        lexer := parser.NewTeradataStatementLexer(stream)
        tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
        prsr := parser.NewTeradataStatementParser(tokenStream)
        antlr.ParseTreeWalkerDefault.Walk(&listener, prsr.Program())
        w.Close()          // close redirected stdout
        os.Stderr = stderr // redirect to normal stdout
    }()

    // capture stdout and check for errors
    parseStdout := <-outStream
    if parseStdout != "" {
        // non empty stderr, handle errors reported by ANTLR
    }
Morrell answered 15/1, 2021 at 8:5 Comment(1)
This is a crazy solution to the problem. Just remove the default error listeners as described in the above answers...Quarters

© 2022 - 2024 — McMap. All rights reserved.