2012-01-26 54 views
2

我正在Ruby中構建一個詞法分析器,並且即將開始在符號表中收集和存儲符號。我關於符號設計的主要問題以及它是否應該是靜態表(意味着所有數據將保持在課程級別),還是應該以實例爲基礎。Ruby中的符號表設計和實現

選項1:類級別的數據結構

require 'SymbolTableEntry.rb' 

class SymbolTable 
    @sym_table = Array.new(500) 
    def initialize() 
    end 

    def SymbolTable.add(element, index) 
    @sym_table[index] = element if element.is_a? SymbolTableEntry 
    end 

    def SymbolTable.to_s 
    pp @sym_table 
    end 
end 

使用這種方案的符號表類有一個排序的「靜態」的功能,這意味着我不實際創建符號表的一個實例,唯一存在的對象是類一級。

(假設SymbolTableEntry是即使我在這裏不把它定義一個有效的對象)

例:

irb(main):002:0> require 'SymbolTable.rb' 
=> true 

irb(main):003:0> ste = SymbolTableEntry.new 
=> #<SymbolTableEntry:0x7ef36884> 

irb(main):004:0> SymbolTable.add(ste, 10) 
=> #<SymbolTableEntry:0x7ef36884> 

irb(main):005:0> SymbolTable.to_s 
[nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
#<SymbolTableEntry:0x7ef36884>] 
=> nil 

選項2:實例級數據結構

require 'rubygems' 
require 'backports' 
require 'SymbolTableEntry.rb' 

class SymbolTable 
    def initialize() 
    @sym_table = Array.new(10) 
    end 

    def add(element, index) 
    @sym_table[index] = element if element.is_a? SymbolTableEntry 
    end 

    def to_s 
    pp @sym_table 
    end 
end 

有了這個方案,我實際上需要實例化一個SymbolTable類的實例,以便將值添加到sym bol桌子。

irb(main):001:0> require 'SymbolTable.rb' 
=> true 

irb(main):002:0> st = SymbolTable.new 
=> #<SymbolTable:0x7eeb6c9c @sym_table=[nil, nil, nil, nil, nil, 
             nil, nil, nil, nil, nil]> 

irb(main):003:0> ste=SymbolTableEntry.new 
=> #<SymbolTableEntry:0x7eeb4d5c> 

irb(main):004:0> st.add(ste,10) 
=> #<SymbolTableEntry:0x7eeb4d5c> 

irb(main):007:0> st.to_s 
[nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
nil, 
#<SymbolTableEntry:0x7eeb4d5c>] 
=> nil 

我很樂意聽到任何和所有輸入上的設計,你會使用或喜歡使用,以及對一般的Ruby代碼的任何評論。

感謝

回答

1

不想實例變量在類變量,如果沒有其他原因,比使用類變量類是更痛苦的單元測試了一下。

您可以使用實例變量,並且仍然有一個符號表來統一它們。一種方法是將您的符號表分配給全局變量:

$symbol_table = SymbolTable.new 

在某些語言中,使用全局變量的類很難測試。在Ruby中,它們並不是那麼糟糕,因爲鴨子打字可以讓你在執行被測對象之前將模擬對象分配給全局變量。

或者,您可以使用單例模式。 Ruby有一個圖書館,使這個簡單:

require 'singleton' 
class SymbolTable 
    include Singleton 
    ... 
end 

要檢索符號表的一個只和實例,如果需要創建它:

SymbolTable.instance 
+0

謝謝,這是非常有幫助的。 –

+0

我認爲Singleton絕對是要走的路,因爲我肯定只需要在整個編譯過程中使用SymbolTable的一個實例。謝謝 –

+0

@Hunter,不客氣,謝謝你的提問。 –

1

使用實例變量。但由於測試處理的原因,至少不是(至少不是)。而是因爲

  • 每解析過程中會產生它自己的符號表,所以你可能有多個同時
  • 只需要符號表只要解析工作正在進行
  • 類變量引入的必要性做同步實現線程安全的 - 即使每天的解析過程可以有自己的一套符號生活得很好

乾杯

robert

+0

總體目標是構建一個功能正常的編譯器,它一次只能編譯一個源文件。但是這對於實例變量來說是一個很好的參數。謝謝。 –

+0

即使您需要一次只編譯一個文件,這裏也不需要全局變量。相反,彙編的狀態很容易在彙編中保留下來,並在記憶中無用。另外,如果您決定可以並行執行多個編譯,這似乎不太不切實際,那就更容易了。 –

0

只是羅伯特和韋恩給出的幾個答案的快速說明,兩者都提到類變量

原來的問題不建議使用在所有類變量但並詢問有關使用類的實例變量。第一個選擇的Hunter使用類對象本身作爲符號表的單個實例(狀態存儲在類實例變量中),而第二個選項使用更典型的類/實例框架,狀態存儲在符號實例中表。

Ruby的類變量與類實例變量不一樣,通常應該避免。