第二十三章:解析天书,诠释法则------Interpreter的解释艺术
风云际会,解释器登场
在Memento展示完他那精妙的状态记忆艺术后,Interpreter正在解析一段古老的符文的语言学家走出。
"Memento兄的状态记忆确实精妙,"Interpreter专注地说道,"但在需要解释特定语言或文法时,需要更加专业的解释机制。我的解释器模式,允许你定义语言的文法,并提供一个解释器来解释语言中的句子。对于简单的文法,解释器模式可以优雅地处理解释任务。"
架构老人眼中闪过赞许之色:"善!Interpreter,就请你为大家展示这解释艺术的精妙所在。"
解释器模式的核心要义
Interpreter面向众人,开始阐述他的武学真谛:
"在我的解释器模式中,主要包含几个核心角色:"
"AbstractExpression(抽象表达式):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。"
"TerminalExpression(终结符表达式):实现与文法中的终结符相关联的解释操作。一个句子中的每个终结符需要该类的一个实例。"
"NonterminalExpression(非终结符表达式):对文法中的每一条规则都需要一个具体的非终结符表达式类。这些类通常包含其他表达式的引用(可以是终结符,也可以是非终结符),然后递归地调用这些表达式进行解释。"
"Context(上下文):包含解释器之外的一些全局信息。"
"Client(客户端):构建表示该文法定义的语言中一个特定句子的抽象语法树。该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成。然后调用解释操作。"
"其精妙之处在于,"Interpreter继续道,"我将一个语言表示为一个抽象语法树,并定义一个解释器,通过递归的方式解释执行这些语法树节点。这样,就可以很容易地改变和扩展文法。"
C++实战:数学表达式计算器
"且让我以一个数学表达式计算器为例,展示解释器模式的实战应用。"Interpreter说着,手中凝聚出一道道代码流光。
基础框架搭建
首先,Interpreter定义了表达式和上下文的接口:
cpp
#include <iostream>
#include <string>
#include <memory>
#include <stack>
#include <map>
#include <sstream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
// 前向声明
class Context;
// 抽象表达式
class Expression {
public:
virtual ~Expression() = default;
// 解释方法
virtual double interpret(Context& context) = 0;
// 表达式类型
virtual std::string getType() const = 0;
// 显示表达式
virtual void display(int indent = 0) const = 0;
// 表达式信息
virtual std::string toString() const = 0;
};
// 上下文:存储变量和函数
class Context {
private:
std::map<std::string, double> variables_;
std::map<std::string, std::function<double(std::vector<double>)>> functions_;
public:
Context() {
initializeBuiltinFunctions();
}
// 变量操作
void setVariable(const std::string& name, double value) {
variables_[name] = value;
std::cout << "📝 设置变量 " << name << " = " << value << std::endl;
}
double getVariable(const std::string& name) const {
auto it = variables_.find(name);
if (it != variables_.end()) {
return it->second;
}
throw std::runtime_error("未知变量: " + name);
}
bool hasVariable(const std::string& name) const {
return variables_.find(name) != variables_.end();
}
// 函数操作
void setFunction(const std::string& name, std::function<double(std::vector<double>)> func) {
functions_[name] = func;
std::cout << "📝 设置函数 " << name << "()" << std::endl;
}
double callFunction(const std::string& name, const std::vector<double>& args) {
auto it = functions_.find(name);
if (it != functions_.end()) {
return it->second(args);
}
throw std::runtime_error("未知函数: " + name);
}
bool hasFunction(const std::string& name) const {
return functions_.find(name) != functions_.end();
}
// 显示上下文内容
void display() const {
std::cout << "\n📋 上下文内容:" << std::endl;
std::cout << "=============" << std::endl;
std::cout << "变量 (" << variables_.size() << " 个):" << std::endl;
for (const auto& [name, value] : variables_) {
std::cout << " • " << name << " = " << value << std::endl;
}
std::cout << "函数 (" << functions_.size() << " 个):" << std::endl;
for (const auto& [name, _] : functions_) {
std::cout << " • " << name << "(...)" << std::endl;
}
}
// 清除所有变量
void clearVariables() {
variables_.clear();
std::cout << "🧹 清除所有变量" << std::endl;
}
private:
void initializeBuiltinFunctions() {
// 内置数学函数
setFunction("sin", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("sin函数需要一个参数");
return std::sin(args[0]);
});
setFunction("cos", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("cos函数需要一个参数");
return std::cos(args[0]);
});
setFunction("tan", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("tan函数需要一个参数");
return std::tan(args[0]);
});
setFunction("log", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("log函数需要一个参数");
return std::log(args[0]);
});
setFunction("exp", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("exp函数需要一个参数");
return std::exp(args[0]);
});
setFunction("pow", [](const std::vector<double>& args) {
if (args.size() != 2) throw std::runtime_error("pow函数需要两个参数");
return std::pow(args[0], args[1]);
});
setFunction("sqrt", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("sqrt函数需要一个参数");
return std::sqrt(args[0]);
});
setFunction("abs", [](const std::vector<double>& args) {
if (args.size() != 1) throw std::runtime_error("abs函数需要一个参数");
return std::abs(args[0]);
});
setFunction("max", [](const std::vector<double>& args) {
if (args.empty()) throw std::runtime_error("max函数需要至少一个参数");
double maxVal = args[0];
for (double val : args) {
if (val > maxVal) maxVal = val;
}
return maxVal;
});
setFunction("min", [](const std::vector<double>& args) {
if (args.empty()) throw std::runtime_error("min函数需要至少一个参数");
double minVal = args[0];
for (double val : args) {
if (val < minVal) minVal = val;
}
return minVal;
});
setFunction("sum", [](const std::vector<double>& args) {
double total = 0.0;
for (double val : args) {
total += val;
}
return total;
});
setFunction("avg", [](const std::vector<double>& args) {
if (args.empty()) throw std::runtime_error("avg函数需要至少一个参数");
double total = 0.0;
for (double val : args) {
total += val;
}
return total / args.size();
});
}
};
具体表达式实现
Interpreter展示了各种数学表达式的具体实现:
cpp
// 终结符表达式:数字
class NumberExpression : public Expression {
private:
double value_;
public:
NumberExpression(double value) : value_(value) {
std::cout << "🔢 创建数字表达式: " << value_ << std::endl;
}
double interpret(Context& context) override {
return value_;
}
std::string getType() const override {
return "Number";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "📊 数字: " << value_ << std::endl;
}
std::string toString() const override {
return std::to_string(value_);
}
double getValue() const { return value_; }
};
// 终结符表达式:变量
class VariableExpression : public Expression {
private:
std::string name_;
public:
VariableExpression(const std::string& name) : name_(name) {
std::cout << "📝 创建变量表达式: " << name_ << std::endl;
}
double interpret(Context& context) override {
return context.getVariable(name_);
}
std::string getType() const override {
return "Variable";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "📝 变量: " << name_ << std::endl;
}
std::string toString() const override {
return name_;
}
std::string getName() const { return name_; }
};
// 非终结符表达式:二元运算
class BinaryOperationExpression : public Expression {
public:
enum Operation {
ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, MODULO
};
private:
std::unique_ptr<Expression> left_;
std::unique_ptr<Expression> right_;
Operation operation_;
public:
BinaryOperationExpression(std::unique_ptr<Expression> left,
std::unique_ptr<Expression> right,
Operation operation)
: left_(std::move(left)), right_(std::move(right)), operation_(operation) {
std::cout << "🔗 创建二元运算表达式: " << getOperationSymbol() << std::endl;
}
double interpret(Context& context) override {
double leftValue = left_->interpret(context);
double rightValue = right_->interpret(context);
switch (operation_) {
case ADD:
return leftValue + rightValue;
case SUBTRACT:
return leftValue - rightValue;
case MULTIPLY:
return leftValue * rightValue;
case DIVIDE:
if (rightValue == 0) throw std::runtime_error("除以零错误");
return leftValue / rightValue;
case POWER:
return std::pow(leftValue, rightValue);
case MODULO:
if (rightValue == 0) throw std::runtime_error("取模运算除数为零");
return std::fmod(leftValue, rightValue);
default:
throw std::runtime_error("未知的二元运算");
}
}
std::string getType() const override {
return "BinaryOperation";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "🔗 二元运算: " << getOperationSymbol() << std::endl;
left_->display(indent + 2);
right_->display(indent + 2);
}
std::string toString() const override {
return "(" + left_->toString() + " " + getOperationSymbol() + " " + right_->toString() + ")";
}
Operation getOperation() const { return operation_; }
private:
std::string getOperationSymbol() const {
switch (operation_) {
case ADD: return "+";
case SUBTRACT: return "-";
case MULTIPLY: return "*";
case DIVIDE: return "/";
case POWER: return "^";
case MODULO: return "%";
default: return "?";
}
}
};
// 非终结符表达式:函数调用
class FunctionCallExpression : public Expression {
private:
std::string functionName_;
std::vector<std::unique_ptr<Expression>> arguments_;
public:
FunctionCallExpression(const std::string& functionName,
std::vector<std::unique_ptr<Expression>> arguments)
: functionName_(functionName), arguments_(std::move(arguments)) {
std::cout << "📞 创建函数调用表达式: " << functionName_
<< " (参数数: " << arguments_.size() << ")" << std::endl;
}
double interpret(Context& context) override {
std::vector<double> args;
for (const auto& arg : arguments_) {
args.push_back(arg->interpret(context));
}
return context.callFunction(functionName_, args);
}
std::string getType() const override {
return "FunctionCall";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "📞 函数调用: " << functionName_
<< " (参数数: " << arguments_.size() << ")" << std::endl;
for (const auto& arg : arguments_) {
arg->display(indent + 2);
}
}
std::string toString() const override {
std::string result = functionName_ + "(";
for (size_t i = 0; i < arguments_.size(); ++i) {
result += arguments_[i]->toString();
if (i < arguments_.size() - 1) {
result += ", ";
}
}
result += ")";
return result;
}
std::string getFunctionName() const { return functionName_; }
int getArgumentCount() const { return arguments_.size(); }
};
// 非终结符表达式:括号表达式
class ParenthesizedExpression : public Expression {
private:
std::unique_ptr<Expression> expression_;
public:
ParenthesizedExpression(std::unique_ptr<Expression> expression)
: expression_(std::move(expression)) {
std::cout << "📌 创建括号表达式" << std::endl;
}
double interpret(Context& context) override {
return expression_->interpret(context);
}
std::string getType() const override {
return "Parenthesized";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "📌 括号表达式" << std::endl;
expression_->display(indent + 2);
}
std::string toString() const override {
return "(" + expression_->toString() + ")";
}
};
// 非终结符表达式:一元运算
class UnaryOperationExpression : public Expression {
public:
enum Operation {
PLUS, MINUS, FACTORIAL
};
private:
std::unique_ptr<Expression> expression_;
Operation operation_;
public:
UnaryOperationExpression(std::unique_ptr<Expression> expression, Operation operation)
: expression_(std::move(expression)), operation_(operation) {
std::cout << "🔧 创建一元运算表达式: " << getOperationSymbol() << std::endl;
}
double interpret(Context& context) override {
double value = expression_->interpret(context);
switch (operation_) {
case PLUS:
return +value;
case MINUS:
return -value;
case FACTORIAL: {
if (value < 0 || std::floor(value) != value) {
throw std::runtime_error("阶乘运算需要非负整数");
}
double result = 1.0;
for (int i = 2; i <= static_cast<int>(value); ++i) {
result *= i;
}
return result;
}
default:
throw std::runtime_error("未知的一元运算");
}
}
std::string getType() const override {
return "UnaryOperation";
}
void display(int indent = 0) const override {
std::string indentation(indent, ' ');
std::cout << indentation << "🔧 一元运算: " << getOperationSymbol() << std::endl;
expression_->display(indent + 2);
}
std::string toString() const override {
std::string symbol = getOperationSymbol();
if (operation_ == FACTORIAL) {
return expression_->toString() + symbol;
} else {
return symbol + expression_->toString();
}
}
Operation getOperation() const { return operation_; }
private:
std::string getOperationSymbol() const {
switch (operation_) {
case PLUS: return "+";
case MINUS: return "-";
case FACTORIAL: return "!";
default: return "?";
}
}
};
表达式解析器
Interpreter展示了如何将字符串解析为表达式树:
cpp
// 表达式解析器
class ExpressionParser {
private:
std::string input_;
size_t pos_;
char currentChar_;
Context& context_;
public:
ExpressionParser(const std::string& input, Context& context)
: input_(input), pos_(0), context_(context) {
currentChar_ = input_.empty() ? '\0' : input_[0];
std::cout << "🔍 创建表达式解析器: " << input_ << std::endl;
}
// 主解析方法
std::unique_ptr<Expression> parse() {
auto result = parseExpression();
skipWhitespace();
if (currentChar_ != '\0') {
throw std::runtime_error("意外的字符: " + std::string(1, currentChar_));
}
return result;
}
private:
// 推进到下一个字符
void advance() {
pos_++;
currentChar_ = (pos_ < input_.length()) ? input_[pos_] : '\0';
}
// 跳过空白字符
void skipWhitespace() {
while (currentChar_ != '\0' && std::isspace(currentChar_)) {
advance();
}
}
// 解析表达式
std::unique_ptr<Expression> parseExpression() {
return parseAddSubtract();
}
// 解析加减法
std::unique_ptr<Expression> parseAddSubtract() {
auto left = parseMultiplyDivide();
while (true) {
skipWhitespace();
BinaryOperationExpression::Operation op;
if (currentChar_ == '+') {
op = BinaryOperationExpression::ADD;
} else if (currentChar_ == '-') {
op = BinaryOperationExpression::SUBTRACT;
} else {
break;
}
advance();
auto right = parseMultiplyDivide();
left = std::make_unique<BinaryOperationExpression>(std::move(left), std::move(right), op);
}
return left;
}
// 解析乘除法
std::unique_ptr<Expression> parseMultiplyDivide() {
auto left = parsePower();
while (true) {
skipWhitespace();
BinaryOperationExpression::Operation op;
if (currentChar_ == '*') {
op = BinaryOperationExpression::MULTIPLY;
} else if (currentChar_ == '/') {
op = BinaryOperationExpression::DIVIDE;
} else if (currentChar_ == '%') {
op = BinaryOperationExpression::MODULO;
} else {
break;
}
advance();
auto right = parsePower();
left = std::make_unique<BinaryOperationExpression>(std::move(left), std::move(right), op);
}
return left;
}
// 解析幂运算
std::unique_ptr<Expression> parsePower() {
auto left = parseUnary();
while (true) {
skipWhitespace();
if (currentChar_ == '^') {
advance();
auto right = parseUnary();
left = std::make_unique<BinaryOperationExpression>(
std::move(left), std::move(right), BinaryOperationExpression::POWER);
} else {
break;
}
}
return left;
}
// 解析一元运算
std::unique_ptr<Expression> parseUnary() {
skipWhitespace();
UnaryOperationExpression::Operation op = UnaryOperationExpression::PLUS;
bool hasUnary = false;
if (currentChar_ == '+') {
op = UnaryOperationExpression::PLUS;
hasUnary = true;
} else if (currentChar_ == '-') {
op = UnaryOperationExpression::MINUS;
hasUnary = true;
}
if (hasUnary) {
advance();
auto expr = parseUnary(); // 递归处理连续的一元运算符
return std::make_unique<UnaryOperationExpression>(std::move(expr), op);
}
return parsePrimary();
}
// 解析基本表达式
std::unique_ptr<Expression> parsePrimary() {
skipWhitespace();
if (currentChar_ == '(') {
return parseParentheses();
} else if (std::isdigit(currentChar_) || currentChar_ == '.') {
return parseNumber();
} else if (std::isalpha(currentChar_)) {
return parseIdentifier();
} else {
throw std::runtime_error("无法解析的字符: " + std::string(1, currentChar_));
}
}
// 解析括号表达式
std::unique_ptr<Expression> parseParentheses() {
advance(); // 跳过 '('
auto expression = parseExpression();
skipWhitespace();
if (currentChar_ != ')') {
throw std::runtime_error("期望 ')'");
}
advance(); // 跳过 ')'
return std::make_unique<ParenthesizedExpression>(std::move(expression));
}
// 解析数字
std::unique_ptr<Expression> parseNumber() {
std::string numberStr;
bool hasDecimal = false;
while (currentChar_ != '\0' &&
(std::isdigit(currentChar_) || currentChar_ == '.')) {
if (currentChar_ == '.') {
if (hasDecimal) {
throw std::runtime_error("数字中不能有多个小数点");
}
hasDecimal = true;
}
numberStr += currentChar_;
advance();
}
// 检查阶乘运算符
skipWhitespace();
if (currentChar_ == '!') {
advance();
auto numberExpr = parseNumberFromString(numberStr);
return std::make_unique<UnaryOperationExpression>(
std::move(numberExpr), UnaryOperationExpression::FACTORIAL);
}
return parseNumberFromString(numberStr);
}
std::unique_ptr<Expression> parseNumberFromString(const std::string& numberStr) {
try {
double value = std::stod(numberStr);
return std::make_unique<NumberExpression>(value);
} catch (const std::exception&) {
throw std::runtime_error("无效的数字: " + numberStr);
}
}
// 解析标识符(变量或函数)
std::unique_ptr<Expression> parseIdentifier() {
std::string identifier;
while (currentChar_ != '\0' &&
(std::isalnum(currentChar_) || currentChar_ == '_')) {
identifier += currentChar_;
advance();
}
skipWhitespace();
// 检查是否是函数调用
if (currentChar_ == '(') {
return parseFunctionCall(identifier);
} else {
// 检查阶乘运算符
if (currentChar_ == '!') {
advance();
auto varExpr = std::make_unique<VariableExpression>(identifier);
return std::make_unique<UnaryOperationExpression>(
std::move(varExpr), UnaryOperationExpression::FACTORIAL);
}
// 变量
return std::make_unique<VariableExpression>(identifier);
}
}
// 解析函数调用
std::unique_ptr<Expression> parseFunctionCall(const std::string& functionName) {
advance(); // 跳过 '('
std::vector<std::unique_ptr<Expression>> arguments;
skipWhitespace();
if (currentChar_ != ')') {
while (true) {
arguments.push_back(parseExpression());
skipWhitespace();
if (currentChar_ == ')') {
break;
} else if (currentChar_ == ',') {
advance();
} else {
throw std::runtime_error("期望 ',' 或 ')'");
}
}
}
advance(); // 跳过 ')'
return std::make_unique<FunctionCallExpression>(functionName, std::move(arguments));
}
};
UML 武功秘籍图
creates uses uses uses <<interface>> Expression +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string Context -map<string,double> variables_ -map<string,function> functions_ +setVariable(string, double) : void +getVariable(string) : double +hasVariable(string) : bool +setFunction(string, function) : void +callFunction(string, vector<double>) : double +hasFunction(string) : bool +display() : void +clearVariables() : void NumberExpression -double value_ +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string +getValue() : double VariableExpression -string name_ +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string +getName() : string BinaryOperationExpression -unique_ptr<Expression> left_ -unique_ptr<Expression> right_ -Operation operation_ +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string +getOperation() : Operation FunctionCallExpression -string functionName_ -vector<unique_ptr>Expression<> arguments_ +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string +getFunctionName() : string +getArgumentCount() : int UnaryOperationExpression -unique_ptr<Expression> expression_ -Operation operation_ +interpret(Context&) : double +getType() : string +display(int) : void +toString() : string +getOperation() : Operation ExpressionParser -string input_ -size_t pos_ -char currentChar_ -Context& context_ +parse() : unique_ptr<Expression>
实战演练:高级计算器系统
Interpreter继续展示更复杂的解释器模式应用:
cpp
// 高级计算器系统
class AdvancedCalculator {
private:
Context context_;
std::map<std::string, std::unique_ptr<Expression>> storedExpressions_;
std::vector<std::string> history_;
public:
AdvancedCalculator() {
std::cout << "🧮 创建高级计算器系统" << std::endl;
initializeDefaultVariables();
}
// 计算表达式
double evaluate(const std::string& expression) {
try {
std::cout << "\n🔍 解析表达式: " << expression << std::endl;
ExpressionParser parser(expression, context_);
auto expr = parser.parse();
std::cout << "📐 抽象语法树:" << std::endl;
expr->display(2);
std::cout << "📝 表达式: " << expr->toString() << std::endl;
double result = expr->interpret(context_);
// 记录历史
std::string historyEntry = expression + " = " + std::to_string(result);
history_.push_back(historyEntry);
std::cout << "✅ 计算结果: " << result << std::endl;
return result;
} catch (const std::exception& e) {
std::cout << "❌ 计算错误: " << e.what() << std::endl;
throw;
}
}
// 存储表达式
void storeExpression(const std::string& name, const std::string& expression) {
try {
ExpressionParser parser(expression, context_);
auto expr = parser.parse();
storedExpressions_[name] = std::move(expr);
std::cout << "💾 存储表达式 '" << name << "': " << expression << std::endl;
} catch (const std::exception& e) {
std::cout << "❌ 存储表达式失败: " << e.what() << std::endl;
throw;
}
}
// 评估存储的表达式
double evaluateStored(const std::string& name) {
auto it = storedExpressions_.find(name);
if (it == storedExpressions_.end()) {
throw std::runtime_error("未找到存储的表达式: " + name);
}
std::cout << "\n🔍 评估存储的表达式: " << name << std::endl;
std::cout << "📐 抽象语法树:" << std::endl;
it->second->display(2);
std::cout << "📝 表达式: " << it->second->toString() << std::endl;
double result = it->second->interpret(context_);
std::cout << "✅ 计算结果: " << result << std::endl;
return result;
}
// 设置变量
void setVariable(const std::string& name, double value) {
context_.setVariable(name, value);
}
// 显示系统状态
void displaySystemStatus() const {
std::cout << "\n📊 计算器系统状态" << std::endl;
std::cout << "================" << std::endl;
context_.display();
std::cout << "存储的表达式: " << storedExpressions_.size() << " 个" << std::endl;
for (const auto& [name, _] : storedExpressions_) {
std::cout << " • " << name << std::endl;
}
std::cout << "计算历史: " << history_.size() << " 条" << std::endl;
for (size_t i = 0; i < std::min(history_.size(), size_t(5)); ++i) {
std::cout << " • " << history_[i] << std::endl;
}
}
// 批量计算
void batchEvaluate(const std::vector<std::string>& expressions) {
std::cout << "\n🔧 批量计算 " << expressions.size() << " 个表达式" << std::endl;
int successCount = 0;
for (const auto& expr : expressions) {
try {
evaluate(expr);
successCount++;
} catch (const std::exception& e) {
std::cout << "⚠️ 跳过有问题的表达式: " << expr << " (" << e.what() << ")" << std::endl;
}
}
std::cout << "📈 批量计算完成: " << successCount << "/" << expressions.size() << " 成功" << std::endl;
}
// 清除历史
void clearHistory() {
history_.clear();
std::cout << "🧹 清除计算历史" << std::endl;
}
// 清除存储的表达式
void clearStoredExpressions() {
storedExpressions_.clear();
std::cout << "🧹 清除存储的表达式" << std::endl;
}
private:
void initializeDefaultVariables() {
// 设置一些常用常量
context_.setVariable("pi", 3.141592653589793);
context_.setVariable("e", 2.718281828459045);
context_.setVariable("phi", 1.618033988749895);
std::cout << "✅ 初始化默认变量完成" << std::endl;
}
};
// 测试解释器模式
void testInterpreterPattern() {
std::cout << "=== 解释器模式测试开始 ===" << std::endl;
// 创建计算器
AdvancedCalculator calculator;
// 测试基本算术
std::cout << "\n--- 基本算术测试 ---" << std::endl;
calculator.evaluate("2 + 3 * 4");
calculator.evaluate("(2 + 3) * 4");
calculator.evaluate("10 / 2 - 1");
calculator.evaluate("2 ^ 3 ^ 2"); // 幂运算右结合
calculator.evaluate("10 % 3"); // 取模运算
// 测试变量
std::cout << "\n--- 变量测试 ---" << std::endl;
calculator.setVariable("x", 5);
calculator.setVariable("y", 3);
calculator.evaluate("x * y + 2");
calculator.evaluate("x ^ y");
// 测试一元运算
std::cout << "\n--- 一元运算测试 ---" << std::endl;
calculator.evaluate("-5 + 3");
calculator.evaluate("+2 * -3");
calculator.evaluate("5!");
calculator.evaluate("3! + 2!");
// 测试函数
std::cout << "\n--- 函数测试 ---" << std::endl;
calculator.evaluate("sin(0)");
calculator.evaluate("cos(0)");
calculator.evaluate("pow(2, 8)");
calculator.evaluate("sqrt(16)");
calculator.evaluate("abs(-5)");
calculator.evaluate("max(1, 5, 3, 9, 2)");
calculator.evaluate("min(1, 5, 3, 9, 2)");
calculator.evaluate("sum(1, 2, 3, 4, 5)");
calculator.evaluate("avg(1, 2, 3, 4, 5)");
// 测试复杂表达式
std::cout << "\n--- 复杂表达式测试 ---" << std::endl;
calculator.evaluate("sin(pi / 2) + cos(0) * 2");
calculator.evaluate("pow(2, 3) + sqrt(16) * max(1, 2, 3)");
calculator.evaluate("(x + y) * (x - y) / 2");
// 存储和重用表达式
std::cout << "\n--- 表达式存储测试 ---" << std::endl;
calculator.storeExpression("circle_area", "pi * r ^ 2");
calculator.setVariable("r", 5);
calculator.evaluateStored("circle_area");
calculator.storeExpression("quadratic", "(-b + sqrt(b ^ 2 - 4 * a * c)) / (2 * a)");
calculator.setVariable("a", 1);
calculator.setVariable("b", -3);
calculator.setVariable("c", 2);
calculator.evaluateStored("quadratic");
// 显示系统状态
calculator.displaySystemStatus();
std::cout << "\n=== 解释器模式测试结束 ===" << std::endl;
}
// 实战应用:自定义规则引擎
class SimpleRuleEngine {
private:
Context context_;
std::map<std::string, std::unique_ptr<Expression>> rules_;
std::vector<std::string> executionLog_;
public:
SimpleRuleEngine() {
std::cout << "⚖️ 创建简单规则引擎" << std::endl;
initializeDefaultFacts();
}
// 添加规则
void addRule(const std::string& ruleName, const std::string& condition) {
try {
ExpressionParser parser(condition, context_);
auto expr = parser.parse();
rules_[ruleName] = std::move(expr);
std::cout << "📝 添加规则: " << ruleName << " = " << condition << std::endl;
} catch (const std::exception& e) {
std::cout << "❌ 添加规则失败: " << e.what() << std::endl;
throw;
}
}
// 评估规则
bool evaluateRule(const std::string& ruleName) {
auto it = rules_.find(ruleName);
if (it == rules_.end()) {
throw std::runtime_error("未找到规则: " + ruleName);
}
double result = it->second->interpret(context_);
bool boolResult = result != 0.0; // 非零为真
std::string logEntry = "规则 '" + ruleName + "': " +
(boolResult ? "真" : "假") + " (数值: " +
std::to_string(result) + ")";
executionLog_.push_back(logEntry);
std::cout << "🔍 " << logEntry << std::endl;
return boolResult;
}
// 设置事实
void setFact(const std::string& fact, double value) {
context_.setVariable(fact, value);
std::cout << "📋 设置事实 " << fact << " = " << value << std::endl;
}
// 批量评估所有规则
void evaluateAllRules() {
std::cout << "\n🔍 评估所有规则 (" << rules_.size() << " 个)" << std::endl;
int trueCount = 0;
for (const auto& [ruleName, _] : rules_) {
try {
if (evaluateRule(ruleName)) {
trueCount++;
}
} catch (const std::exception& e) {
std::cout << "❌ 评估规则 '" << ruleName << "' 失败: " << e.what() << std::endl;
}
}
std::cout << "📊 规则评估统计: " << trueCount << "/" << rules_.size() << " 为真" << std::endl;
}
// 显示规则引擎状态
void displayRuleEngineStatus() const {
std::cout << "\n📊 规则引擎状态" << std::endl;
std::cout << "==============" << std::endl;
context_.display();
std::cout << "规则数量: " << rules_.size() << " 个" << std::endl;
for (const auto& [name, _] : rules_) {
std::cout << " • " << name << std::endl;
}
std::cout << "执行日志: " << executionLog_.size() << " 条" << std::endl;
for (const auto& log : executionLog_) {
std::cout << " • " << log << std::endl;
}
}
// 清除执行日志
void clearExecutionLog() {
executionLog_.clear();
std::cout << "🧹 清除执行日志" << std::endl;
}
private:
void initializeDefaultFacts() {
// 设置一些默认事实
setFact("true", 1.0);
setFact("false", 0.0);
setFact("yes", 1.0);
setFact("no", 0.0);
}
};
// 测试规则引擎
void testRuleEngine() {
std::cout << "\n=== 规则引擎测试开始 ===" << std::endl;
SimpleRuleEngine ruleEngine;
// 添加业务规则
ruleEngine.addRule("is_adult", "age >= 18");
ruleEngine.addRule("has_license", "driver_license == 1");
ruleEngine.addRule("can_drive", "is_adult && has_license");
ruleEngine.addRule("senior_discount", "age >= 65");
ruleEngine.addRule("student_discount", "age < 25 && student == 1");
ruleEngine.addRule("vip_discount", "vip_level >= 2 && purchase_amount > 1000");
ruleEngine.addRule("bulk_discount", "quantity >= 10 && unit_price >= 50");
// 设置事实
ruleEngine.setFact("age", 20);
ruleEngine.setFact("driver_license", 1);
ruleEngine.setFact("student", 1);
ruleEngine.setFact("vip_level", 1);
ruleEngine.setFact("purchase_amount", 500);
ruleEngine.setFact("quantity", 5);
ruleEngine.setFact("unit_price", 30);
// 评估规则
ruleEngine.evaluateAllRules();
// 显示状态
ruleEngine.displayRuleEngineStatus();
// 测试规则变化
std::cout << "\n--- 更新事实测试 ---" << std::endl;
ruleEngine.setFact("age", 16);
ruleEngine.setFact("vip_level", 3);
ruleEngine.setFact("purchase_amount", 1500);
ruleEngine.setFact("quantity", 15);
ruleEngine.clearExecutionLog();
ruleEngine.evaluateAllRules();
std::cout << "\n=== 规则引擎测试结束 ===" << std::endl;
}
// 高级应用:自定义语言解释器
class CustomLanguageInterpreter {
private:
Context context_;
std::map<std::string, std::unique_ptr<Expression>> macros_;
public:
CustomLanguageInterpreter() {
std::cout << "🌐 创建自定义语言解释器" << std::endl;
initializeLanguage();
}
// 解释自定义语言语句
double interpret(const std::string& statement) {
std::cout << "\n🔍 解释语句: " << statement << std::endl;
// 简单的语句类型识别
if (statement.find('=') != std::string::npos) {
return interpretAssignment(statement);
} else if (statement.find("define") == 0) {
return interpretMacroDefinition(statement);
} else {
return interpretExpression(statement);
}
}
// 显示语言状态
void displayLanguageStatus() const {
std::cout << "\n📊 自定义语言状态" << std::endl;
std::cout << "================" << std::endl;
context_.display();
std::cout << "宏定义: " << macros_.size() << " 个" << std::endl;
for (const auto& [name, _] : macros_) {
std::cout << " • " << name << std::endl;
}
}
private:
double interpretAssignment(const std::string& statement) {
size_t equalsPos = statement.find('=');
std::string varName = statement.substr(0, equalsPos);
std::string expressionStr = statement.substr(equalsPos + 1);
// 去除空格
varName.erase(0, varName.find_first_not_of(" \t"));
varName.erase(varName.find_last_not_of(" \t") + 1);
ExpressionParser parser(expressionStr, context_);
auto expr = parser.parse();
double value = expr->interpret(context_);
context_.setVariable(varName, value);
std::cout << "💾 赋值: " << varName << " = " << value << std::endl;
return value;
}
double interpretMacroDefinition(const std::string& statement) {
// 简单实现:define macro_name = expression
size_t defineEnd = statement.find(' ', 7); // "define ".length()
if (defineEnd == std::string::npos) {
throw std::runtime_error("无效的宏定义语法");
}
std::string macroName = statement.substr(7, defineEnd - 7);
size_t equalsPos = statement.find('=', defineEnd);
if (equalsPos == std::string::npos) {
throw std::runtime_error("宏定义中缺少等号");
}
std::string expressionStr = statement.substr(equalsPos + 1);
ExpressionParser parser(expressionStr, context_);
auto expr = parser.parse();
macros_[macroName] = std::move(expr);
std::cout << "📖 定义宏: " << macroName << " = " << expressionStr << std::endl;
return 0.0;
}
double interpretExpression(const std::string& expressionStr) {
ExpressionParser parser(expressionStr, context_);
auto expr = parser.parse();
double result = expr->interpret(context_);
std::cout << "🔢 表达式结果: " << result << std::endl;
return result;
}
void initializeLanguage() {
// 初始化语言内置元素
context_.setVariable("true", 1.0);
context_.setVariable("false", 0.0);
context_.setVariable("PI", 3.141592653589793);
context_.setVariable("E", 2.718281828459045);
}
};
// 测试自定义语言
void testCustomLanguage() {
std::cout << "\n=== 自定义语言测试开始 ===" << std::endl;
CustomLanguageInterpreter languageInterpreter;
// 测试赋值语句
std::cout << "\n--- 测试赋值语句 ---" << std::endl;
languageInterpreter.interpret("x = 10");
languageInterpreter.interpret("y = 20");
languageInterpreter.interpret("z = x + y * 2");
// 测试表达式计算
std::cout << "\n--- 测试表达式计算 ---" << std::endl;
languageInterpreter.interpret("x + y");
languageInterpreter.interpret("(x + y) * z / 2");
languageInterpreter.interpret("sin(PI / 2)");
// 测试宏定义
std::cout << "\n--- 测试宏定义 ---" << std::endl;
languageInterpreter.interpret("define circle_area = PI * r ^ 2");
languageInterpreter.interpret("r = 5");
languageInterpreter.interpret("circle_area");
languageInterpreter.interpret("define quadratic = (-b + sqrt(b^2 - 4*a*c)) / (2*a)");
languageInterpreter.interpret("a = 1");
languageInterpreter.interpret("b = -5");
languageInterpreter.interpret("c = 6");
languageInterpreter.interpret("quadratic");
// 显示语言状态
languageInterpreter.displayLanguageStatus();
std::cout << "\n=== 自定义语言测试结束 ===" << std::endl;
}
int main() {
std::cout << "🌈 设计模式武林大会 - 解释器模式演示 🌈" << std::endl;
std::cout << "=====================================" << std::endl;
// 测试解释器模式
testInterpreterPattern();
// 测试规则引擎
testRuleEngine();
// 测试自定义语言
testCustomLanguage();
std::cout << "\n🎉 解释器模式演示全部完成!" << std::endl;
std::cout << "✨ 23种设计模式全部讲解完毕! ✨" << std::endl;
return 0;
}
解释器模式的武学心得
适用场景
- 简单语言解释:当有一个简单的语言需要解释执行,并且可以将语言中的句子表示为一棵抽象语法树时
- 重复问题:当一个特定类型的问题频繁发生,并且可以表示为一种语言时
- 语法简单:当语言的文法比较简单时(复杂的文法会导致类层次庞大,难以维护)
- 效率非关键:当效率不是关键问题时(解释器模式通常效率较低)
优点
- 易于扩展:很容易改变和扩展文法,因为使用类来表示文法规则
- 易于实现:实现文法很简单,可以逐步定义各个表达式类
- 增加新方式:可以很容易地增加新的解释表达式的方式
- 易于维护:每个文法规则都对应一个类,结构清晰
缺点
- 复杂文法难维护:对于复杂的文法,文法的类层次会变得庞大而难以管理
- 执行效率较低:解释器模式使用了大量的递归和循环调用,效率可能较低
- 应用场景有限:实际应用场景相对较少,通常用于简单的语言或 DSL
武林高手的点评
Composite 赞叹道:"Interpreter 兄的语言解释确实精妙!能够如此优雅地将语言表示为抽象语法树,这在需要解释简单语言的系统中确实无人能及。"
Visitor 也点头称赞:"Interpreter 兄专注于语言的解释,而我更关注对复杂结构的操作。我们都可以处理树形结构,但关注点不同。"
Interpreter 谦虚回应:"诸位过奖了。每个模式都有其适用场景。在需要解释简单语言时,我的解释器模式确实能发挥重要作用。但在需要处理复杂对象结构时,Visitor 兄的方法更加合适。"
终章总结
架构老人缓缓站起,目光扫过在场的23位设计模式高手,脸上露出了欣慰的笑容。
"诸位!经过这23章的论剑,设计模式的智慧已经完整地展现在大家面前。从创建型的造化万物,到结构型的勾连万象,再到行为型的运筹帷幄,每一种模式都是先贤们智慧的结晶。"
"记住,设计模式不是银弹,而是工具箱中的工具。真正的武林高手,懂得在合适的时机使用合适的工具,懂得模式的组合与变通,懂得根据具体问题灵活运用。"
"软件工程的江湖永远在变化,但设计模式的智慧将指引我们写出更加优雅、灵活、可维护的代码。愿诸位将这份智慧传承下去,在各自的江湖中创造传奇!"
23位高手齐声应和,声音响彻云霄。设计模式武林大会在智慧的光芒中圆满落幕,但设计模式的传承与应用,将在软件工程的江湖中永远继续......
23种设计模式全部讲解完毕!感谢您的阅读,愿设计模式的智慧指引您的编程之路!