一、引子
其實沒有什麼好的例子引入解譯器模式,因為它描述了如何構成一個簡單的語言解譯器,主要應用在使用物件導向語言開發編譯器中;在實際應用中,我們可能很少碰到去構造一個語言的文法的情況。
雖然你幾乎用不到這個模式,但是看一看還是能受到一定的啟發的。
二、定義與結構
解譯器模式的定義如下:定義語言的文法,並且建立一個解譯器來解釋該語言中的句子。它屬於類的行為模式。這裡的語言意思是使用規定格式和文法的代碼。
在GOF的書中指出:如果一種特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個執行個體表述為一個簡單語言中的句子。這樣就可以構建一個解譯器,該解譯器通過解釋這些句子來解決該問題。而且當文法簡單、效率不是關鍵問題的時候效果最好。
這也就是解譯器模式應用的環境了。
讓我們來看看神秘的解譯器模式是由什麼來組成的吧。
1) 抽象運算式角色:聲明一個抽象的解釋操作,這個介面為所有具體運算式角色(抽象文法樹中的節點)都要實現的。
什麼叫做抽象文法樹呢?《java與模式》中給的解釋為:抽象文法樹的每一個節點都代表一個語句,而在每個節點上都可以執行解釋方法。這個解釋方法的執行就代表這個語句被解釋。由於每一個語句都代表這個語句被解釋。由於每一個語句都代表一個常見的問題的執行個體,因此每一個節點上的解釋操作都代表對一個問題執行個體的解答。
2) 終結符運算式角色:具體運算式。
a) 實現與文法中的終結符相關聯的解釋操作
b) 而且句子中的每個終結符需要該類的一個執行個體與之對應
3) 非終結符運算式角色:具體運算式。
a) 文法中的每條規則R::=R1R2…Rn都需要一個非終結符錶帶式角色
b) 對於從R1到Rn的每個符號都維護一個抽象運算式角色的執行個體變數
c) 實現解釋操作,解釋一般要遞迴地調用表示從R1到Rn的那些對象的解釋操作
4) 上下文(環境)角色:包含解譯器之外的一些全域資訊。
5) 客戶角色:
a) 構建(或者被給定)表示該文法定義的語言中的一個特定的句子的抽象文法樹
b) 調用解釋操作
放上張解譯器結構類圖吧,這也是來自於GOF的書中。
對每一個角色都給出了詳細的職責,而且在類圖中給出五個角色之間的關係。這樣實現起來也不是很困難了,下面舉了一個簡單的例子,希望能加深你對解譯器模式的理解。