C++二十三种设计模式之表明器模式

打印 上一主题 下一主题

主题 1022|帖子 1022|积分 3066

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、组成

抽象表达式类:声明表明接口。
终结符表达式类:实现表明接口,代表语言中的终结符(数字、变量)。
抽象非终结符表达式类:实现非终结符获取左表达式和获取右表达式接口。
具体非终结符表达式类:实现非终结符的表明接口,代表语言中的非终结符。
解析函数:使用表达式类解析表达式字符串。
二、特点

1、解析函数充当表达式类的使用者身份。
2、解析函数使用表达式栈来存储逐步解析的表达式。
3、表明器模式逐步解析得到的是一个个表达式。
三、目的

提供表明器,根据语言的语法规则,将表达式表示为一个抽象的语法树来解析。
四、缺点

1、性能问题,复杂语句包罗大量的循环和递归时会影响系统的性能。
2、类膨胀问题,语言文法规则复杂时,需要大量的表达式类,会导致类急剧膨胀。
五、示例代码

  1. #include<iostream>
  2. #include <vector>
  3. #include <list>
  4. #include <string>
  5. #include <mutex>
  6. #include <map>
  7. #include<stack>
  8. using namespace std;
  9. class Expression;//抽象表达式类
  10. class VarExpression;//终结符表达式类
  11. class SymbolExpression;//抽象非终结符表达式类
  12. class AddExpression;//具体非终结符表达式类
  13. class SubExpression;//具体非终结符表达式类
  14. Expression* analyse(string strExp);//解析函数
  15. class Expression {
  16. public:
  17.         Expression(int num, char sign) : m_num_dbg(num), m_sign_dbg(sign) {}
  18.         virtual int interpret(map <char, int> var) = 0;
  19.         virtual ~Expression() {};
  20.         int m_num_dbg;
  21.         char m_sign_dbg;
  22. };
  23. class VarExpression : public Expression {
  24. public:
  25.         VarExpression(const char& key, int num, char sign) : Expression(num, sign), m_key(key) {}
  26.         int interpret(map <char, int> var) {
  27.                 return var[m_key];
  28.         };
  29.         ~VarExpression() {
  30.                 cout << "delete VarExpression num:" << m_num_dbg << " sign:" << m_sign_dbg << endl;
  31.         };
  32. private:
  33.         char m_key;
  34. };
  35. class SymbolExpression : public Expression {
  36. public:
  37.         SymbolExpression(Expression* left, Expression* right, int num, char sign) : Expression(num, sign), m_left(left), m_right(right) {}
  38.         Expression* GetLeft() {
  39.                 return m_left;
  40.         };
  41.         Expression* GetRight() {
  42.                 return m_right;
  43.         };
  44.         ~SymbolExpression() {
  45.                 delete m_left;
  46.                 delete m_right;
  47.                 cout << "delete SymbolExpression num:" << m_num_dbg << " sign:" << m_sign_dbg << endl;
  48.         }
  49. protected:
  50.         Expression* m_left;
  51.         Expression* m_right;
  52. };
  53. class AddExpression : public SymbolExpression {
  54. public:
  55.         AddExpression(Expression* left, Expression* right, int num, char sign) : SymbolExpression(left, right, num, sign) {}
  56.         int interpret(map <char, int> var) {
  57.                 int value1 = m_left->interpret(var);
  58.                 int value2 = m_right->interpret(var);
  59.                 int result = value1 + value2;
  60.                 return result;
  61.         };
  62.         ~AddExpression() {};
  63. };
  64. class SubExpression : public SymbolExpression {
  65. public:
  66.         SubExpression(Expression* left, Expression* right, int num, char sign) : SymbolExpression(left, right, num, sign) {}
  67.         int interpret(map <char, int> var) {
  68.                 int value1 = m_left->interpret(var);
  69.                 int value2 = m_right->interpret(var);
  70.                 int result = value1 - value2;
  71.                 return result;
  72.         };
  73. };
  74. Expression* analyse(string strExp) {
  75.         stack<Expression*> expStack;
  76.         Expression* left;
  77.         Expression* right;
  78.         int iCount = 0;
  79.         for (size_t i = 0; i < strExp.size(); i++) {
  80.                 switch (strExp[i]) {
  81.                 case '+':
  82.                         left = expStack.top();
  83.                         ++i;
  84.                         right = new VarExpression(strExp[i], iCount++, 'v');
  85.                         expStack.push(new AddExpression(left, right, iCount++, '+'));
  86.                         break;
  87.                 case '-':
  88.                         left = expStack.top();
  89.                         ++i;
  90.                         right = new VarExpression(strExp[i], iCount++, 'v');
  91.                         expStack.push(new SubExpression(left, right, iCount++, '-'));
  92.                         break;
  93.                 default:
  94.                         expStack.push(new VarExpression(strExp[i], iCount++, 'v'));
  95.                         break;
  96.                 }
  97.         }
  98.         return expStack.top();
  99. }
  100. int main() {
  101.         string expStr = "a+b-c";
  102.         map<char, int> var;
  103.         var.insert({ 'a',1 });
  104.         var.insert({ 'b',3 });
  105.         var.insert({ 'c',2 });
  106.         unique_ptr<Expression> exp(analyse(expStr));
  107.         int result = (exp)->interpret(var);
  108.         for (auto iter = var.begin(); iter != var.end(); iter++) {
  109.                 cout << iter->first << ":" << iter->second << endl;
  110.         }
  111.         cout << expStr << "=" << result << endl;
  112. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表