ANTLR 4:避免打印到控制台时出错

ANTLR 4:避免打印到控制台时出错,antlr,antlr4,Antlr,Antlr4,使用ANTLR,我解析语法。ANTLR错误在语法的自定义编辑器中指示。 但是,我想禁用向Java控制台打印错误消息 我已经实现了自己的BaseErrorListener,并删除了ANTLR手册中描述的默认设置: MyErrorListener errList=new MyErrorListener (); lexer.removeErrorListeners(); lexer.addErrorListener(errList); parser.removeErrorListeners();

使用ANTLR,我解析语法。ANTLR错误在语法的自定义编辑器中指示。 但是,我想禁用向Java控制台打印错误消息

我已经实现了自己的BaseErrorListener,并删除了ANTLR手册中描述的默认设置:

MyErrorListener errList=new MyErrorListener ();
lexer.removeErrorListeners();
lexer.addErrorListener(errList);
parser.removeErrorListeners();   
parser.addErrorListener(errList);
我仍然会将打印的输出发送到Java控制台(连接到Java输出和错误流)


如何在ANTLR中禁用控制台打印?

您可以检查您有哪些侦听器

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

查找
ConsoleErrorListener

我终于找到了解决方案。我在语法之前有一个过滤器:

Filter filter = new Filter(tokens)
其中还必须删除筛选器的侦听器(预解析器类):

filter.removeErrorListeners();

默认情况下,
ConsoleListener
被激活[1]

您可以在代码中删除它:

lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);

[1] (请参见添加(ConsoleErrorListener.INSTANCE);)

ANTLR警告将打印到os.Stderr。因此,您可以做的是重定向Stderr,捕获所有警告,并决定如何处理它们

当然,这意味着您的程序在解析过程中不能向Stderr输出任何内容

伪代码,只是为了得到要点

//重定向stdout-antlr运行时打印到stdout时出错
外扩:=制造(成串)
stderr:=os.Stdout
r、 w,err:=os.Pipe()
如果出错!=零{
返回错误
}
os.Stderr=w
//捕获标准
go func(){
var buf字节。缓冲区
io.副本(&buf,r)

你在你的“MyErrorListener”里干什么?在扩展BaseErrorListener的my listener中,我收集错误并提取行号以在我的自定义编辑器中标记它们。我不会将任何内容打印到标准输出。感谢您的回答,我已经有一段时间没有检查此问题了。我有一个扩展BaseErrorListener的自定义侦听器。此(我的侦听器)是我通过上面的代码片段得到的打印输出。这是错误的答案。它将删除所有侦听器,但您只想删除打印到控制台的侦听器。请参阅@uwolfer answer。对我来说,从解析器中删除侦听器是有效的。