直譯器模式用於描述如何構成乙個簡單的語言直譯器,主要應用於使用物件導向語言開發的直譯器的設計。當需要開發乙個新的語言時可以考慮使用直譯器模式。
在某些情況下,為了更好地描述某些特定型別的問題可以建立一種新的語言,這種語言擁有自己的表示式和結構,即文法規則,這些問題的例項將對應為該語言中的句子,此時可以使用直譯器模式來設計這種新的語言。
定義如下:
直譯器模式:給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子。
interperter pattern:given a language,define a representation for its grammar along with an interpreter
that uses the representation to interpret sentences in the language.
在直譯器模式的定義中所指的「語言」是使用規定格式和語法的**,直譯器模式是一種類行為型模式。
如「1+2+3-4+1」都包含了3個語言單位,可以使用以下文法規則來定義:
expression :: = value | operation
operation :: = expression ' + ' expression | expression ' - ' expression
value :: = an integer //乙個整數值
該文法規則包含3條語句,第一條表示表示式的組成方式,其中value和operation是後面兩個語言單位的定義,每一條語句所定義的字串(如operation和value)稱為語言構造成分或語言單位,符號「:: ="是」定義為「的意思,其左邊的語言單位通過右邊來進行說明和定義,語言單位對應終結符表示式和非終結符表示式。例如本規則中operation是非終結符表示式,它的組成元素仍然可以是表示式,可以進一步分解,而value是終結符表示式,它的組成元素是最基本的語言單位,不能再進行分解。
在文法規則定義中可以使用一些符號來表示不同的含義,如使用「|」表示或、使用「」表示組合、使用「*」表示出現0次或多次等。除了使用文法規則來定義乙個語言外,在直譯器模式中還可以通過一種稱為抽象語法樹(abstract syntax tree,ast)的圖形方式來直觀地表示語言的構成,每一棵抽象語法樹對應乙個語言例項。抽象語法樹描述了如何構成乙個複雜的句子,通過對抽象語法樹的分析可以識別出語言中的終結符類和非終結符類。
(1)abstractexpression(抽象表示式):在抽象表示式中宣告了抽象的解釋操作,它是所有終結符表示式和非終結符表示式的公共父類。
(2)terminalexpression(終結符表示式):終結符表示式是抽象表示式的子類,它實現了與文法中的終結符相關聯的解釋操作,在句子中的每乙個終結符都是該類的乙個例項。通常在乙個直譯器模式中只有少數幾個終結符表示式類,它們的例項可以通過非終結符表示式組成較為複雜的句子。
(3)nonterminalexpression(非終結符表示式):非終結符表示式也是抽象表示式的子類,它實現了文法中非終結符的解釋操作,由於在非終結符表示式中可以包含終結符表示式,也可以繼續包含非終結符表示式,因此其解釋操作一般通過遞迴的方式完成。
(4)context(環境類):環境類又稱為上下文類,它用於儲存直譯器之外的一些全域性資訊,通常它臨時儲存了需要解釋的語句。
抽象表示式類,典型**如下:
public abstract class abstractexpression
終結符表示式類,典型**如下:
public class terminalexpression extends abstractexpression
}
非終結符表示式,其典型**如下:
public class nonterminalexpression extends abstractexpression
public void interpret(context ctx)
}
環境類,典型**如下:
public class context
public string lookup(string key)
}
當系統無須提供全域性公共資訊時可以省略環境類,根據實際情況決定是否需要環境類。
(1)易於改變和擴充套件文法。由於在直譯器模式中使用類表示語言的文法規則,因此可以通過繼承等機制來改變或擴充套件文法。
(2)每一條文法規則都可以表示為乙個類,因此可以方便地實現乙個簡單的語言。
(3)實現文法較為容易。
(4)增加新的解釋表示式較為方便。如果使用者要增加新的解釋表示式只需要對應增加乙個新的終結符表示式或非終結符表示式類,原有表示式類**無須修改,符合開閉原則。
(1)對於複雜文法難以維護。在直譯器模式中每一條規則至少需要定義乙個類,因此如果乙個語言包含太多文法規則,類的個數將會急劇增加,導致系統難以管理和維護,此時可以考慮使用語法分析程式等方式來取代直譯器模式。
(2)執行效率低。由於在直譯器模式中採用了大量的迴圈和遞迴呼叫,因此在解釋較為複雜的句子時其速度很慢,而且**的除錯過程也比較麻煩。
(1)可以將乙個需要解釋執行的語言中的句子表示為一棵抽象語法樹。
(2)一些重複出現的問題可以用一種簡單的語言進行表達。
(3)乙個語言的文法較為簡單。對於複雜的文法,直譯器模式中的文法類層次結構將變得很龐大而無法管理,此時最好使用語法分析程式生成器。
(4)執行效率不是關鍵問題。高效的直譯器通常不是通過直接解釋抽象語法樹來實現的,而是需要將它們轉換成其他形式,使用直譯器模式的執行效率並不高。
Java設計模式之直譯器模式
定義 一種語法分析工具,用來分步解釋乙個複雜的運算過程,複雜運算拆分成多個小運算。需求 計算 1 2 3 4 的值。必備元素 建立直譯器介面,裡面包含乙個解釋操作的方法 public inte ce expression 建立終結符表示式,裡面計算加法 public class terminalex...
Java設計模式筆記之直譯器模式
1.定義 直譯器模式 interpreter 給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子。2.uml圖 角色介紹 3.通用模式 抽象表示式 public abstract class abstractexpression 3.2 終結表示式 終結符...
JAVA設計模式 直譯器模式
直譯器模式 給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子。如果乙個特定型別的問題發生的頻率足夠高,那麼可能就值得將該問題的各個例項表述為乙個簡單語言的句子。這樣就可以構建乙個直譯器,該直譯器通過解釋這些句子來解決該問題。使用 當有乙個語言需要解釋執行...