无法捕获 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
肯定不会让人觉得它是一个错误侦听器。
我试图在访问 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
肯定不会让人觉得它是一个错误侦听器。