程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 深刻解析C++設計形式編程中說明器形式的應用

深刻解析C++設計形式編程中說明器形式的應用

編輯:關於C++

深刻解析C++設計形式編程中說明器形式的應用。本站提示廣大學習愛好者:(深刻解析C++設計形式編程中說明器形式的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析C++設計形式編程中說明器形式的應用正文


說明器形式(interpreter),給定一個說話,界說它的文法的一種表現,並界說一個說明器,這個說明器應用該表現來說明說話中的句子。

說明器形式須要處理的是,假如一種特定類型的成績產生的頻率足夠高,那末能夠就值得將該成績的各個實例表述為一個簡略說話中的句子。如許便可以構建一個說明器,該說明器經由過程說明這些句子來處理該成績。當有一個說話須要說明履行,而且你可將該說話中的句子表現為一個籠統語法樹時,可以使用說明器形式。用懂得釋器形式,就意味著可以很輕易地轉變和擴大文法,由於該形式應用類來表現文律例則,你可以使用繼續來轉變或擴大該文法。也比擬輕易完成文法,由於界說籠統語法樹中各個節點的類的完成年夜體相似,這些類都易於直接編寫。

構造圖:

實例:

音樂說明器

playContext.h

/************************************************************************ 
 * description: 吹奏內容 
 * 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: 表達式類 
 * 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); 
    } 
  } 
  // 履行 
  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 : 界說掌握台運用法式的進口點。 
// 
#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; 
} 

缺乏的地方
說明器形式缺乏的是,說明器形式為文法中的每條規矩至多界說了一個類,是以包括很多規矩的文法能夠難以治理和保護。建議當文法異常龐雜時,應用其他的技巧如語法剖析法式或編譯器生成器來處置。

實用場景

  • 當有一個說話須要說明履行, 而且你可將該說話中的句子表現為一個籠統語法樹時,可以使用說明器形式。而當存在以下情形時該形式後果最好:
  • 該文法簡略關於龐雜的文法, 文法的類條理變得宏大而沒法治理。此時語法剖析法式生成器如許的對象是更好的選擇。它們無需構建籠統語法樹便可說明表達式, 如許可以節儉空間並且還能夠節儉時光。
  • 效力不是一個症結成績最高效的說明器平日不是經由過程直接說明語法剖析樹完成的, 而是起首將它們轉換成另外一種情勢。例如,正則表達式平日被轉換成狀況機。但即便在這類情形下, 轉換器仍可用說明器形式完成, 該形式還是有效的。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved