解释器模式(Interpreter Pattern)是一种行为设计模式,它定义了一种语言的文法表示,并提供一个解释器来解释这种语言中的句子。
核心概念
设计原则
解释器模式遵循以下设计原则:
- 单一职责原则:将文法规则分解为多个类 
- 开闭原则:可以扩展新的解释方式而不修改现有代码 
- 封装性:封装语言解释的具体实现 
主要优点
- 易于扩展:可以方便地扩展语言的文法 
- 实现简单:每个文法规则都可以表示为一个类 
- 灵活解释:可以灵活改变解释方式 
- 领域特定语言:适合实现简单的领域特定语言(DSL) 
模式结构
主要组件
- AbstractExpression(抽象表达式) - 声明一个抽象的解释操作 
 
- TerminalExpression(终结符表达式) - 实现与文法中的终结符相关的解释操作 
 
- NonterminalExpression(非终结符表达式) - 实现文法规则的解释操作 
- 通常包含对其他表达式的引用 
 
- Context(上下文) - 包含解释器之外的全局信息 
 
- Client(客户端) - 构建抽象语法树 
- 调用解释操作 
 
完整代码示例
#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>
#include <stack>
#include <stdexcept>
// ==================== 上下文类 ====================
class Context {
    std::unordered_map<std::string, int> variables_;
    
public:
    void setVariable(const std::string& var, int value) {
        variables_[var] = value;
    }
    
    int getVariable(const std::string& var) const {
        return variables_.at(var);
    }
};
// ==================== 抽象表达式 ====================
class Expression {
public:
    virtual int interpret(Context& context) = 0;
    virtual ~Expression() = default;
};
// ==================== 终结符表达式 ====================
class Number : public Expression {
    int number_;
    
public:
    explicit Number(int number) : number_(number) {}
    
    int interpret(Context&) override {
        return number_;
    }
};
class Variable : public Expression {
    std::string name_;
    
public:
    explicit Variable(const std::string& name) : name_(name) {}
    
    int interpret(Context& context) override {
        return context.getVariable(name_);
    }
};
// ==================== 非终结符表达式 ====================
class Add : public Expression {
    std::unique_ptr<Expression> left_;
    std::unique_ptr<Expression> right_;
    
public:
    Add(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
        : left_(std::move(left)), right_(std::move(right)) {}
    
    int interpret(Context& context) override {
        return left_->interpret(context) + right_->interpret(context);
    }
};
class Subtract : public Expression {
    std::unique_ptr<Expression> left_;
    std::unique_ptr<Expression> right_;
    
public:
    Subtract(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
        : left_(std::move(left)), right_(std::move(right)) {}
    
    int interpret(Context& context) override {
        return left_->interpret(context) - right_->interpret(context);
    }
};
class Multiply : public Expression {
    std::unique_ptr<Expression> left_;
    std::unique_ptr<Expression> right_;
    
public:
    Multiply(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
        : left_(std::move(left)), right_(std::move(right)) {}
    
    int interpret(Context& context) override {
        return left_->interpret(context) * right_->interpret(context);
    }
};
// ==================== 解析器 ====================
class Parser {
    std::vector<std::string> tokens_;
    size_t currentToken_;
    
    std::unique_ptr<Expression> parseExpression() {
        auto left = parseTerm();
        
        while (currentToken_ < tokens_.size()) {
            const auto& token = tokens_[currentToken_];
            
            if (token == "+") {
                currentToken_++;
                auto right = parseTerm();
                left = std::make_unique<Add>(std::move(left), std::move(right));
            } else if (token == "-") {
                currentToken_++;
                auto right = parseTerm();
                left = std::make_unique<Subtract>(std::move(left), std::move(right));
            } else {
                break;
            }
        }
        
        return left;
    }
    
    std::unique_ptr<Expression> parseTerm() {
        auto left = parseFactor();
        
        while (currentToken_ < tokens_.size()) {
            const auto& token = tokens_[currentToken_];
            
            if (token == "*") {
                currentToken_++;
                auto right = parseFactor();
                left = std::make_unique<Multiply>(std::move(left), std::move(right));
            } else {
                break;
            }
        }
        
        return left;
    }
    
    std::unique_ptr<Expression> parseFactor() {
        const auto& token = tokens_[currentToken_++];
        
        if (token == "(") {
            auto expr = parseExpression();
            if (tokens_[currentToken_++] != ")") {
                throw std::runtime_error("缺少右括号");
            }
            return expr;
        } else if (isdigit(token[0])) {
            return std::make_unique<Number>(std::stoi(token));
        } else {
            return std::make_unique<Variable>(token);
        }
    }
    
public:
    std::unique_ptr<Expression> parse(const std::string& expression) {
        // 简单分词 - 实际应用中可能需要更复杂的词法分析
        tokens_.clear();
        std::string token;
        for (char ch : expression) {
            if (isspace(ch)) {
                if (!token.empty()) {
                    tokens_.push_back(token);
                    token.clear();
                }
            } else if (ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*') {
                if (!token.empty()) {
                    tokens_.push_back(token);
                    token.clear();
                }
                tokens_.push_back(std::string(1, ch));
            } else {
                token += ch;
            }
        }
        
        if (!token.empty()) {
            tokens_.push_back(token);
        }
        
        currentToken_ = 0;
        return parseExpression();
    }
};
// ==================== 客户端代码 ====================
int main() {
    std::cout << "=== 解释器模式演示: 简单数学表达式计算 ===" << std::endl;
    
    Context context;
    context.setVariable("x", 10);
    context.setVariable("y", 5);
    context.setVariable("z", 2);
    
    Parser parser;
    
    try {
        // 解析并计算表达式
        auto expr1 = parser.parse("x + y * z");
        std::cout << "x + y * z = " << expr1->interpret(context) << std::endl;
        
        auto expr2 = parser.parse("(x + y) * z");
        std::cout << "(x + y) * z = " << expr2->interpret(context) << std::endl;
        
        auto expr3 = parser.parse("x * y + z");
        std::cout << "x * y + z = " << expr3->interpret(context) << std::endl;
        
        // 更复杂的表达式
        auto expr4 = parser.parse("x + y * z + (x - y)");
        std::cout << "x + y * z + (x - y) = " << expr4->interpret(context) << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
    }
    
    return 0;
}模式变体
1. 使用抽象语法树(AST)
// AST节点基类
class ASTNode {
public:
    virtual int evaluate(Context&) = 0;
    virtual ~ASTNode() = default;
};
// 更复杂的AST节点类型
class IfNode : public ASTNode {
    std::unique_ptr<ASTNode> condition_;
    std::unique_ptr<ASTNode> thenBranch_;
    std::unique_ptr<ASTNode> elseBranch_;
    
public:
    int evaluate(Context& context) override {
        if (condition_->evaluate(context)) {
            return thenBranch_->evaluate(context);
        } else if (elseBranch_) {
            return elseBranch_->evaluate(context);
        }
        return 0;
    }
};2. 使用访问者模式遍历AST
class ASTVisitor {
public:
    virtual void visit(NumberNode* node) = 0;
    virtual void visit(VariableNode* node) = 0;
    virtual void visit(BinaryOpNode* node) = 0;
    virtual ~ASTVisitor() = default;
};
class InterpreterVisitor : public ASTVisitor {
    Context& context_;
    int result_;
    
public:
    explicit InterpreterVisitor(Context& context) : context_(context) {}
    
    int getResult() const { return result_; }
    
    void visit(NumberNode* node) override {
        result_ = node->getValue();
    }
    
    void visit(VariableNode* node) override {
        result_ = context_.getVariable(node->getName());
    }
    
    void visit(BinaryOpNode* node) override {
        InterpreterVisitor leftVisitor(context_), rightVisitor(context_);
        node->getLeft()->accept(&leftVisitor);
        node->getRight()->accept(&rightVisitor);
        
        int left = leftVisitor.getResult();
        int right = rightVisitor.getResult();
        
        switch (node->getOp()) {
            case '+': result_ = left + right; break;
            case '-': result_ = left - right; break;
            case '*': result_ = left * right; break;
            default: throw std::runtime_error("未知操作符");
        }
    }
};实际应用场景
- 正则表达式:解释正则表达式模式 
- SQL解析:解析SQL查询语句 
- 数学公式计算:如示例中的表达式计算 
- 编译器设计:解释编程语言的语法 
- 业务规则引擎:解释和执行业务规则