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

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

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

2020-05-23 14:06:36
字體:
供稿:網(wǎng)友
這篇文章主要介紹了C++設(shè)計(jì)模式編程中解釋器模式的運(yùn)用,解釋器模式給定一個(gè)語言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子,需要的朋友可以參考下
 

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

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

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

C++,設(shè)計(jì)模式編程,解釋器模式

 

實(shí)例:

音樂解釋器

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ī)則至少定義了一個(gè)類,因此包含許多規(guī)則的文法可能難以管理和維護(hù)。建議當(dāng)文法非常復(fù)雜時(shí),使用其他的技術(shù)如語法分析程序或編譯器生成器來處理。

適用場景

  • 當(dāng)有一個(gè)語言需要解釋執(zhí)行, 并且你可將該語言中的句子表示為一個(gè)抽象語法樹時(shí),可使用解釋器模式。而當(dāng)存在以下情況時(shí)該模式效果最好:
  • 該文法簡單對于復(fù)雜的文法, 文法的類層次變得龐大而無法管理。此時(shí)語法分析程序生成器這樣的工具是更好的選擇。它們無需構(gòu)建抽象語法樹即可解釋表達(dá)式, 這樣可以節(jié)省空間而且還可能節(jié)省時(shí)間。
  • 效率不是一個(gè)關(guān)鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實(shí)現(xiàn)的, 而是首先將它們轉(zhuǎn)換成另一種形式。例如,正則表達(dá)式通常被轉(zhuǎn)換成狀態(tài)機(jī)。但即使在這種情況下, 轉(zhuǎn)換器仍可用解釋器模式實(shí)現(xiàn), 該模式仍是有用的。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鸡西市| 清涧县| 清丰县| 理塘县| 高尔夫| 巩留县| 桐梓县| 霍城县| 娄烦县| 潼南县| 临安市| 罗江县| 饶阳县| 城固县| 浪卡子县| 奉化市| 鄢陵县| 家居| 大宁县| 霸州市| 南岸区| 连平县| 舞阳县| 炉霍县| 三台县| 玛纳斯县| 壤塘县| 湟源县| 江阴市| 米林县| 陵川县| 胶南市| 合阳县| 教育| 谢通门县| 福清市| 安西县| 广宁县| 鄂托克前旗| 安达市| 凌源市|