我正在研究用Ruby编写的编译器,目前我处于语义分析阶段(类型检查)。我有一个AST需要以两种方式访问:预订和后期订单,我想知道在Ruby中最好的方法是什么。我知道将块传递给each
本质上就是访问者模式,但由于我需要以两种方式访问(pre,post)并且Ruby不支持方法重载,所以我不确定如何处理它。
(注意:我正在尝试让Node对象控制它们的访问方式,因此我的访问者不会膨胀)
以下是我正在考虑的尝试:
为调用其他节点的相应accept_pre
和accept_post
方法的每个Node类accept_pre
和accept_post
提供两种接受方法
class Node
def initialize(a, b, c)
@a, @b, @c = a, b, c
end
def accept_pre(visitor)
@a.accept_pre visitor
@b.accept_pre visitor
@c.accept_pre visitor
vistor.visit_node(self)
end
def accept_post(visitor)
visitor.visit_node(self)
@c.accept_post visitor
@b.accept_post visitor
@a.accept_post visitor
end
end
有更好的方法吗?可以用.each
来完成,即使我需要两个订单吗?
任何帮助都将不胜感激。
答案 0 :(得分:3)
您可以使用遍历选项arg将两个排序折叠成一个接受。您当然可以通过节点成员使用每个成员来分派孩子的接受。
class Node
def initialize(a, b, c)
@a, @b, @c = a, b, c
end
def accept(visitor, traversal=:pre)
visitor.visit(self) if traversal == :pre
order = traversal == :pre ? :each : :reverse_each
[@a,@b,@c].send(order) { |e| e.accept(visitor, traversal) }
visitor.visit(self) if traversal == :post
end
end