【设计模式详解】探秘解释器模式,掌握解释器模式的艺术及其神奇力量【C++代码实现示例】

本文详细介绍了设计模式中的解释器模式,包括其原理、C++示例、结构图、使用场景、优缺点以及在数学表达式和自定义语言解析中的应用。
摘要由CSDN通过智能技术生成

其他模式的详解:

【设计模式】桥接模式详解,如何优雅地处理不同维度的系统变化? 有原理、示例、场景、优缺点及常见面试题和答案-CSDN博客

【设计模式详解】外观模式:简化复杂系统接口的大门,一键式接入,无忧使用 C++代码详解实现-CSDN博客 

【设计模式】功能无限,结构不变:探秘装饰器模式的神奇魔力,揭秘装饰器模式的设计精髓-CSDN博客

【设计模式】适配器模式 告别接口难题,让你的代码更兼容,让你的接口不再孤单,解锁接口兼容新境界,让你的代码变得更灵活!-CSDN博客

前言:

咱们一起来聊聊行为型设计模式的解释器模式。

一、原理及示例代码

解释器模式是一种行为型设计模式,它用于定义语言的文法,并且在运行时解释和执行语言中的表达式。该模式通常包含以下几个角色:

  1. 抽象表达式(Abstract Expression):定义了一个抽象的接口,用于解释和执行特定的语法规则。
  2. 终结符表达式(Terminal Expression):实现了抽象表达式接口,用于表示语言中的终结符(如变量、常量等)。
  3. 非终结符表达式(Non-terminal Expression):实现了抽象表达式接口,用于表示语言中的非终结符,通常由多个终结符或非终结符组成。
  4. 上下文(Context):包含解释器需要的全局信息,对解释器进行初始化和赋值。

下面是一个简单的 C++ 示例代码,演示了如何使用解释器模式来解释和执行简单的数学表达式:

#include <iostream>
#include <map>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<char, int>& context) = 0;
};

// 终结符表达式
class VariableExpression : public Expression {
private:
    char name;
public:
    VariableExpression(char name) : name(name) {}
    int interpret(std::map<char, int>& context) override {
        return context[name];
    }
};

// 非终结符表达式
class AddExpression : public Expression {
private:
    Expression* left;
    Expression* right;
public:
    AddExpression(Expression* left, Expression* right) : left(left), right(right) {}
    int interpret(std::map<char, int>& context) override {
        return left->interpret(context) + right->interpret(context);
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<char, int> context;
    context['a'] = 5;
    context['b'] = 7;

    // 构建表达式:a + b
    Expression* expression = new AddExpression(new VariableExpression('a'), new VariableExpression('b'));

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

在上面的示例中,我们定义了抽象表达式 Expression,终结符表达式 VariableExpression 和非终结符表达式 AddExpression。然后,我们创建了一个上下文 context,并构建了一个简单的数学表达式 a + b。最后,我们执行表达式并输出结果。

二、结构图

解释器模式的结构图如下所示:

  +---------------------+      +---------------------+
  |   AbstractExpression|      |   TerminalExpression|
  +---------------------+      +---------------------+
  |   interpret()       |      |   interpret()       |
  +---------------------+      +---------------------+
              |                        |
              |                        |
              +------------------------+
                           |
                           |
                  +------------------+
                  | NonterminalExpression|
                  +------------------+
                  |   interpret()    |
                  +------------------+

在上面的结构图中,我们可以看到以下几个重要的角色:

  1. AbstractExpression(抽象表达式):定义了一个抽象的接口,包含 interpret 方法,用于解释和执行特定的语法规则。
  2. TerminalExpression(终结符表达式):实现了抽象表达式接口,用于表示语言中的终结符,通常包含 interpret 方法来执行具体的解释。
  3. NonterminalExpression(非终结符表达式):同样实现了抽象表达式接口,用于表示语言中的非终结符,通常由多个终结符或非终结符组成,也包含 interpret 方法来执行具体的解释。

这些角色共同协作,使得解释器模式可以解释和执行特定语言的表达式。

三、使用场景

解释器模式通常在以下情况下使用:

  1. 当有一个简单的语法规则,并且需要解释和执行这个语法规则时,可以使用解释器模式。例如,数学表达式、逻辑表达式等都可以使用解释器模式来解释和执行。

  2. 当需要构建一个可以灵活扩展的语言解释器时,可以使用解释器模式。通过定义抽象表达式和具体的终结符表达式、非终结符表达式,可以轻松地扩展语言的语法规则。

下面分别给出这两种情况的C++示例代码:

场景一:数学表达式解释器

#include <iostream>
#include <map>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<char, int>& context) = 0;
};

// 终结符表达式
class VariableExpression : public Expression {
private:
    char name;
public:
    VariableExpression(char name) : name(name) {}
    int interpret(std::map<char, int>& context) override {
        return context[name];
    }
};

// 非终结符表达式
class AddExpression : public Expression {
private:
    Expression* left;
    Expression* right;
public:
    AddExpression(Expression* left, Expression* right) : left(left), right(right) {}
    int interpret(std::map<char, int>& context) override {
        return left->interpret(context) + right->interpret(context);
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<char, int> context;
    context['a'] = 5;
    context['b'] = 7;

    // 构建表达式:a + b
    Expression* expression = new AddExpression(new VariableExpression('a'), new VariableExpression('b'));

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

场景二:自定义语言解释器

#include <iostream>
#include <map>
#include <string>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<std::string, int>& context) = 0;
};

// 终结符表达式
class NumberExpression : public Expression {
private:
    int value;
public:
    NumberExpression(int value) : value(value) {}
    int interpret(std::map<std::string, int>& context) override {
        return value;
    }
};

// 非终结符表达式
class VariableExpression : public Expression {
private:
    std::string name;
public:
    VariableExpression(const std::string& name) : name(name) {}
    int interpret(std::map<std::string, int>& context) override {
        return context[name];
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<std::string, int> context;
    context["x"] = 5;
    context["y"] = 7;

    // 构建表达式:2 * x + y
    Expression* expression = new AddExpression(
        new MultiplyExpression(new NumberExpression(2), new VariableExpression("x")),
        new VariableExpression("y")
    );

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

在这两个示例中,我们分别展示了数学表达式解释器和自定义语言解释器的使用,演示了如何使用解释器模式来解释和执行特定的语法规则。

四、优缺点

解释器模式(Interpreter Pattern)的优点和缺点如下:

优点:

  1. 易于扩展:可以通过增加新的表达式类来扩展语言的语法规则,而不需要修改现有的代码。
  2. 易于实现语法解释:对于简单的语法规则,使用解释器模式可以很容易地实现语法解释和执行。
  3. 易于维护:将语法规则的解释功能封装在表达式类中,使得代码易于维护和理解。

缺点:

  1. 可能导致类膨胀:随着语法规则的复杂性增加,可能需要创建大量的表达式类,导致类的数量膨胀,使得系统变得复杂。
  2. 可能降低性能:解释器模式通常需要对语法规则进行解释和执行,可能会导致性能上的一些损失,特别是在处理复杂语法规则时。

总的来说,解释器模式适合用于处理简单的语法规则的解释和执行,但在处理复杂的语法规则时可能会导致类膨胀和性能损失。在选择是否使用解释器模式时,需要根据具体的场景和需求进行权衡。

------------------------------------------分界线-------------------------------------------

     5                                                          
                                                            
              +---+                                               
              |   |                                               
              |   | 3                       3                                                 |---|
        |      |   |                                                                           |   |
        |      |   +---+                   -----                  + ---+                       |   |
        |      | +      |       |            |   |                  +     |----|3              |   |
  +     |    2 | +      |       |          2 |   |     2            +     |    |               |   |
  +     |      | +      |       |            |   |                  +     |    |               |   |
  +     |  +---+ +      |       |        ----+   |   +---+          +     |    |               |   |
  +       |     +      |       |        |       |   |   |          +     |    |    ++++++|    |   |
  +     1 |     +      | 1     |      1 |       | 1 |   | 1        +     |    |    |     |    |   |
  +       |     +      |       |        |       |   |   |          +     |    |    |     |    |   |
  +   +---+     +      +---+   |    +---+       +---+   +---+      +     |    |    |     |    |   |
  +   |         +          |   |    |                       |      +     |    |    |     |    |   |
  + 0 |         +          | 0 |  0 |                       | 0    +     |    |    |     |    |   |
  +   |         +          |   |    |                       |      +     |    |    |     |    |   |
  +---+         +          +-------+                       +---+  +  +--- |    |+   |     |++ |   |+
                +                                                      
    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14   15  16  17  18 19  20  21
 

  • 39
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五木大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值