最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2016年03月16日 11:05:04   作者:dai_jing  
這篇文章主要介紹了C++設(shè)計(jì)模式編程中解釋器模式的運(yùn)用,解釋器模式給定一個(gè)語(yǔ)言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來(lái)解釋語(yǔ)言中的句子,需要的朋友可以參考下

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

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

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

2016316110227128.jpg (450×242)

實(shí)例:

音樂(lè)解釋器

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 : 定義控制臺(tái)應(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ù)如語(yǔ)法分析程序或編譯器生成器來(lái)處理。

適用場(chǎng)景

  • 當(dāng)有一個(gè)語(yǔ)言需要解釋執(zhí)行, 并且你可將該語(yǔ)言中的句子表示為一個(gè)抽象語(yǔ)法樹(shù)時(shí),可使用解釋器模式。而當(dāng)存在以下情況時(shí)該模式效果最好:
  • 該文法簡(jiǎn)單對(duì)于復(fù)雜的文法, 文法的類層次變得龐大而無(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), 該模式仍是有用的。

相關(guān)文章

  • QT+Quick實(shí)現(xiàn)自定義組件的示例詳解

    QT+Quick實(shí)現(xiàn)自定義組件的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用QT+Quick實(shí)現(xiàn)自定義組件(按鈕、下拉菜單等),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-11-11
  • QT實(shí)現(xiàn)讀寫(xiě)ini文件的示例代碼

    QT實(shí)現(xiàn)讀寫(xiě)ini文件的示例代碼

    .ini文件是Initialization?File的縮寫(xiě),即初始化文件,本文主要給大家介紹了關(guān)于Qt讀寫(xiě)ini文件的相關(guān)方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • C語(yǔ)言中l(wèi)seek()函數(shù)和fseek()函數(shù)的使用詳解

    C語(yǔ)言中l(wèi)seek()函數(shù)和fseek()函數(shù)的使用詳解

    這篇文章主要介紹了C語(yǔ)言中l(wèi)seek()函數(shù)和fseek()函數(shù)的使用詳解,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例

    C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例

    今天小編就為大家分享一篇關(guān)于C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • C++ Eigen庫(kù)實(shí)現(xiàn)最小二乘擬合的示例代碼

    C++ Eigen庫(kù)實(shí)現(xiàn)最小二乘擬合的示例代碼

    Eigen 是一個(gè)線性算術(shù)的 C++ 模板庫(kù),功能強(qiáng)大、快速、優(yōu)雅以及支持多平臺(tái),本文主要為大家介紹了C++利用Eigen庫(kù)實(shí)現(xiàn)最小二乘擬合的示例代碼,希望對(duì)大家有所幫助
    2023-07-07
  • 線程按指定順序輸出字符到數(shù)組的實(shí)例代碼

    線程按指定順序輸出字符到數(shù)組的實(shí)例代碼

    這篇文章主要介紹了線程按指定順序輸出字符到數(shù)組的實(shí)例代碼,需要的朋友可以參考下
    2014-02-02
  • C++ Boost shared_ptr共享指針詳細(xì)講解

    C++ Boost shared_ptr共享指針詳細(xì)講解

    shared_ptr是一個(gè)標(biāo)準(zhǔn)的共享所有權(quán)的智能指針,允許多個(gè)指針指向同一個(gè)對(duì)象,定義在memory文件中,命名空間為std,這篇文章主要介紹了C++ shared_ptr使用,需要的朋友可以參考下
    2022-11-11
  • 詳解Matlab如何繪制圓角半透明圖例

    詳解Matlab如何繪制圓角半透明圖例

    目前MATLAB的legend圖例是不支持圓角和半透明的,所以本文將自制實(shí)現(xiàn)圓角半透明圖例。文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-05-05
  • 二叉搜索樹(shù)的插入與刪除(詳細(xì)解析)

    二叉搜索樹(shù)的插入與刪除(詳細(xì)解析)

    添加結(jié)點(diǎn)其實(shí)很容易,我們只需要找到結(jié)點(diǎn)所行對(duì)應(yīng)的位置就可以了,而且沒(méi)有要求是平衡的二叉搜索樹(shù),因此每次添加結(jié)點(diǎn)都是在葉子結(jié)點(diǎn)上操作,不需要修改二叉搜索樹(shù)整體的結(jié)構(gòu)
    2013-09-09
  • C++ typeid 和虛函數(shù)詳解

    C++ typeid 和虛函數(shù)詳解

    這篇文章主要介紹了c++ typeid 和虛函數(shù)的使用,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下,希望能夠給你帶來(lái)幫助
    2021-09-09

最新評(píng)論

临清市| 搜索| 莱州市| 子长县| 绥德县| 施甸县| 大兴区| 岑溪市| 龙泉市| 隆林| 唐海县| 榆中县| 无棣县| 延安市| 从化市| 桦甸市| 靖西县| 海盐县| 广饶县| 都兰县| 沁源县| 漠河县| 遂溪县| 榆中县| 宾川县| 定结县| 台北市| 卓尼县| 岐山县| 大渡口区| 彝良县| 咸丰县| 南川市| 博罗县| 济源市| 红河县| 平邑县| 东安县| 徐水县| 西充县| 通榆县|