解释器模式 (Interpreter Pattern)

解释器模式 (Interpreter Pattern)

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

基础组件
  • AbstractExpression (抽象表达式):声明抽象解释操作
  • TerminalExpression (终结符表达式):实现与文法中终结符相关的解释操作
  • NonterminalExpression (非终结符表达式):对文法中的规则进行解释
  • Context (上下文):包含解释器需要的全局信息
  • Client (客户端):构建抽象语法树并调用解释操作
继承/实现关系
AbstractExpression <|-- TerminalExpression
AbstractExpression <|-- NonterminalExpression
NonterminalExpression --> AbstractExpression (组合关系)
Client --> AbstractExpression
Client --> Context
应用场景
  • 需要解释执行简单语言
  • 文法规则可以表示为树形结构
  • 效率不是关键问题(解释器模式通常效率不高)
C++ 实现(布尔表达式解释器)
#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
#include <stack>

/*
* 解释器模式(应用频率不高)
* 意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
* 基础组件:
* - AbstractExpression (抽象表达式):声明抽象解释操作
* - TerminalExpression (终结符表达式):实现与文法中终结符相关的解释操作
* - NonterminalExpression (非终结符表达式):对文法中的规则进行解释
* - Context (上下文):包含解释器需要的全局信息
* - Client (客户端):构建抽象语法树并调用解释操作
* 继承/实现关系:
* TerminalExpression 和 NonterminalExpression 都继承自 AbstractExpression。
* NonterminalExpression 可能包含多个 TerminalExpression 或其他 NonterminalExpression 的实例。
* Client 使用 AbstractExpression 的子类来构建抽象语法树并调用解释操作。
* Client 通过 Context 提供必要的上下文信息给表达式进行解释。
*/

// 上下文:存储变量值
class Context {
public:
    void setVariable(const std::string& var, bool value) {
        variables_[var] = value;
    }

    bool getVariable(const std::string& var) const {
        auto it = variables_.find(var);
        return it != variables_.end() ? it->second : false;
    }

private:
    std::unordered_map<std::string, bool> variables_;
};

// 抽象表达式
class BooleanExpression {
public:
    virtual ~BooleanExpression() = default;
    virtual bool interpret(const Context& context) const = 0;
};

// 终结符表达式:变量
class VariableExpression : public BooleanExpression {
public:
    explicit VariableExpression(const std::string& name) : name_(name) {}

    bool interpret(const Context& context) const override {
        return context.getVariable(name_);
    }

private:
    std::string name_;
};

// 非终结符表达式:与运算
class AndExpression : public BooleanExpression {
public:
    AndExpression(std::unique_ptr<BooleanExpression> left,
        std::unique_ptr<BooleanExpression> right)
        : left_(std::move(left)), right_(std::move(right)) {}

    bool interpret(const Context& context) const override {
        return left_->interpret(context) && right_->interpret(context);
    }

private:
    std::unique_ptr<BooleanExpression> left_;
    std::unique_ptr<BooleanExpression> right_;
};

// 非终结符表达式:或运算
class OrExpression : public BooleanExpression {
public:
    OrExpression(std::unique_ptr<BooleanExpression> left,
        std::unique_ptr<BooleanExpression> right)
        : left_(std::move(left)), right_(std::move(right)) {}

    bool interpret(const Context& context) const override {
        return left_->interpret(context) || right_->interpret(context);
    }

private:
    std::unique_ptr<BooleanExpression> left_;
    std::unique_ptr<BooleanExpression> right_;
};

// 非终结符表达式:非运算
class NotExpression : public BooleanExpression {
public:
    explicit NotExpression(std::unique_ptr<BooleanExpression> expr)
        : expr_(std::move(expr)) {}

    bool interpret(const Context& context) const override {
        return !expr_->interpret(context);
    }

private:
    std::unique_ptr<BooleanExpression> expr_;
};

// 简单解析器(构建表达式树)
class ExpressionParser {
public:
    std::unique_ptr<BooleanExpression> parse(const std::string& expression) {
        std::stack<std::unique_ptr<BooleanExpression>> stack;

        // 简单分词
        size_t pos = 0;
        while (pos < expression.size()) {
            if (expression[pos] == ' ') {
                pos++;
                continue;
            }

            if (expression[pos] == '&') {
                auto right = std::move(stack.top()); stack.pop();
                auto left = std::move(stack.top()); stack.pop();
                stack.push(std::make_unique<AndExpression>(std::move(left), std::move(right)));
                pos++;
            }
            else if (expression[pos] == '|') {
                auto right = std::move(stack.top()); stack.pop();
                auto left = std::move(stack.top()); stack.pop();
                stack.push(std::make_unique<OrExpression>(std::move(left), std::move(right)));
                pos++;
            }
            else if (expression[pos] == '!') {
                auto expr = std::move(stack.top()); stack.pop();
                stack.push(std::make_unique<NotExpression>(std::move(expr)));
                pos++;
            }
            else {
                // 解析变量名
                size_t end = pos;
                while (end < expression.size() && expression[end] != ' ' &&
                    expression[end] != '&' && expression[end] != '|' && expression[end] != '!') {
                    end++;
                }
                std::string var = expression.substr(pos, end - pos);
                stack.push(std::make_unique<VariableExpression>(var));
                pos = end;
            }
        }

        return std::move(stack.top());
    }
};

void InterpreterPattern()
{
	std::cout << std::string(13, '-') << " Interpreter Pattern " << std::string(13, '-') << "\n";

    Context context;
    context.setVariable("A", true);
    context.setVariable("B", false);
    context.setVariable("C", true);

    ExpressionParser parser;

    // 解析表达式:A AND (B OR C)
    auto expr1 = parser.parse("A B C | &");
    std::cout << "A AND (B OR C) = "
        << std::boolalpha << expr1->interpret(context) << "\n"; // true

    // 解析表达式:NOT (A AND B)
    auto expr2 = parser.parse("A B & !");
    std::cout << "NOT (A AND B) = "
        << std::boolalpha << expr2->interpret(context) << "\n"; // true
}

组件对应关系
  • BooleanExpression → 抽象表达式
  • VariableExpression → 终结符表达式
  • AndExpression/OrExpression/NotExpression → 非终结符表达式
  • Context → 上下文
  • ExpressionParser → 客户端(解析器)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值