为何我的Antlr ParseTree及visit方法返回值为null?
问题根源与解决方案
核心问题1:Visitor方法名不匹配
ANTLR生成的MachDefBaseVisitor中,对应语法起始规则prog的访问方法是visitProg(MachDefParser.ProgContext ctx),但你的AntlrToProgram类里写的是visitProgram——这个方法不会被ANTLR的Visitor机制调用,因此默认返回null,这就是progVisitor.visit(antlrAST)返回null的直接原因。
核心问题2:方法返回类型不匹配
你的AntlrToProgram继承自MachDefBaseVisitor<Program>,但visitProgram方法的返回类型是Expression,虽然Program继承自Expression,但方法签名不匹配,进一步导致Visitor无法正确识别该方法。
额外问题:ParseTree打印为空的原因
调用antlrAST.toString()默认输出节点的简洁表示,如果语法解析过程中存在错误(比如语法规则不匹配),可能会导致节点结构异常显示为[],但getText()会返回所有输入文本,这是正常现象。可以添加错误监听排查语法问题。
修正后的代码
1. 修正AntlrToProgram类
public class AntlrToProgram extends MachDefBaseVisitor<Program> { public AntlrToProgram() { } // 修正方法名:visitProg 而非 visitProgram,返回类型改为Program @Override public Program visitProg(MachDefParser.ProgContext ctx) { Program prog = new Program(); AntlrToExpression exprVisitor = new AntlrToExpression(); // 避免重复调用visit,先存到变量里 for(int i = 0; i < ctx.getChildCount(); i++) { if(i == ctx.getChildCount()-1) { // 跳过EOF节点 continue; } Expression expr = exprVisitor.visit(ctx.getChild(i)); prog.addExpression(expr); System.out.println("Adding to prog: " + expr.toString()); } return prog; } }
2. 添加语法错误排查(可选)
在getParser方法中添加错误监听,查看解析过程中是否有语法错误:
private static MachDefParser getParser(String fileName) { MachDefParser parser = null; try { CharStream input = CharStreams.fromFileName("src//" + fileName); MachDefLexer lexer = new MachDefLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); parser = new MachDefParser(tokens); // 添加错误监听,打印语法错误 parser.removeErrorListeners(); parser.addErrorListener(new DiagnosticErrorListener()); } catch (IOException e) { e.printStackTrace(); } return parser; }
其他注意事项
- 确保你的语法文件(
.g4)中确实存在prog起始规则,且结构符合预期,比如prog应该包含多个表达式节点,最后以EOF结束。 - 检查
AntlrToExpression是否能正确处理prog子节点的解析,避免返回null导致Program中的表达式列表出现null元素。
内容的提问来源于stack exchange,提问作者N the Ninja
相关产品推荐
相关产品推荐

