• 解释器模式 行为型模式之五


    1.定义

            给定一个语言,定义它的文法的一种表示,并定义一个解释器。比如加减乘除在代码里是一种表示,我们需要翻译成可以阅读的数学公式,并且可以供用户输入数字得到输出结果。

    2.组成结构

    1. 抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
    2. 终结符表达式(Terminal Expression):是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
    3. 非终结符表达式(Nonterminal Expression):也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
    4. 上下文(Context):通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。

    我们将用示例代码来解释各个组成部分的意义。

    3.示例代码

    1. #include
    2. #include
    3. using namespace std;
    4. #define DELETE(pointer) delete pointer; pointer=nullptr
    5. const string key1 = string("s1");
    6. const string key2 = string("s2");
    7. const string key3 = string("s3");
    8. const string key4 = string("s4");
    9. class Context
    10. {
    11. public:
    12. Context() {
    13. datas[key1] = 1;
    14. datas[key2] = 2;
    15. datas[key3] = 3;
    16. datas[key4] = 4;
    17. }
    18. int getValue(string key) {
    19. if (!datas.count(key))
    20. {
    21. return 0;
    22. }
    23. return datas[key];
    24. }
    25. private:
    26. std::mapint> datas;
    27. };
    28. class Expression
    29. {
    30. public:
    31. Expression(Expression* left, Expression* right) :left(left), right(right) { }
    32. virtual ~Expression() {
    33. if (left != nullptr)
    34. {
    35. DELETE(left);
    36. }
    37. if (right != nullptr)
    38. {
    39. DELETE(right);
    40. }
    41. }
    42. virtual int interpreter(Context* context) = 0;
    43. protected:
    44. Expression* left;
    45. Expression* right;
    46. };
    47. class MultiExpression : public Expression
    48. {
    49. public:
    50. MultiExpression(Expression* left, Expression* right) : Expression(left, right) { }
    51. int interpreter(Context* context) override {
    52. if ((left == nullptr) || (right == nullptr))
    53. {
    54. return 0;
    55. }
    56. return left->interpreter(context) * right->interpreter(context);
    57. }
    58. };
    59. class DivisionExpression : public Expression
    60. {
    61. public:
    62. DivisionExpression(Expression* left, Expression* right) : Expression(left, right) { }
    63. int interpreter(Context* context) override {
    64. if ((left == nullptr) || (right == nullptr))
    65. {
    66. return 0;
    67. }
    68. return left->interpreter(context) / right->interpreter(context);
    69. }
    70. };
    71. class TerminalExpression : public Expression
    72. {
    73. public:
    74. TerminalExpression(int value) : value(value), Expression(nullptr, nullptr) { }
    75. int interpreter(Context* context) {
    76. return value;
    77. }
    78. private:
    79. int value;
    80. };
    81. void doInterpreter() // 客户端client
    82. {
    83. /* 3*4/2==6 对应语法树如下:
    84. / (除法)
    85. / \
    86. * 2
    87. / \
    88. 3 4
    89. */
    90. Context context;
    91. MultiExpression* multiExpression = new MultiExpression(new TerminalExpression(context.getValue(key3))
    92. , new TerminalExpression(context.getValue(key4))); // 终止节点作为叶子结点,非终止节点作为非叶子节点
    93. int mutil = multiExpression->interpreter(&context);
    94. cout << "mutil==" << mutil << endl;
    95. DivisionExpression* divisionExpression = new DivisionExpression(multiExpression
    96. , new TerminalExpression(context.getValue(key2))); // 乘法表达式作为左子树 / 右子树
    97. int division = divisionExpression->interpreter(&context); // 运行解释器
    98. cout << "division==" << division << endl;
    99. DELETE(divisionExpression);
    100. // 这里注意,不能第二次释放divisionExpression,因为此时它是divisionExpression的左子树
    101. //,divisionExpression释放的时候会自动释放左右子树,也就是递归释放,最终只需要释放最后一次嵌套调用的就行
    102. }
    103. int main()
    104. {
    105. doInterpreter();
    106. system("pause");
    107. return 1;
    108. }

    引用

    C++设计模式——解释器模式(interpreter pattern)_c++interpreter模式-CSDN博客

     

     

  • 相关阅读:
    渗透测试信息收集方法笔记
    【TypeScript】使用CRA创建支持TS的React项目(从踩坑到放弃)
    事件处理、事件修饰符(详细)
    【AHK】任务栏调节音量/边缘滚动调节/边缘触发
    【kafka】十四、kafka生产者API
    重生奇迹mu游戏有哪些职业?
    展讯多语言支持列表
    有没有免费的云渲染平台?哪家云渲染平台收费更合理?
    【微机原理及接口技术】中断系统
    沉睡者:你会的套路我都会,只是我不对你用而已。
  • 原文地址:https://blog.csdn.net/Physics_ITBoy/article/details/133632561