C++ 设计模式:解析器模式(Interpreter Pattern)

链接:C++ 设计模式

解析器模式(Interpreter Pattern)是一种行为设计模式,它定义了一种语言的文法表示,并定义一个解释器来解释该语言中的句子。解析器模式通常用于设计一个简单的语言或表达式求值系统。

1.问题分析

解析器模式主要解决的问题是:如何为一种语言定义一个文法,并且如何解释该语言中的句子。它适用于以下场景:

  • 需要解释一种语言的句子
  • 需要将一个复杂的表达式分解为更简单的子表达式,并逐个解释

2.实现步骤

  1. 定义文法规则:确定语言的文法规则,并将其表示为类。
  2. 创建抽象表达式类:定义一个抽象类,包含一个解释方法。
  3. 创建具体表达式类:为文法中的每个规则创建具体的表达式类,实现解释方法。
  4. 构建语法树:根据具体的表达式类构建语法树。
  5. 解释表达式:通过遍历语法树来解释表达式。

3.代码示例

3.1.创建抽象表达式类

cpp 复制代码
class Expression {
 public:
  virtual ~Expression() = default;
  virtual int interpret(const std::unordered_map<std::string, int>& context) = 0;
};

3.2.创建具体表达式类

变量表达式类

cpp 复制代码
class VariableExpression : public Expression {
 public:
  VariableExpression(const std::string& name) : name(name) {}
  int interpret(const std::unordered_map<std::string, int>& context) override { return context.at(name); }

 private:
  std::string name;
};

常量表达式类

cpp 复制代码
class ConstantExpression : public Expression {
 public:
  ConstantExpression(int value) : value(value) {}
  int interpret(const std::unordered_map<std::string, int>& context) override { return value; }

 private:
  int value;
};

加法表达式类

cpp 复制代码
class AddExpression : public Expression {
 public:
  AddExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right) : left(std::move(left)), right(std::move(right)) {}
  int interpret(const std::unordered_map<std::string, int>& context) override {
    return left->interpret(context) + right->interpret(context);
  }

 private:
  std::unique_ptr<Expression> left;
  std::unique_ptr<Expression> right;
};

减法表达式类

cpp 复制代码
class SubtractExpression : public Expression {
 public:
  SubtractExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
      : left(std::move(left)), right(std::move(right)) {}
  int interpret(const std::unordered_map<std::string, int>& context) override {
    return left->interpret(context) - right->interpret(context);
  }

 private:
  std::unique_ptr<Expression> left;
  std::unique_ptr<Expression> right;
};

3.3.构建解析器

cpp 复制代码
class Parser {
 public:
  static std::unique_ptr<Expression> parse(const std::string& expression) {
    std::istringstream iss(expression);
    return parseExpression(iss);
  }

 private:
  static std::unique_ptr<Expression> parseExpression(std::istringstream& iss) {
    auto left = parseTerm(iss);
    while (iss) {
      char op = iss.peek();
      if (op == '+' || op == '-') {
        iss.get();
        auto right = parseTerm(iss);
        if (op == '+') {
          left = std::make_unique<AddExpression>(std::move(left), std::move(right));
        } else {
          left = std::make_unique<SubtractExpression>(std::move(left), std::move(right));
        }
      } else {
        break;
      }
    }
    return left;
  }

  static std::unique_ptr<Expression> parseTerm(std::istringstream& iss) {
    if (std::isdigit(iss.peek())) {
      int value;
      iss >> value;
      return std::make_unique<ConstantExpression>(value);
    } else {
      std::string name;
      iss >> name;
      return std::make_unique<VariableExpression>(name);
    }
  }
};

3.4.解释表达式

cpp 复制代码
int main() {
  std::string expression = "x + 10 - y";

  // 解析表达式
  auto expr = Parser::parse(expression);

  // 上下文
  std::unordered_map<std::string, int> context = {{"x", 5}, {"y", 3}};

  // 解释表达式
  int result = expr->interpret(context);
  std::cout << "Result: " << result << std::endl;  // 输出结果应为 5 + 10 - 3 = 12

  return 0;
}
相关推荐
筏.k3 分钟前
C++ 设计模式系列:生产者-消费者模式完全指南
开发语言·c++·设计模式
LXS_3575 小时前
Day 05 C++ 入门 之 指针
开发语言·c++·笔记·学习方法·改行学it
挂科是不可能出现的6 小时前
最长连续序列
数据结构·c++·算法
mjhcsp7 小时前
C++ int 类型深度解析:从底层实现到实战应用
c++·int
程序员老舅9 小时前
C++参数传递:值、指针与引用的原理与实战
c++·c/c++·值传递·引用传递·指针传递·参数传递机制
liu****9 小时前
8.list的使用
数据结构·c++·算法·list
立志成为大牛的小牛9 小时前
数据结构——二十六、邻接表(王道408)
开发语言·数据结构·c++·学习·程序人生
草莓熊Lotso10 小时前
C++ 方向 Web 自动化测试入门指南:从概念到 Selenium 实战
前端·c++·python·selenium
CoderCodingNo11 小时前
【GESP】C++五级考试大纲知识点梳理, (5) 算法复杂度估算(多项式、对数)
开发语言·c++·算法
星河队长11 小时前
VS创建C++动态库和C#访问过程
java·c++·c#