【发布时间】:2014-01-04 06:52:02
【问题描述】:
我有一个对象的层次结构来表示算术表达式。类似于以下内容:
TreeNode
/ \
/ \
/ \
NumericNode BinaryOpNode
/ | \ \
/ | \ \
/ | \ \
AddNode MulNode DivNode ...etc
我的词法分析器和解析器正在工作。现在,我正在尝试找出以实用且易于适应的方式对生成的 AST 执行操作的最佳方法。 现在我已经用一个访问者和访问接口实现了访问者模式,但是我不确定我是否真的需要所有的具体类来实现访问者接口。
由于我想控制访问者的遍历顺序,我发现自己重复了很多代码。例如,对于 PrintInOrder 访问者,我有如下方法:
public void visit(AddNode node) {
node.getLeft().accept(this);
System.out.print(node + " ");
node.getRight().accept(this);
}
代表某个算术运算的每个具体节点。
但我可以在超类中实现相同的实现 Visitable。例如,相同的 PrintInOrder 访问者看起来像:
public void visit(BinaryOpNode node) {
node.getLeft().accept(this);
System.out.print(node + " ");
node.getRight().accept(this);
}
但是,我不知道这项任务最常用的方法是什么。
问题 1: 如果我希望我的设计让我几乎可以通过 AST 做任何我想做的事情,我真的需要访问所有具体节点并编写所有重复的代码吗?
问题 2:假设访问者可以返回某种类型,例如:
public interface Visitor<T> {
public T visit(AddNode node);
public T visit(MulNode node);
...
}
这看起来比普通的 void 版本更通用。但它有有用的好处吗?并且可以和void版本一样使用吗?
【问题讨论】:
标签: java parsing abstract-syntax-tree visitor-pattern