• 设计模式-解析器-笔记


    “领域规则”模式

    在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将稳日抽象为语法规则,从而给出在该领域下的一般性解决方案。

    典型模式:Interpreter

    动机(Motivation)

    在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式实现将面临非常频繁的变化。

    在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

    模式定义:

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

    示例:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class Expression {
    6. public:
    7. virtual int interpreter(map<char, int>& var) = 0;
    8. virtual ~Expression() {}
    9. };
    10. //变量表达式
    11. class VarExpression : public Expression {
    12. char key;
    13. public:
    14. VarExpression(const char& key) {
    15. this->key = key;
    16. }
    17. int interpreter(map<char, int>& var) {
    18. return var[key];
    19. }
    20. };
    21. //符号表达式
    22. class SymbolExpression : public Expression {
    23. //运算符左右两个参数
    24. protected:
    25. Expression* left;
    26. Expression* right;
    27. public:
    28. SymbolExpression(Expression* left, Expression* right) {
    29. this->left = left;
    30. this->right = right;
    31. }
    32. };
    33. //加法运行
    34. class AddExpression : public SymbolExpression {
    35. public:
    36. AddExpression(Expression* left, Expression* right)
    37. : SymbolExpression(left, right)
    38. {}
    39. int interpreter(map<char, int>& var) {
    40. return left->interpreter(var)
    41. + right->interpreter(var);
    42. }
    43. };
    44. //减法运行
    45. class SubExpression : public SymbolExpression {
    46. public:
    47. SubExpression(Expression* left, Expression* right)
    48. : SymbolExpression(left, right)
    49. {}
    50. int interpreter(map<char, int>& var) {
    51. return left->interpreter(var)
    52. - right->interpreter(var);
    53. }
    54. };
    55. Expression* analyse(string expStr) {
    56. stack expStack;
    57. Expression* left;
    58. Expression* right;
    59. for (int i = 0; i < expStr.size(); ++i)
    60. {
    61. switch (expStr[i])
    62. {
    63. case '+':
    64. //加法运算
    65. left = expStack.top();
    66. right = new VarExpression(expStr[++i]);
    67. expStack.push(new AddExpression(left, right));
    68. break;
    69. case '-':
    70. //减法运算
    71. left = expStack.top();
    72. right = new VarExpression(expStr[++i]);
    73. expStack.push(new SubExpression(left, right));
    74. break;
    75. default:
    76. expStack.push(new VarExpression(expStr[i]));
    77. break;
    78. }
    79. }
    80. return expStack.top();
    81. }
    82. void release(Expression* expression) {
    83. // 释放表达式树的节点内存
    84. }
    85. int main() {
    86. string expStr = "a+b-c+d";
    87. map<char, int> var;
    88. var.insert(make_pair('a', 5));
    89. var.insert(make_pair('b', 2));
    90. var.insert(make_pair('c', 1));
    91. var.insert(make_pair('d', 6));
    92. Expression* expression = analyse(expStr);
    93. int result = expression->interpreter(var);
    94. cout << result << endl;
    95. release(expression);
    96. return 0;
    97. }

    要点总结:

    Interpreter模式的应用场合式Interpreter模式的应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。

    使用Interpreter模式来表达文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。

    Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

  • 相关阅读:
    CCNA-NAT协议 静态NAT 动态NAT(多对多) PAT(多对一) 内网与外网之间的通信 GNS3实验验证
    JSON decoding error: Invalid UTF-8 start byte 0xb6
    栩栩如生,音色克隆,Bert-vits2文字转语音打造鬼畜视频实践(Python3.10)
    大公司为什么禁止SpringBoot项目使用Tomcat?
    ADAS/AD笔记之特斯拉Autopilot-HW3.0系统
    Linux中ROS话题通信中发布者基本操作(C++实现)
    SourceTree提示128错误
    【CV】第 3 章:使用 OpenCV 和 CNN 进行面部检测
    假期学生休闲用什么蓝牙耳机?高配置蓝牙耳机推荐
    【PYG】简单分析Planetoid()中存储Cora数据集边的数量
  • 原文地址:https://blog.csdn.net/zhaodongdong2012/article/details/134542582