意圖:
給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子.
適用性:
1、當有乙個語言需要解釋執行,並且你可以把該語言中的句子表示為乙個抽象的語法樹時,可使用直譯器模式.而當存在以下情況時,該模式的效果最好:
2、該文法簡單,對於複雜的文法,文法的類層次變得龐大而無法管理.此時,語法分析程式生成器這樣得工具時更好得選擇。它們無需構建抽象語法樹即可解釋表示式,這樣可以節省空間而且還可以節省時間;
3、效率不是乙個關鍵的問題,最高效的直譯器通常不是通過直接解釋語法分析樹實現的,而是首先把他們轉換成另外一種形式.例如:正規表示式通常被轉換成狀態機。但即使在這種情況下,轉換器仍可用直譯器模式實現,該模式仍是有用的.
結構圖:
設計模式中的幾種角色:
abstractexpression:
- 宣告乙個抽象的
interpret
方法,抽象語法樹中所有的節點都必須實現該抽象方法。
terminalexpression:
- 實現和語法中末端符號相關的
interpret
方法。-
在每個句子的末端符號中均需要乙個
terminalexpression
例項。nonterminalexpression:
另外乙個實現了
abstractexpression
介面的類,用來處理語法樹中非末端節點的語法。它含有下乙個
abstractexpression
(s)的引用,呼叫它每個子節點的
interpret
方法。context:
interpreter
方法所需要的資訊的容器,該資訊對
interpreter
而言全域性可見。充當幾個
abstractexpresssion
例項之間的通訊頻道。
patternclient:
構建或者接收乙個抽象語法書的例項。對於乙個特定的句子而言,語法樹往往由若干個
terminalexpressions
和nonterminalexpression
組成。patterclient
在合適的
context
下,呼叫
interpret
方法。interpreter
模式的應用場合是
interpreter
模式應用中的難點,只有滿足
「業務規則頻繁變化,且類似的模式不斷重複出現,並且容易抽象為語法規則的問題
」才適合使用
interpreter
模式。使用
interpreter
模式來表示文法規則,從而可以使用物件導向技巧來方便地「擴充套件
」文法。
interpreter
模式比較適合簡單的文法表示,對於複雜的文法表示,
interpreter
模式會產生比較大的類層次結構,這時候就不應該採用
interpreter
模式了。
效率不是乙個
interpreter
關心的關鍵問題。最高效的直譯器通常不是通過直接解釋語法分析樹實現的,而是首先將它們轉換成另一種形式。例如:正規表示式通常被轉換成狀態機。但即使在這種情況下,如果效率不是乙個關鍵問題,轉換器仍可用
interpreter
模式實現,該模式仍是有用的。
**:以下是乙個運用interpretor模式完成羅馬數字到阿拉伯數字轉換的例子,其中用到了後面將講到的template method模式,注意,該程式只能處理萬以下的數值轉換
#include #include using namespace std;
// "context"
class context
friend class expression;
friend ostream& operator << (ostream& os, context& context)
};// "abstractexpression"
class expression
else if (input.find(four()) == 0)
else if (input.find(five()) == 0)
while (input.find(one()) == 0)
}virtual const char* one() = 0;
virtual const char* four() = 0;
virtual const char* five() = 0;
virtual const char* nine() = 0;
virtual int multiplier() = 0;
};// thousand checks for the roman numeral m
// "terminalexpression"
class thousandexpression : public expression
const char* four()
const char* five()
const char* nine()
int multiplier()
};// hundred checks c, cd, d or cm
// "terminalexpression"
class hundredexpression : public expression
const char* four()
const char* five()
const char* nine()
int multiplier()
};// ten checks for x, xl, l and xc
// "terminalexpression"
class tenexpression : public expression
const char* four()
const char* five()
const char* nine()
int multiplier()
};// one checks for i, ii, iii, iv, v, vi, vii, viii, ix
// "terminalexpression"
class oneexpression : public expression
const char* four()
const char* five()
const char* nine()
int multiplier()
};int main()
; vectorv_exp(exp, exp + sizeof(exp) / sizeof(expression*));
vector::iterator it = v_exp.begin();
for (; it != v_exp.end(); it++)
cout << roman.c_str() << "=" << context << endl;
}
composite模式:抽象語法樹是乙個復合模式的例項
flyweight模式:說明了如何在抽象語法樹中共享終結符
iterator模式:直譯器可用乙個迭代器遍歷該結構
visitor模式:可用來在乙個類中維護抽象語法樹中各節點的行為
設計模式之解析器
一 作用 定義乙個語言的文法,並且建立乙個直譯器來解釋該語言中的句子,這裡的 語言 是指使用規定格式和語法的 直譯器模式是一種類行為型模式。二 特點 它將文法分為終結者和非終結者,挺簡單的。三 例子 抽象表示式 abstract class node 非終結符表示式 class addnode ex...
設計模式 解析器(parser)
特定領域,某些變化雖然頻繁,但是可以抽象為某種規則 結合特定領域,將問題抽象為語法規則,從而給出該領域的一般性解決方案。interpreter屬於 領域規則 模式。motivation 軟體構件過程中,對於某一特定領域的問題比較複雜,類似結構重複出現 可以將特定領域的問題表達為語法規則下的句子,然後...
Interpreter解析器模式
在特定領域中,某些變化雖然頻繁,但可以抽象為某種規則。這時候,結合特定領域,將問題抽象為語法規則,從而給出在該領域下的一般性解決方案。在軟體構建中,如果某一特定領域的問題比較複雜,類似的結構不斷重複出現,如果使用普通的程式設計方式來實現將面臨非常頻繁的變化。這種情況下,將特定領域的問題表達為某種語法...