5.3 INTERPRETER(解釋器)—類(lèi)行為型模式

1 意圖

給定一個(gè)語(yǔ)言,定義它的文法的一種表示瞬项,并定義一個(gè)解釋器蠕嫁,這個(gè)解釋器使用該表示來(lái)解釋語(yǔ)言中的句子地梨。

2 動(dòng)機(jī)

如果一種特定類(lèi)型的問(wèn)題發(fā)生的頻率足夠高帝璧,那么可能就值得將問(wèn)題的各個(gè)實(shí)例表述為一個(gè)簡(jiǎn)單語(yǔ)言中的句子。這樣就可以構(gòu)建一個(gè)解釋器湿刽,該解釋器通過(guò)解釋這些句子來(lái)解決該問(wèn)題。

例如褐耳,搜索匹配一個(gè)模式的字符串是一個(gè)常見(jiàn)的問(wèn)題诈闺。正則表達(dá)式是描述字符串模式的一種標(biāo)準(zhǔn)語(yǔ)言。與其為每一個(gè)的模式都構(gòu)造一個(gè)特定的算法铃芦,不如使用一種通用的搜索算法來(lái)解釋執(zhí)行一個(gè)正則表達(dá)式雅镊,該正則表達(dá)式定義了待匹配字符串的集合。

解釋器模式描述了如何為簡(jiǎn)單的語(yǔ)言定義一個(gè)文法刃滓,如何在該語(yǔ)言中表示一個(gè)句子仁烹,以及如何解釋這些句子。在上面的例子中咧虎,本設(shè)計(jì)模式描述了如何為正則表達(dá)式定義一個(gè)文法卓缰,如果表示一個(gè)特定的正則表達(dá)式,以及如何解釋這個(gè)正則表達(dá)式。
考慮以下文法定義正則表達(dá)式:


image.png

解釋器模式使用類(lèi)來(lái)表示每一條文法規(guī)則征唬,在規(guī)則右邊的符號(hào)是這些類(lèi)的實(shí)例變量捌显。上面的文法用5個(gè)類(lèi)表示,一個(gè)抽象類(lèi)RegularExpression和它的四個(gè)子類(lèi)LiteralExpression总寒、AlternationExpression扶歪、SequenceExpression和RepetitionExpression后三個(gè)類(lèi)定義的變量代表子表達(dá)式。


image.png

每個(gè)用這個(gè)文法定義的正則表達(dá)式都被表示為一個(gè)由這些類(lèi)的實(shí)例構(gòu)成的抽象語(yǔ)法樹(shù)摄闸。
例如, 抽象語(yǔ)法樹(shù):
image.png

表示正則表達(dá)式:
raining & (dogs | cats) *
如果我們?yōu)镽egularExpression的每一子類(lèi)都定義解釋 ( Interpret )操作善镰,那么就得到了為這些正則表達(dá)式的一個(gè)解釋器。解釋器將該表達(dá)式的上下文做為一個(gè)參數(shù)年枕。上下文包含輸入字符串和關(guān)于目前它已有多少已經(jīng)被匹配等信息炫欺。為匹配輸入字符串的下一部分,每一RegularExpression的子類(lèi)都在當(dāng)前上下文的基礎(chǔ)上實(shí)現(xiàn)解釋操作 (Interpret)画切。例如,

  • LiteralExpression將檢查輸入是否匹配它定義的字 ( literal );
  • AlternationExpression將檢查輸入是否匹配它的任意一個(gè)選擇項(xiàng);
  • RepetitionExpression將檢查輸入是否含有多個(gè)它所重復(fù)的表達(dá)式竣稽。
3 適用性

當(dāng)有一個(gè)語(yǔ)言需要解釋執(zhí)行 , 并且你可將該語(yǔ)言中的句子表示為一個(gè)抽象語(yǔ)法樹(shù)時(shí),可使
用解釋器模式霍弹。而當(dāng)存在以下情況時(shí)該模式效果最好:

  • 該文法簡(jiǎn)單對(duì)于復(fù)雜的文法 , 文法的類(lèi)層次變得龐大而無(wú)法管理毫别。此時(shí)語(yǔ)法分析程序生
    成器這樣的工具是更好的選擇。它們無(wú)需構(gòu)建抽象語(yǔ)法樹(shù)即可解釋表達(dá)式 , 這樣可以節(jié)
    省空間而且還可能節(jié)省時(shí)間典格。
  • 效率不是一個(gè)關(guān)鍵問(wèn)題最高效的解釋器通常不是通過(guò)直接解釋語(yǔ)法分析樹(shù)實(shí)現(xiàn)的 , 而是
    首先將它們轉(zhuǎn)換成另一種形式岛宦。例如,正則表達(dá)式通常被轉(zhuǎn)換成狀態(tài)機(jī)耍缴。但即使在這種
    情況下, 轉(zhuǎn)換器仍可用解釋器模式實(shí)現(xiàn), 該模式仍是有用的砾肺。
4 結(jié)構(gòu)
image.png
5 參與者
  • AbstractExpression(抽象表達(dá)式,如RegularExpression )
    ——聲明一個(gè)抽象的解釋操作防嗡,這個(gè)接口為抽象語(yǔ)法中所有的節(jié)點(diǎn)所共享变汪;
  • TerminalExpression(終結(jié)符表達(dá)式,如LiteralExpression)
    ——實(shí)現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作蚁趁;
    ——一個(gè)句子的每個(gè)終結(jié)符需要該類(lèi)的一個(gè)實(shí)例裙盾。
  • NonterminalExpression (非終結(jié)符表達(dá)式,如AlternationExpression,RepetitionExpression,SequenceExpressions)
    ——對(duì)文法中的每一條規(guī)則 R ::= R1R2. . . Rn都需要一個(gè)NonterminalExpression類(lèi)他嫡;
    ——為從R1到Rn的每個(gè)符號(hào)都維護(hù)一個(gè)AbstractExpression類(lèi)型的實(shí)例變量番官;
    ——為文法中的非終結(jié)符實(shí)現(xiàn)解釋 ( Interpret )操作。解釋( Interpret )一般要遞歸地調(diào)用表示R1到Rn的那些對(duì)象的解釋操作钢属。
6 協(xié)作
  • Client構(gòu)建(或被給定)一個(gè)句子徘熔,它是NonterminalExpression和TerminalExpression的實(shí)例裝配而成。
6 協(xié)作
  • 1 Client構(gòu)建(或被給定)一個(gè)句子淆党,它是由NonterminalExpression和TerminalExpression的實(shí)例裝配而成的一個(gè)抽象語(yǔ)法樹(shù)酷师,然后初始化上下文并調(diào)用解釋操作祟峦。
  • 2 每一非終結(jié)符表達(dá)式節(jié)點(diǎn)定義相應(yīng)表達(dá)式的解釋操作狸棍,而各終極符表達(dá)式的解釋操作構(gòu)成了遞歸的基礎(chǔ)桂敛。
  • 3 每一節(jié)點(diǎn)的解釋操作通過(guò)上下文來(lái)存儲(chǔ)和訪問(wèn)解釋器的狀態(tài)赡矢。
7 效果

解釋器模式有下列的優(yōu)點(diǎn)和不足:

  • 1 易于改變和擴(kuò)展文法 因?yàn)樵撃J绞褂妙?lèi)來(lái)表示文法規(guī)則 , 你可使用繼承來(lái)改變或擴(kuò)展該文法。已有的表達(dá)式可被增量式地改變 ,而新的表達(dá)式可定義為舊表達(dá)式的變體饱须。
  • 2 也易于實(shí)現(xiàn)文法 定義抽象語(yǔ)法樹(shù)中各個(gè)節(jié)點(diǎn)的類(lèi)的實(shí)現(xiàn)大體類(lèi)似域醇。這些類(lèi)易于直接編寫(xiě),通常它們也可以用一個(gè)編譯器或語(yǔ)法分析程序生成器自動(dòng)生成蓉媳。
  • 3 復(fù)雜的文法難以維護(hù) 解釋器模式為文法中的每一條規(guī)則至少定義了一個(gè)類(lèi)譬挚,因此包含許多規(guī)則的文法可能難以管理和維護(hù)±疑耄可應(yīng)用其它的設(shè)計(jì)模式來(lái)緩解這一問(wèn)題减宣。但當(dāng)文法非常復(fù)雜時(shí),其它技術(shù)如語(yǔ)法分析程序或編譯生成器更為合適玩荠。
  • 4 增加了新的解釋表達(dá)式的方式 解釋器模式使得實(shí)現(xiàn)新表達(dá)式“計(jì)算”變得容易漆腌。 例如,你可以在表達(dá)式類(lèi)上定義一個(gè)新的操作以支持優(yōu)美打印或表達(dá)式的類(lèi)型檢查。如果你經(jīng)常創(chuàng)建新的解釋表達(dá)式的方式, 那么可以考慮使用Visitor(5.11)模式以避免修改這些代表文法的類(lèi)阶冈。
8 實(shí)現(xiàn)

Interpreter和Composite(4 . 3)模式在實(shí)現(xiàn)上有許多相通的地方闷尿。下面是Interpreter所要考慮的一些特殊問(wèn)題:

  • 1 創(chuàng)建抽象語(yǔ)法樹(shù)解釋器模式并未解釋如何創(chuàng)建一個(gè)抽象的語(yǔ)法樹(shù)。換言之 , 它不涉及語(yǔ)法分析女坑。抽象語(yǔ)法樹(shù)可用一個(gè)表驅(qū)動(dòng)的語(yǔ)法分析程序來(lái)生成填具,也可用手寫(xiě)的 (通常為遞歸下降法) 語(yǔ)法分析程序創(chuàng)建,或直接由Client提供匆骗;
  • 2 定義解釋操作 并不一定要在表達(dá)式類(lèi)中定義解釋操作劳景。如果經(jīng)常要?jiǎng)?chuàng)建一種新的解釋器, 那么使用Visitor(5 . 11)模式將解釋放入一個(gè)獨(dú)立的 “訪問(wèn)者” 對(duì)象更好一些。例如,一個(gè)程序設(shè)計(jì)語(yǔ)言的會(huì)有許多在抽象語(yǔ)法樹(shù)上的操作碉就,比如類(lèi)型檢查盟广、優(yōu)化、代碼生成瓮钥,等等筋量。恰當(dāng)?shù)淖龇ㄊ鞘褂靡粋€(gè)訪問(wèn)者以避免在每一個(gè)類(lèi)上都定義這些操作。
  • 3 與Flyweight模式共享終結(jié)符 在一些文法中, 一個(gè)句子可能多次出現(xiàn)同一個(gè)終結(jié)符骏庸。此時(shí)最好共享那個(gè)符號(hào)的單個(gè)拷貝。計(jì)算機(jī)程序的文法是很好的例子 — 每個(gè)程序變量在整個(gè)代碼中將會(huì)出現(xiàn)多次年叮。在動(dòng)機(jī)一節(jié)的例子中 , 一個(gè)句子中終結(jié)符dog (由LiteralExpression類(lèi)描述)也可出現(xiàn)多次具被。終結(jié)節(jié)點(diǎn)通常不存儲(chǔ)關(guān)于它們?cè)诔橄笳Z(yǔ)法樹(shù)中位置的信息。在解釋過(guò)程中只损,任何它們所
    需要的上下文信息都由父節(jié)點(diǎn)傳遞給它們一姿。因此在共享的 (內(nèi)部的)狀態(tài)和傳入的(外部的)狀態(tài)區(qū)分得很明確, 這就用到了Flyweight(4 . 6)模式七咧。
9 代碼示例

github地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市叮叹,隨后出現(xiàn)的幾起案子艾栋,更是在濱河造成了極大的恐慌,老刑警劉巖蛉顽,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝗砾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡携冤,警方通過(guò)查閱死者的電腦和手機(jī)悼粮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)曾棕,“玉大人扣猫,你說(shuō)我怎么就攤上這事∏痰兀” “怎么了申尤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)衙耕。 經(jīng)常有香客問(wèn)我昧穿,道長(zhǎng),這世上最難降的妖魔是什么臭杰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任粤咪,我火速辦了婚禮,結(jié)果婚禮上渴杆,老公的妹妹穿的比我還像新娘寥枝。我一直安慰自己,他們只是感情好磁奖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布囊拜。 她就那樣靜靜地躺著,像睡著了一般比搭。 火紅的嫁衣襯著肌膚如雪冠跷。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天身诺,我揣著相機(jī)與錄音蜜托,去河邊找鬼。 笑死霉赡,一個(gè)胖子當(dāng)著我的面吹牛橄务,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播穴亏,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蜂挪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼重挑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起棠涮,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谬哀,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后严肪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體史煎,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年诬垂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劲室。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡结窘,死狀恐怖很洋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情隧枫,我是刑警寧澤喉磁,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站官脓,受9級(jí)特大地震影響协怒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卑笨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一孕暇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赤兴,春花似錦妖滔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至陨帆,卻和暖如春曲秉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疲牵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工承二, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纲爸。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓亥鸠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親缩焦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子读虏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件## 考慮這樣一個(gè)實(shí)際的應(yīng)用,維護(hù)系統(tǒng)自定義的配置文件袁滥。 幾乎每個(gè)實(shí)際的應(yīng)用系...
    七寸知架構(gòu)閱讀 3,088評(píng)論 2 56
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理盖桥,服務(wù)發(fā)現(xiàn),斷路器题翻,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 設(shè)計(jì)模式匯總 一揩徊、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,903評(píng)論 1 15
  • 轉(zhuǎn)載: 第一次知道原生家庭結(jié)構(gòu)圖嵌赠,是在我和許晉老師無(wú)意的聊天中說(shuō)起我們成員家庭關(guān)系的時(shí)候塑荒。當(dāng)時(shí)我提到了我和哥哥的關(guān)...
    夏蘇的花園閱讀 3,724評(píng)論 4 23
  • 9曾記否炊豪,朱自清凌箕? 曾記否,小朱词渤?小朱牵舱,全名朱自清,和著名散文家朱自清同名同姓而且同字缺虐,真是驚人的巧合芜壁。人稱朱自清...
    秭歸秀才9條命兒閱讀 534評(píng)論 0 2