首页 > 解决方案 > 无法捕获 ANTLR4 语法错误

问题描述

在访问ParseTree. 简化后,我声明双精度的语法是这样的:

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

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

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

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

编译器类:

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. 每当发现错误时,我都不想继续。我认为通过像我一样实现错误侦听器,我可以创建自己的错误消息并停止运行程序。我预计该syntaxError方法会被触发,但事实并非如此。我已使用此主题作为参考。

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

提前致谢。

标签: javagrammarantlr4

解决方案


你的Compiler类实现ANTLRErrorListener了,但你从不使用它甚至实例化它,所以它没有任何效果。

相反,您实例化BaseErrorListener了,它什么都不做(事实上,我对代码甚至编译后感到有点惊讶——我本来希望BaseErrorListener它是一个抽象类)。

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

PS:我建议您将您的类重命名为包含单词的名称,ErrorListener因为该名称Compiler肯定不会表明它是一个错误侦听器。


推荐阅读