无法捕获 ANTLR4 语法错误

Unable to catch ANTLR4 Syntax errors

我试图在访问 ParseTree 之前捕获 ANTLR4 中的语法错误。简化一下,我声明 double 的语法是这样的:

double 类型的语法(解析器规则):

declare_double: DOUBLE_TYPE  WHITESPACE ID WHITESPACE(EQUALS WHITESPACE DOUBLE)? SEMICOLON;

double 类型的语法(词法分析器规则):

DOUBLE: [0-9]+ '.' [0-9]+ | '.' [0-9]+ | [0-9]+;

编译器class:

public class Compiler implements ANTLRErrorListener {
    public static void main(String[] args) {

        //CharStream chars = CharStreams.fromString("double a = 3.1415;");
        CharStream chars = CharStreams.fromString("double a = 3;");


        SimpleJavaLexer lexer = new SimpleJavaLexer(chars);
        CommonTokenStream tokens = new CommonTokenStream(lexer);

        SimpleJavaParser parser = new SimpleJavaParser(tokens);

        ANTLRErrorListener errorListener = new BaseErrorListener();

        //parser.removeErrorListeners();

        parser.addErrorListener(errorListener);

        SimpleJavaParser.ProgramContext programTree = parser.program();


        TypeChecker visitor = new TypeChecker();
        visitor.visit(programTree);
    }

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object o, int i, int i1, String s, RecognitionException e) {
        System.out.println("Syntax Error");
    }

    @Override
    public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
        System.out.println("Report ambiguity");
    }

    @Override
    public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
        System.out.println("Report attempting full context");
    }

    @Override
    public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
        System.out.println("Report context sensitivity");
    }
}

如果我 运行 这样做并且不从解析器中删除默认侦听器,我会得到以下结果:

默认错误侦听器输出

    line 1:11 mismatched input '3' expecting DOUBLE
    line 1:12 extraneous input ';' expecting {<EOF>, WHITESPACE, '(', INTEGER,BOOLEAN, DOUBLE, STRING, ID}

我遇到的问题是,在显示此错误后,访问者被实例化,它将访问 TypeChecker。每当发现错误,我就不想继续了。我认为通过像我那样实现错误侦听器,我可以创建自己的错误消息并停止 运行ning 程序。我希望触发 syntaxError 方法,但它没有。我用了this topic作为参考。

我如何适当地侦听错误并相应地管理它们?

提前致谢。

您的 Compiler class 实现了 ANTLRErrorListener,但您从未使用过它,甚至从未实例化过它,因此它没有任何效果。

相反,您实例化 BaseErrorListener,它什么都不做(事实上,我有点惊讶代码甚至被编译了——我本以为 BaseErrorListener 是一个抽象的 class).

如果您将 new BaseErrorListener() 替换为 new Compiler(),您的 syntaxError 方法将被调用。

PS:我建议您将 class 重命名为包含单词 ErrorListener 的名称,因为名称 Compiler 肯定不会让人觉得它是一个错误侦听器。