023 --- 第27章 解释器模式

简述:

  解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

  解释器模式包括:上下文类、抽象表达式类、终结符表达式类、非终结符表达式类。

    上下文类:包含解释器之外的一些全局信息。

    抽象表达式类:声明一个抽象的解释操作,这个接口作为抽象语法树中所有的节点共享。

    终结符表达式类:继承自抽象表达式类,实现与文法中的终结符相关联的解释操作。

    非终结符表达式类:继承自抽象表达式类,为文法中的非终结符实现解释操作,对文法中每一条规则R1、R2……RN都需要一个具体的非终结符表达式类。

解释器模式:

 1 #include <iostream>
 2 #include <list>
 3 using namespace std;
 4 
 5 // 上下文类
 6 class CContext
 7 {
 8 private:
 9     string m_szInput;
10     string m_szOutPut;
11 
12 public:
13     void SetInput(string szInput) { m_szInput = szInput; }
14 
15     string GetInput() { return m_szInput; }
16 
17     void SetOutPut(string szOutPut) { m_szOutPut = szOutPut; }
18 
19     string GetOutPut() { return m_szOutPut; }
20 
21 };
22 
23 // 抽象表达式类
24 class CAbstractExpression
25 {
26 public:
27     virtual void Interpret(CContext* pContext) = 0;
28 };
29 
30 // 终结符表达式类
31 class CTerminalExpression : public CAbstractExpression
32 {
33 public:
34     virtual void Interpret(CContext* pContext) { cout << "终端解释器" << endl; }
35 };
36 
37 // 非终结符表达式类
38 class CNonterminalExpression : public CAbstractExpression
39 {
40 public:
41     virtual void Interpret(CContext* pContext) { cout << "非终端解释器" << endl; }
42 };
43 
44 int main()
45 {
46     CContext Context;
47     list<CAbstractExpression*> list;
48     CTerminalExpression TerminalExpression1;
49     list.push_back(&TerminalExpression1);
50     CNonterminalExpression NonterminalExpression;
51     list.push_back(&NonterminalExpression);
52     CTerminalExpression TerminalExpression2;
53     list.push_back(&TerminalExpression2);
54     CTerminalExpression TerminalExpression3;
55     list.push_back(&TerminalExpression3);
56 
57     for (auto Expression : list)
58         Expression->Interpret(&Context);
59 
60     system("pause");
61     return 0;
62 }

输出结果:

例:音乐解释器

代码如下:

  1 #include <iostream>
  2 #include <list>
  3 using namespace std;
  4 
  5 // 演奏内容(上下文类)
  6 class CPlayContext
  7 {
  8 private:
  9     string m_szText; // 演奏文本
 10 
 11 public:
 12     void SetText(string szText) { m_szText = szText; }
 13 
 14     string GetText()
 15     { return m_szText; }
 16 };
 17 
 18 // 抽象表达式类
 19 class CExpression
 20 {
 21 public:
 22     // 解释器
 23     void Interpret(CPlayContext* pContext)
 24     {
 25         if (pContext->GetText().length() == 0)
 26             return;
 27         else
 28         {
 29             string szPlayKey = pContext->GetText().substr(0, 1);
 30             char cKey = szPlayKey[0];
 31             pContext->SetText(pContext->GetText().substr(2));
 32             double fPlayValue = atof(pContext->GetText().substr(0, pContext->GetText().find_first_of(' ')).c_str());
 33             pContext->SetText(pContext->GetText().substr(pContext->GetText().find_first_of(' ') + 1));
 34         
 35             Excute(cKey, fPlayValue);
 36         }
 37     }
 38 
 39     // 执行
 40     virtual void Excute(char szKey, double fValue) = 0;
 41 };
 42 
 43 // 音符类(终结符表达式类)
 44 class CNote : public CExpression
 45 {
 46     void Excute(char cKey, double fValue)
 47     {
 48         int nNote = 0;
 49 
 50         switch (cKey)
 51         {
 52         case 'C':
 53             nNote = 1;
 54             break;
 55         case 'D':
 56             nNote = 2;
 57             break;
 58         case 'E':
 59             nNote = 3;
 60             break;
 61         case 'F':
 62             nNote = 4;
 63             break;
 64         case 'G':
 65             nNote = 5;
 66             break;
 67         case 'A':
 68             nNote = 6;
 69             break;
 70         case 'B':
 71             nNote = 7;
 72             break;
 73         }
 74         cout << nNote << " ";
 75     }
 76 };
 77 
 78 // 音阶类(终结符表达式类)
 79 class CScale : public CExpression
 80 {
 81 public:
 82     void Excute(char cKey, double fValue)
 83     {
 84         string m_szScale;
 85 
 86         switch ((int)fValue)
 87         {
 88         case 1:
 89             m_szScale = "低音";
 90             break;
 91         case 2:
 92             m_szScale = "中音";
 93             break;
 94         case 3:
 95             m_szScale = "高音";
 96             break;
 97         }
 98         cout << m_szScale << " ";
 99     }
100 };
101 
102 // 音速类(终结符表达式类)
103 class CSpeed : public CExpression
104 {
105 public:
106     void Excute(char cKey, double fValue)
107     {
108         string m_szSpeed;
109 
110         if (fValue < 500)
111             m_szSpeed = "快速";
112         else if(fValue >= 1000)
113             m_szSpeed = "慢速";
114         else
115             m_szSpeed = "中速";
116 
117         cout << m_szSpeed << " ";
118     }
119 };
120 
121 // 缺少非终结符表达式的子类,如果做到不改动客户端,C#可以用简单工厂加反射,C++可以用动态创建对象等技术,之前有写,这里就没有重复写
122 
123 int main()
124 {
125     CPlayContext Context;
126     CScale Scale;
127     CNote Note;
128     CSpeed Speed;
129     // 音乐-上海滩
130     cout << "上海滩:" << endl;
131     Context.SetText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3");
132 
133     CExpression* pExpression = NULL;
134     try
135     {
136         while (Context.GetText().length() > 0)
137         {
138             char c = Context.GetText().substr(0, 1)[0];
139             switch (c)
140             {
141             case 'O':
142                 pExpression = &Scale;
143                 break;
144             case 'T':
145                 pExpression = &Speed;
146                 break;
147             case 'C':
148             case 'D':
149             case 'E':
150             case 'G':
151             case 'A':
152             case 'B':
153             case 'P':
154                 pExpression = &Note;
155                 break;
156             default:
157                 cout << endl << "播放完成" << endl;
158                 system("pause");
159                 return 0;
160             }
161             pExpression->Interpret(&Context);
162         }
163     }
164     catch (exception ex)
165     {
166         cout << ex.what() << endl; // 第19次取出长度错误,所以报错
167     }
168 
169     system("pause");
170     return 0;
171 }

输出结果:

原文地址:https://www.cnblogs.com/SmallAndGreat/p/13650267.html