当前位置: 首页 > news >正文

第二十三章:解析天书,诠释法则——Interpreter的解释艺术

第二十三章:解析天书,诠释法则——Interpreter的解释艺术

风云际会,解释器登场

在Memento展示完他那精妙的状态记忆艺术后,Interpreter正在解析一段古老的符文的语言学家走出。

"Memento兄的状态记忆确实精妙,"Interpreter专注地说道,“但在需要解释特定语言或文法时,需要更加专业的解释机制。我的解释器模式,允许你定义语言的文法,并提供一个解释器来解释语言中的句子。对于简单的文法,解释器模式可以优雅地处理解释任务。”

架构老人眼中闪过赞许之色:“善!Interpreter,就请你为大家展示这解释艺术的精妙所在。”

解释器模式的核心要义

Interpreter面向众人,开始阐述他的武学真谛:

“在我的解释器模式中,主要包含几个核心角色:”

AbstractExpression(抽象表达式):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。”

TerminalExpression(终结符表达式):实现与文法中的终结符相关联的解释操作。一个句子中的每个终结符需要该类的一个实例。”

NonterminalExpression(非终结符表达式):对文法中的每一条规则都需要一个具体的非终结符表达式类。这些类通常包含其他表达式的引用(可以是终结符,也可以是非终结符),然后递归地调用这些表达式进行解释。”

Context(上下文):包含解释器之外的一些全局信息。”

Client(客户端):构建表示该文法定义的语言中一个特定句子的抽象语法树。该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成。然后调用解释操作。”

"其精妙之处在于,"Interpreter继续道,“我将一个语言表示为一个抽象语法树,并定义一个解释器,通过递归的方式解释执行这些语法树节点。这样,就可以很容易地改变和扩展文法。”

C++实战:数学表达式计算器

"且让我以一个数学表达式计算器为例,展示解释器模式的实战应用。"Interpreter说着,手中凝聚出一道道代码流光。

基础框架搭建

首先,Interpreter定义了表达式和上下文的接口:

#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展示了各种数学表达式的具体实现:

// 终结符表达式:数字
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展示了如何将字符串解析为表达式树:

// 表达式解析器
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继续展示更复杂的解释器模式应用:

// 高级计算器系统
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 = expressionsize_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种设计模式全部讲解完毕!感谢您的阅读,愿设计模式的智慧指引您的编程之路!

http://www.dtcms.com/a/452801.html

相关文章:

  • 论文阅读-FoundationStereo
  • bug日记
  • 大数据集群环境搭建(Ubantu)
  • 深入浅出 HarmonyOS 应用开发:ArkTS 语法精要与实践
  • 用 Python+OpenCV 实现实时文档扫描:从摄像头捕捉到透视矫正全流程
  • 普陀做网站公司任丘市建设局网站
  • 前端框架篇——VueReact篇
  • R语言从入门到精通Day4之【数据结构】
  • JavaScript快速入门_javascript入门教程
  • 有几家做网站的公司易贝跨境电商平台
  • 基于websocket的多用户网页五子棋(六)
  • 月光与饼:Python 爱情月饼可视化
  • 【C++】STL有序关联容器的双生花:set/multiset 和 map/multimap 使用指南
  • 迷你论坛项目
  • 【C++STL】一文掌握 String 核心接口:从基础到实用!
  • 长沙宁乡建设网站网站本地环境搭建
  • 从以太网到多个 CAN 网络的网关
  • 网站做弹窗怀化职院网站
  • ros2 功能包 package.xml 结构详细解释
  • ros2 功能包 CMakeLists.txt 结构详细解释
  • 【Python】小练习-考察变量作用域问题
  • YOLO算法原理详解系列 第007期-YOLOv7 算法原理详解
  • 【C++贪心】P8087 『JROI-5』Interval|普及+
  • C++知识点总结用于打算法
  • 【算法】二分查找(一)朴素二分
  • 干货>肉夹馍词嵌入方案(embedding方案),适合资源受限、要求可解释、领域边界清晰的应用场景
  • PDML 不能和rebuild partition index同时运行
  • 网站目录管理模板做一个网站一般要多少钱
  • 对于力扣2025,10,7的每日的一点反思(非递归并查集写法)
  • Elasticsearch、OpenSearch 与 Easysearch:三代搜索引擎的演化与抉择