当前位置: 首页 > article >正文

C++实现设计模式---解释器模式 (Interpreter Pattern)

解释器模式 (Interpreter Pattern)

解释器模式 是一种行为型设计模式,它提供了一个语言的语法表示,并定义了一个解释器来处理这个语言的语法。通过解释器模式,可以实现对特定语法或表达式的解析和执行。


意图

  • 定义一种语言的文法,并提供一个解释器来处理语言中的语句。
  • 通过解析和解释特定语言的表达式,实现灵活的扩展和动态计算。

使用场景

  1. 需要解析特定语法或表达式
    • 如计算器的表达式求值。
  2. 语言规则相对简单,且可扩展
    • 规则可以使用组合模式表达。
  3. 需要对用户输入的语句进行解析并执行
    • 如脚本语言解析器。

参与者角色

  1. 抽象表达式 (Expression)
    • 定义解释操作的接口。
  2. 终结符表达式 (TerminalExpression)
    • 实现与文法中的终结符相关的解释操作。
  3. 非终结符表达式 (NonTerminalExpression)
    • 实现文法中的非终结符的解释操作,通常是其他表达式的组合。
  4. 上下文 (Context)
    • 包含解释器需要的全局信息。
  5. 客户端 (Client)
    • 构建文法树,并通过调用解释器来解释表达式。

示例代码

以下代码展示了解释器模式的实现,用于解析和计算简单的数学表达式。

#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>

// 抽象表达式
class Expression {
public:
    virtual ~Expression() = default;

    // 解释方法
    virtual int interpret(const std::unordered_map<std::string, int>& context) const = 0;
};

// 终结符表达式:变量
class VariableExpression : public Expression {
private:
    std::string name;

public:
    explicit VariableExpression(std::string name) : name(std::move(name)) {}

    int interpret(const std::unordered_map<std::string, int>& context) const override {
        auto it = context.find(name);
        if (it != context.end()) {
            return it->second; // 返回变量的值
        }
        throw std::runtime_error("变量未定义: " + name);
    }
};

// 终结符表达式:常量
class ConstantExpression : public Expression {
private:
    int value;

public:
    explicit ConstantExpression(int value) : value(value) {}

    int interpret(const std::unordered_map<std::string, int>& context) const override {
        return value; // 返回常量值
    }
};

// 非终结符表达式:加法
class AddExpression : public Expression {
private:
    std::shared_ptr<Expression> left;
    std::shared_ptr<Expression> right;

public:
    AddExpression(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
        : left(std::move(left)), right(std::move(right)) {}

    int interpret(const std::unordered_map<std::string, int>& context) const override {
        return left->interpret(context) + right->interpret(context); // 加法操作
    }
};

// 非终结符表达式:减法
class SubtractExpression : public Expression {
private:
    std::shared_ptr<Expression> left;
    std::shared_ptr<Expression> right;

public:
    SubtractExpression(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
        : left(std::move(left)), right(std::move(right)) {}

    int interpret(const std::unordered_map<std::string, int>& context) const override {
        return left->interpret(context) - right->interpret(context); // 减法操作
    }
};

// 客户端代码
int main() {
    // 构建表达式: (x + 10) - y
    auto x = std::make_shared<VariableExpression>("x");
    auto y = std::make_shared<VariableExpression>("y");
    auto constant = std::make_shared<ConstantExpression>(10);

    auto addExpr = std::make_shared<AddExpression>(x, constant); // x + 10
    auto subtractExpr = std::make_shared<SubtractExpression>(addExpr, y); // (x + 10) - y

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

    // 解释表达式
    std::cout << "表达式结果: " << subtractExpr->interpret(context) << "
"; // 输出结果: 12

    return 0;
}

代码解析

1. 抽象表达式 (Expression)
  • 定义了解释操作的接口,所有具体表达式类都需要实现此接口。
class Expression {
public:
    virtual ~Expression() = default;
    virtual int interpret(const std::unordered_map<std::string, int>& context) const = 0;
};
2. 终结符表达式
  • VariableExpression:表示变量,解释时从上下文中获取变量的值。
  • ConstantExpression:表示常量,解释时直接返回常量值。
class VariableExpression : public Expression {
    int interpret(const std::unordered_map<std::string, int>& context) const override {
        return context.at(name);
    }
};
3. 非终结符表达式
  • AddExpressionSubtractExpression 实现了抽象表达式接口。
  • 它们通过组合其他表达式实现复杂的语法结构。
class AddExpression : public Expression {
    int interpret(const std::unordered_map<std::string, int>& context) const override {
        return left->interpret(context) + right->interpret(context);
    }
};
4. 客户端代码
  • 客户端通过组合表达式构建语法树,并传入上下文解析表达式。

优缺点

优点
  1. 扩展性强
    • 可以轻松扩展新的表达式类型。
  2. 语法清晰
    • 将语言的语法结构化,易于维护和扩展。
  3. 灵活性
    • 通过组合模式,可以灵活构造复杂的语法。
缺点
  1. 性能开销
    • 每个表达式都是一个对象,可能导致较大的内存开销。
  2. 复杂性高
    • 对于复杂语法,类的数量可能急剧增加。
  3. 适用范围有限
    • 适用于简单语法,复杂语言解析时不适合。

适用场景

  1. 需要解释语言或语法
    • 如编译器、计算器等。
  2. 需要灵活扩展表达式的语法规则
    • 通过组合表达式动态扩展语法。

总结

解释器模式通过定义语言的文法和解释器,提供了一种解析和执行表达式的机制。它适用于简单语言或语法的解析场景,但对于复杂语言解析可能并不适合。


http://www.kler.cn/a/508216.html

相关文章:

  • Zookeeper 数据迁移实战:基础环境搭建与高效迁移方案全览
  • PHP智慧小区物业管理小程序
  • ComfyUI-PromptOptimizer:文生图提示优化节点
  • 网络安全面试题汇总(个人经验)
  • WebSocket实现分布式的不同方案对比
  • 自动驾驶占用网格预测
  • 学校C语言实验——结构2
  • 基于 K-Means 聚类分析实现人脸照片的快速分类
  • .Net WebApi 中的Token参数校验
  • 几个Linux系统安装体验(续): 中科方德服务器系统
  • OpenAI函数调用迎来重大升级:引入「最小惊讶原则」等软件工程实践,开发体验更上一层楼!
  • pix2pix mmgeneration通用场景黑白图片上色模型训练,Docker
  • postman接口测试-get请求
  • 【北京迅为】iTOP-4412全能版使用手册-第七十七章 Qt串口编程
  • 算法:带头结点的单链表原地逆置
  • git 常用命令 git archive
  • 网络IO与IO多路复用
  • 前端入门(html)
  • 计算机网络 (45)动态主机配置协议DHCP
  • 回归预测 | MATLAB实RVM相关向量机多输入单输出回归预测
  • 安装k8s前置操作(Ubuntu / CentOS)
  • DeepSeek-v3在训练和推理方面的优化
  • WPF的C1DataGrid根据当前行实时选的值控制另外一列行是否可编辑
  • 群发邮件适合外贸行业吗
  • CES 2025:XEO 展出双眼8K VR头显,售价2000美元
  • python爬虫入门(理论)