解释器模式(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查询语句
数学公式计算:如示例中的表达式计算
编译器设计:解释编程语言的语法
业务规则引擎:解释和执行业务规则