国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

深入解析C++設(shè)計模式編程中解釋器模式的運(yùn)用

2020-01-26 14:40:27
字體:
供稿:網(wǎng)友

解釋器模式(interpreter),給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

解釋器模式需要解決的是,如果一種特定類型的問題發(fā)生的頻率足夠高,那么可能就值得將該問題的各個實例表述為一個簡單語言中的句子。這樣就可以構(gòu)建一個解釋器,該解釋器通過解釋這些句子來解決該問題。當(dāng)有一個語言需要解釋執(zhí)行,并且你可將該語言中的句子表示為一個抽象語法樹時,可使用解釋器模式。用了解釋器模式,就意味著可以很容易地改變和擴(kuò)展文法,因為該模式使用類來表示文法規(guī)則,你可使用繼承來改變或擴(kuò)展該文法。也比較容易實現(xiàn)文法,因為定義抽象語法樹中各個節(jié)點(diǎn)的類的實現(xiàn)大體類似,這些類都易于直接編寫。

結(jié)構(gòu)圖:

2016316110227128.jpg (450×242)

實例:

音樂解釋器

playContext.h

/************************************************************************  * description: 演奏內(nèi)容  * remark:    ************************************************************************/ #ifndef _PLAY_CONTEXT_H_ #define _PLAY_CONTEXT_H_ #include <string> #include <iostream> using namespace std; class playContext { public:   string getPlayText()   {     return m_strText;   }   void setPlayText(const string& strText)   {     m_strText = strText;   } private:   string m_strText; }; #endif// _PLAY_CONTEXT_H_ 

 

expression.h

/************************************************************************  * description: 表達(dá)式類  * remark:    ************************************************************************/ #ifndef _EXPRESSION_H_ #define _EXPRESSION_H_ #include "playContext.h" class expression { public:   // 解釋器   void interpret(playContext& PlayContext)   {     if (PlayContext.getPlayText().empty())     {       return;     }     else     {       string strPlayKey = PlayContext.getPlayText().substr(0, 1);       string strtemp = PlayContext.getPlayText().substr(2);       PlayContext.setPlayText(strtemp);              size_t nPos = PlayContext.getPlayText().find(" ");       string strPlayValue = PlayContext.getPlayText().substr(0, nPos);       int  nPlayValue = atoi(strPlayValue.c_str());       nPos = PlayContext.getPlayText().find(" ");       PlayContext.setPlayText(PlayContext.getPlayText().substr(nPos + 1));       excute(strPlayKey, nPlayValue);     }   }   // 執(zhí)行   virtual void excute(string& strKey, const int nValue) = 0; private: }; #endif// _EXPRESSION_H_  

 

note.h

/************************************************************************  * description: 音符類  * remark:    ************************************************************************/ #ifndef _NOTE_H_ #define _NOTE_H_ #include "expression.h" class note : public expression { public:   virtual void excute(string& strKey, const int nValue)   {     char szKey[2];     strncpy(szKey, strKey.c_str(), strKey.length());     string strNote;     switch (szKey[0])     {     case 'C':       strNote = "1";       break;     case 'D':       strNote = "2";       break;     case 'E':       strNote = "3";       break;     case 'F':       strNote = "4";       break;     case 'G':       strNote = "5";       break;     case 'A':       strNote = "6";       break;     case 'B':       strNote = "7";       break;     default:       strNote = "error";       break;     }     cout << strNote << " ";   } }; #endif// _NOTE_H_ 

 

scale.h

/************************************************************************  * description: 音階類  * remark:    ************************************************************************/ #ifndef _SCALE_H_ #define _SCALE_H_ #include "expression.h" class scale : public expression { public:   virtual void excute(string& strKey, const int nValue)   {     string strScale;     switch (nValue)     {     case 1:       strScale = "低音";       break;     case 2:       strScale = "中音";       break;     case 3:       strScale = "高音";       break;     default:       strScale = "error";       break;     }     cout << strScale << " ";   } private: }; #endif// _SCALE_H_ 


speed.h

#ifndef _SPEED_H_ #define _SPEED_H_ #include "expression.h" class speed : public expression { public:   virtual void excute(string& strKey, const int nValue)   {     string strSpeed;     if (nValue < 3)     {       strSpeed = "快速";     }     else if (nValue >= 6)     {       strSpeed = "慢速";     }     else     {       strSpeed = "中速";     }     cout << strSpeed << " ";   } }; #endif// _SPEED_H_  

客戶端: InterpreterApp.cpp

// InterpreterApp.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。 // #include "stdafx.h" #include "note.h" #include "scale.h" #include "speed.h" #include "playContext.h" int _tmain(int argc, _TCHAR* argv[]) {   playContext context;   cout << "Music:";      context.setPlayText("T 2 O 2 E 3 G 5 G 5 ");   expression* expressObj = NULL;      while (!context.getPlayText().empty())   {     string strSep = context.getPlayText().substr(0, 1);     char szKey[2];     strncpy(szKey, strSep.c_str(), strSep.length());     switch (szKey[0])     {     case 'O':       expressObj = new scale();       break;     case 'T':       expressObj = new speed();       break;     case 'C':     case 'D':     case 'E':     case 'F':     case 'G':     case 'A':     case 'B':     case 'P':       expressObj = new note();       break;     default:       break;     }     if (NULL != expressObj)     {       expressObj->interpret(context);     }   }   system("pause");   return 0; } 

不足之處
解釋器模式不足的是,解釋器模式為文法中的每一條規(guī)則至少定義了一個類,因此包含許多規(guī)則的文法可能難以管理和維護(hù)。建議當(dāng)文法非常復(fù)雜時,使用其他的技術(shù)如語法分析程序或編譯器生成器來處理。

適用場景

  • 當(dāng)有一個語言需要解釋執(zhí)行, 并且你可將該語言中的句子表示為一個抽象語法樹時,可使用解釋器模式。而當(dāng)存在以下情況時該模式效果最好:
  • 該文法簡單對于復(fù)雜的文法, 文法的類層次變得龐大而無法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構(gòu)建抽象語法樹即可解釋表達(dá)式, 這樣可以節(jié)省空間而且還可能節(jié)省時間。
  • 效率不是一個關(guān)鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實現(xiàn)的, 而是首先將它們轉(zhuǎn)換成另一種形式。例如,正則表達(dá)式通常被轉(zhuǎn)換成狀態(tài)機(jī)。但即使在這種情況下, 轉(zhuǎn)換器仍可用解釋器模式實現(xiàn), 該模式仍是有用的。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 天津市| 神农架林区| 六枝特区| 岚皋县| 恭城| 岗巴县| 尚志市| 周宁县| 惠州市| 黄龙县| 五寨县| 松原市| 页游| 弥渡县| 天全县| 鹤壁市| 新昌县| 岳西县| 馆陶县| 海南省| 修武县| 富平县| 曲阳县| 江安县| 梨树县| 叙永县| 平乡县| 西丰县| 登封市| 德昌县| 重庆市| 阳原县| 酒泉市| 兴化市| 甘泉县| 昭平县| 绩溪县| 兴隆县| 红安县| 穆棱市| 拉萨市|