这个问题是How to write visitor classes for collections?的延续 - 我尝试了这个答案,但我发现代码在eclipse中工作,但在unix或windows中有一个空指针问题。所以现在它看起来像一个不同的问题,所以我创建了一个新问题。
我已在https://sites.google.com/site/rogergdmn/上传完整代码,以下是摘要。
以下是详细信息(代码是本书中LabeledExpr.g4的变体) - 我正在尝试使用访问者类创建中间数据结构。当我在命令行(在unix或windows中)运行时,会打印“why null e”这一行,但是当我在eclipse中运行时,不会打印这一行。我该如何修复这个错误?
这是语法:
prog: stat+ ;
stat: expr NEWLINE # printExpr
| NEWLINE # blank
;
expr: INT # int
;
这些是EvalVisitor.java中的函数:
public Object visitInt(ExprParser.IntContext ctx) {
System.out.printf("visited----- 1\n");
int value = Integer.valueOf(ctx.INT().getText());
return new E(1, value);
}
public Object visitPrintExpr(ExprParser.PrintExprContext ctx) {
System.out.printf("visited----- 2\n");
E e = (E) visit(ctx.expr()); // evaluate the expr child
return new E(2, e);
}
public Object visitProg(ExprParser.ProgContext ctx) {
System.out.printf("visited----- 3\n");
List<ExprParser.StatContext> sL = ctx.stat();
List<E> eL = new ArrayList<E>();
for(ExprParser.StatContext s : sL) {
E e = (E) visit(s);
if(e==null) System.out.printf("why null e??\n");
eL.add(e);
}
return new E(7, eL);
}
这是E类(仅显示构造函数,以演示错误):
public class E {
int typ;
int val;
E e1;
List<E> eL;
public E(int _typ, int _v) { typ = _typ; val = _v; }
public E(int _typ, E _e1) { typ = _typ; e1 = _e1; }
public E(int _typ, List<E> _eL) { typ = _typ; eL = _eL; }
}
其他代码直接来自书籍示例(http://pragprog.com/titles/tpantlr2/source_code,目录“starter”)。
顺便说一句,类似的访问者代码显示在If/else statements in ANTLR using listeners和https://github.com/bkiers/Mu,该代码适用于我。我的代码与该代码非常相似,所以我不确定这里出了什么问题。
答案 0 :(得分:3)
您没有覆盖visitBlank
,因此任何空白语句都会从null
方法返回visit
。
编辑:Eclipse和其他案例之间的区别是以下之一:
TokenStream
的原始内容以确定。EOF
规则的末尾添加明确的prog
,因此您的解析器可能会忽略输入的某些令牌。要确保在所有情况下都考虑所有令牌,请在EOF
规则的末尾添加对prog
的引用。