2

我正在使用Ruby編寫的編譯器,目前我正處於語義分析階段(類型檢查)。我有一個需要以兩種方式訪問​​的AST:預購和後訂單,我想知道在Ruby中執行此操作的最佳方式是什麼。我知道傳遞一個塊到each本質上是訪問者模式,但由於我需要以兩種方式訪問​​(前,後),而Ruby不支持方法重載,所以我不知道如何處理這個問題。預購和後訂購訪客

(注:我想有一個Node對象控制如何訪問,所以我的觀衆是不是臃腫)

這裏是什麼,我想嘗試:

兩個接受的方法每個Node類accept_preaccept_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 

有沒有更好的辦法來做到這一點的相應accept_preaccept_post方法呢?儘管我需要兩個訂單,可以用.each完成嗎?

任何幫助,將不勝感激。

回答

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 
+0

您還需要顛倒孩子的遍歷。 – 2013-03-23 17:03:55

+0

@DonRoby好點,修好了。 – dbenhur 2013-03-23 17:13:05

+0

這實際上看起來像一個很好的解決方案。我不知道'send'方法。謝謝! – 2013-03-23 17:18:11