解释器模式及优化
解释器模式(Interpreter Pattern)是一种行为型设计模式,核心是将特定语言的语法解析为一个抽象语法树(AST),然后通过遍历这棵树来解释执行相应的操作。这种模式通过将语法规则表示为类的层次结构,使得我们可以通过组合这些类来解析和执行复杂的语法结构。
一、介绍
核心角色
- 抽象表达式(Abstract Expression) 声明一个抽象的解释操作方法,是所有具体表达式的父类。
- 终结符表达式(Terminal Expression) 实现与语法规则中终结符相关的解释操作,通常是语法中的基本元素。
- 非终结符表达式(Non-terminal Expression) 实现与语法规则中非终结符相关的解释操作,通常由多个终结符或非终结符组成。 |
- 上下文(Context) 存储解释器的全局信息,提供解释过程中需要的数据或方法。
- 客户端(Client) 根据语法规则构建抽象语法树,调用解释操作执行解析。
优点
- 易于扩展和修改语法
- 每一条语法规则都被封装在一个类中,添加新的规则只需添加新的类
- 修改现有规则只需修改对应的表达式类,符合开闭原则
- 语法规则清晰可见
- 将语法规则表示为类的层次结构,使语法结构更加清晰易懂
- 便于开发人员理解和维护复杂的语法解析逻辑
- 可组合性强
- 可以通过组合简单的表达式来构建复杂的语法结构
- 利用递归组合可以表示任意复杂的语法规则
- 便于实现语法分析
- 将语法解析过程分解为多个小步骤,每个步骤由特定的表达式类处理
- 降低了复杂语法解析的实现难度
适用场景
- 需要解析和执行特定语言的场景
- 自定义领域特定语言(DSL),如配置文件解析器、查询语言等
- 简单的脚本语言解释器或表达式计算器
- 语法规则相对简单的场景
- 当语法规则不复杂且易于表示为类的层次结构时
- 例如:简单的数学表达式、正则表达式引擎、路由规则解析
- 需要频繁扩展语法规则的场景
- 当需要不断添加新的语法规则,且这些规则可以独立扩展时
- 例如:过滤器表达式、条件判断语句解析器
- 重复出现的问题可以用简单语言描述的场景
- 当系统中存在许多重复的操作,这些操作可以用一种简单的语言来描述和执行时
- 例如:报表生成器中的数据处理规则、工作流引擎中的流程定义
二、实现
以一个简单布尔表达式解析器的为例,支持逻辑运算(与、或、非)和变量
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <stdexcept>
#include <cctype>
#include <algorithm>// 上下文:存储变量值和解析状态
class Context {
private:std::unordered_map<std::string, bool> variables_; // 变量映射表std::string expression_; // 原始表达式size_t position_; // 当前解析位置public:explicit Context(std::string expression) : expression_(std::move(expression)), position_(0) {}// 设置变量值void setVariable(const std::string& name, bool value) {variables_[name] = value;}// 获取变量值bool getVariable(const std::string& name) const {auto it = variables_.find(name);if (it == variables_.end()) {throw std::runtime_error("未定义的变量: " + name);}return it->second;}// 消费当前字符并前进char consume() {if (position_ < expression_.size()) {return expression_[position_++];}return '\0';}// 查看当前字符但不消费char peek() const {if (position_ < expression_.size()) {return expression_[position_];}return '\0';}// 跳过空白字符void skipWhitespace() {while (std::isspace(peek())) {consume();}}// 解析标识符(变量名)std::string parseIdentifier() {skipWhitespace();std::string id;if (!std::isalpha(peek())) {throw std::runtime_error("预期变量名,却遇到: " + std::string(1, peek()));}while (std::isalnum(peek())) {id += consume();}return id;}// 检查是否到达表达式末尾bool isAtEnd() const {return position_ >= expression_.size();}// 获取原始表达式const std::string& getExpression() const {return expression_;}
};// 抽象表达式接口
class Expression {
public:virtual ~Expression() = default;virtual bool interpret(const Context& context) const = 0;virtual std::string toString() const = 0;
};// 终结符表达式:变量
class VariableExpression : public Expression {
private:std::string name_;public:explicit VariableExpression(std::string name) : name_(std::move(name)) {}bool interpret(const Context& context) const override {return context.getVariable(name_);}std::string toString() const override {return name_;}
};// 终结符表达式:布尔常量(true/false)
class ConstantExpression : public Expression {
private:bool value_;public:explicit ConstantExpression(bool value) : value_(value) {}bool interpret(const Context& /*context*/) const override {return value_;}std::string toString() const override {return value_ ? "true" : "false";}
};// 非终结符表达式:逻辑非(NOT)
class NotExpression : public Expression {
private:std::unique_ptr<Expression> operand_;public:explicit NotExpression(std::unique_ptr<Expression> operand): operand_(std::move(operand)) {}bool interpret(const Context& context) const override {return !operand_->interpret(context);}std::string toString() const override {return "NOT(" + operand_->toString() + ")";}
};// 非终结符表达式:逻辑与(AND)
class AndExpression : public Expression {
private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;public:AndExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {}bool interpret(const Context& context) const override {return left_->interpret(context) && right_->interpret(context);}std::string toString() const override {return "(" + left_->toString() + " AND " + right_->toString() + ")";}
};// 非终结符表达式:逻辑或(OR)
class OrExpression : public Expression {
private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;public:OrExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {}bool interpret(const Context& context) const override {return left_->interpret(context) || right_->interpret(context);}std::string toString() const override {return "(" + left_->toString() + " OR " + right_->toString() + ")";}
};// 表达式解析器(构建抽象语法树)
class BooleanParser {
private:// 解析基本因子(变量、常量或括号表达式)std::unique_ptr<Expression> parseFactor(Context& context) {context.skipWhitespace();char current = context.peek();if (current == '(') {// 解析括号内的表达式context.consume(); // 消耗 '('auto expr = parseExpression(context);context.skipWhitespace();if (context.consume() != ')') {throw std::runtime_error("缺少右括号");}return expr;} else if (current == '!') {// 解析非运算context.consume(); // 消耗 '!'return std::make_unique<NotExpression>(parseFactor(context));}else if (std::isalpha(current)) {// 解析变量或常量(true/false)std::string id = context.parseIdentifier();std::transform(id.begin(), id.end(), id.begin(), ::tolower);if (id == "true") {return std::make_unique<ConstantExpression>(true);}else if (id == "false") {return std::make_unique<ConstantExpression>(false);}else {return std::make_unique<VariableExpression>(id);}}throw std::runtime_error("语法错误,遇到意外字符: " + std::string(1, current));}// 解析与运算(优先级高于或运算)std::unique_ptr<Expression> parseAndExpression(Context& context) {auto expr = parseFactor(context);context.skipWhitespace();while (context.peek() == '&') {// 检查是否是 && 操作符if (context.consume() == '&' && context.peek() == '&') {context.consume(); // 消耗第二个 &auto right = parseFactor(context);expr = std::make_unique<AndExpression>(std::move(expr), std::move(right));context.skipWhitespace();}else {throw std::runtime_error("预期 && 操作符");}}return expr;}// 解析或运算(优先级低于与运算)std::unique_ptr<Expression> parseExpression(Context& context) {auto expr = parseAndExpression(context);context.skipWhitespace();while (context.peek() == '|') {// 检查是否是 || 操作符if (context.consume() == '|' && context.peek() == '|') {context.consume(); // 消耗第二个 |auto right = parseAndExpression(context);expr = std::make_unique<OrExpression>(std::move(expr), std::move(right));context.skipWhitespace();}else {throw std::runtime_error("预期 || 操作符");}}return expr;}public:// 解析表达式字符串并返回抽象语法树std::unique_ptr<Expression> parse(Context& context) {auto expr = parseExpression(context);if (!context.isAtEnd()) {throw std::runtime_error("表达式解析不完整,剩余字符: " + context.getExpression().substr(context.peek()));}return expr;}
};// 客户端代码
int main() {try {// 测试1: 基本逻辑运算{Context context("true && !false || (false && true)");BooleanParser parser;auto expr = parser.parse(context);std::cout << "表达式1: " << context.getExpression() << std::endl;std::cout << "语法树1: " << expr->toString() << std::endl;std::cout << "结果1: " << (expr->interpret(context) ? "true" : "false") << "\n" << std::endl;}// 测试2: 带变量的表达式{Context context("a && (b || !c)");// 设置变量值context.setVariable("a", true);context.setVariable("b", false);context.setVariable("c", true);BooleanParser parser;auto expr = parser.parse(context);std::cout << "表达式2: " << context.getExpression() << std::endl;std::cout << "变量值: a=true, b=false, c=true" << std::endl;std::cout << "语法树2: " << expr->toString() << std::endl;std::cout << "结果2: " << (expr->interpret(context) ? "true" : "false") << "\n" << std::endl;}// 测试3: 复杂表达式{Context context("!(x || y) && z");context.setVariable("x", false);context.setVariable("y", false);context.setVariable("z", true);BooleanParser parser;auto expr = parser.parse(context);std::cout << "表达式3: " << context.getExpression() << std::endl;std::cout << "变量值: x=false, y=false, z=true" << std::endl;std::cout << "语法树3: " << expr->toString() << std::endl;std::cout << "结果3: " << (expr->interpret(context) ? "true" : "false") << std::endl;}} catch (const std::exception& e) {std::cerr << "错误: " << e.what() << std::endl;return 1;}return 0;
}
输出结果
表达式1: true && !false || (false && true)
语法树1: ((true AND NOT(false)) OR (false AND true))
结果1: true表达式2: a && (b || !c)
变量值: a=true, b=false, c=true
语法树2: (a AND (b OR NOT(c)))
结果2: false表达式3: !(x || y) && z
变量值: x=false, y=false, z=true
语法树3: (NOT((x OR y)) AND z)
结果3: true
应用场景
- 表达式解析器
- 计算器中的数学表达式解析
- 电子表格中的公式计算(如Excel公式)
- 规则引擎
- 业务规则引擎中的条件表达式解析
- 权限控制系统中的访问规则判断
- 查询语言
- 数据库查询语句(SQL)的部分解析
- 搜索引擎中的过滤条件解析
- 配置文件解析
- 自定义配置文件格式的解析器
- 构建工具中的依赖规则解析
- 自然语言处理
- 简单的自然语言命令解析
- 聊天机器人中的意图识别规则
三、优化
优化点
- 增强功能完整性
- 添加了异或(XOR)运算支持,丰富了逻辑运算类型
- 实现了操作符优先级:NOT > AND > XOR > OR,符合常规逻辑运算规则
- 增加了短路求值优化:
AND
在左操作数为false
时不再计算右操作数,OR
在左操作数为true
时不再计算右操作数
- 完善的错误处理
- 提供详细的语法错误信息,包含行列位置,便于调试
- 检查变量是否已定义,避免使用未初始化的变量
- 验证表达式结构的有效性(如确保二元操作符有两个操作数)
- 增强的表达式分析能力
- 添加
getVariables()
方法,可提取表达式中所有使用的变量 - 实现真值表生成功能,便于验证逻辑表达式的正确性
- 提供
ExpressionEvaluator
类封装评估功能,支持变量批量设置
- 添加
- 扩展性提升
- 所有表达式类实现
clone()
方法,支持表达式的复制 - 使用
ExpressionType
枚举明确标识表达式类型 - 解析器支持静态
parse()
方法,简化使用流程
- 所有表达式类实现
- 用户体验优化
- 格式化输出真值表,清晰展示所有变量组合及结果
- 提供更友好的语法树表示
- 支持下划线作为变量名的一部分,符合常见命名习惯
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <stdexcept>
#include <cctype>
#include <algorithm>
#include <sstream>
#include <iomanip>// 表达式类型枚举
enum class ExpressionType {VARIABLE,CONSTANT,NOT,AND,OR,XOR
};// 上下文:存储变量值和解析状态
class Context {
private:std::unordered_map<std::string, bool> variables_; // 变量映射表std::string expression_; // 原始表达式size_t position_; // 当前解析位置size_t line_; // 当前行号size_t column_; // 当前列号public:explicit Context(std::string expression) : expression_(std::move(expression)), position_(0), line_(1), column_(1) {}// 设置变量值void setVariable(const std::string& name, bool value) {variables_[name] = value;}// 批量设置变量值void setVariables(const std::unordered_map<std::string, bool>& vars) {for (const auto& [name, value] : vars) {variables_[name] = value;}}// 获取变量值bool getVariable(const std::string& name) const {auto it = variables_.find(name);if (it == variables_.end()) {throw std::runtime_error("未定义的变量: " + name);}return it->second;}// 检查变量是否存在bool hasVariable(const std::string& name) const {return variables_.find(name) != variables_.end();}// 获取所有变量const std::unordered_map<std::string, bool>& getVariables() const {return variables_;}// 消费当前字符并前进char consume() {if (position_ < expression_.size()) {char c = expression_[position_++];if (c == '\n') {line_++;column_ = 1;} else {column_++;}return c;}return '\0';}// 查看当前字符但不消费char peek() const {if (position_ < expression_.size()) {return expression_[position_];}return '\0';}// 跳过空白字符void skipWhitespace() {while (std::isspace(peek())) {consume();}}// 解析标识符(变量名)std::string parseIdentifier() {skipWhitespace();std::string id;if (!std::isalpha(peek())) {throwSyntaxError("预期变量名,却遇到: " + std::string(1, peek()));}while (std::isalnum(peek()) || peek() == '_') {id += consume();}return id;}// 检查是否到达表达式末尾bool isAtEnd() const {return position_ >= expression_.size();}// 获取原始表达式const std::string& getExpression() const {return expression_;}// 获取当前位置信息std::string getPositionInfo() const {std::stringstream ss;ss << "行: " << line_ << ", 列: " << column_;return ss.str();}// 抛出语法错误[[noreturn]] void throwSyntaxError(const std::string& message) const {throw std::runtime_error("语法错误 (" + getPositionInfo() + "): " + message);}
};// 抽象表达式接口
class Expression {
public:virtual ~Expression() = default;virtual bool interpret(const Context& context) const = 0;virtual std::string toString() const = 0;virtual ExpressionType getType() const = 0;// 获取表达式中包含的所有变量virtual std::vector<std::string> getVariables() const {return {};}// 克隆表达式virtual std::unique_ptr<Expression> clone() const = 0;
};// 终结符表达式:变量
class VariableExpression : public Expression {
private:std::string name_;public:explicit VariableExpression(std::string name) : name_(std::move(name)) {}bool interpret(const Context& context) const override {return context.getVariable(name_);}std::string toString() const override {return name_;}ExpressionType getType() const override {return ExpressionType::VARIABLE;}std::vector<std::string> getVariables() const override {return {name_};}const std::string& getName() const {return name_;}std::unique_ptr<Expression> clone() const override {return std::make_unique<VariableExpression>(*this);}
};// 终结符表达式:布尔常量(true/false)
class ConstantExpression : public Expression {
private:bool value_;public:explicit ConstantExpression(bool value) : value_(value) {}bool interpret(const Context& /*context*/) const override {return value_;}std::string toString() const override {return value_ ? "true" : "false";}ExpressionType getType() const override {return ExpressionType::CONSTANT;}bool getValue() const {return value_;}std::unique_ptr<Expression> clone() const override {return std::make_unique<ConstantExpression>(*this);}
};// 非终结符表达式:逻辑非(NOT)
class NotExpression : public Expression {
private:std::unique_ptr<Expression> operand_;public:explicit NotExpression(std::unique_ptr<Expression> operand): operand_(std::move(operand)) {if (!operand_) {throw std::invalid_argument("NotExpression 需要一个操作数");}}bool interpret(const Context& context) const override {return !operand_->interpret(context);}std::string toString() const override {return "NOT(" + operand_->toString() + ")";}ExpressionType getType() const override {return ExpressionType::NOT;}std::vector<std::string> getVariables() const override {return operand_->getVariables();}const Expression* getOperand() const {return operand_.get();}std::unique_ptr<Expression> clone() const override {return std::make_unique<NotExpression>(operand_->clone());}
};// 非终结符表达式:逻辑与(AND)
class AndExpression : public Expression {
private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;public:AndExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {if (!left_ || !right_) {throw std::invalid_argument("AndExpression 需要两个操作数");}}bool interpret(const Context& context) const override {// 短路求值:如果左操作数为false,直接返回false,不计算右操作数if (!left_->interpret(context)) {return false;}return right_->interpret(context);}std::string toString() const override {return "(" + left_->toString() + " AND " + right_->toString() + ")";}ExpressionType getType() const override {return ExpressionType::AND;}std::vector<std::string> getVariables() const override {auto vars = left_->getVariables();auto rightVars = right_->getVariables();vars.insert(vars.end(), rightVars.begin(), rightVars.end());// 去重std::sort(vars.begin(), vars.end());vars.erase(std::unique(vars.begin(), vars.end()), vars.end());return vars;}const Expression* getLeft() const {return left_.get();}const Expression* getRight() const {return right_.get();}std::unique_ptr<Expression> clone() const override {return std::make_unique<AndExpression>(left_->clone(), right_->clone());}
};// 非终结符表达式:逻辑或(OR)
class OrExpression : public Expression {
private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;public:OrExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {if (!left_ || !right_) {throw std::invalid_argument("OrExpression 需要两个操作数");}}bool interpret(const Context& context) const override {// 短路求值:如果左操作数为true,直接返回true,不计算右操作数if (left_->interpret(context)) {return true;}return right_->interpret(context);}std::string toString() const override {return "(" + left_->toString() + " OR " + right_->toString() + ")";}ExpressionType getType() const override {return ExpressionType::OR;}std::vector<std::string> getVariables() const override {auto vars = left_->getVariables();auto rightVars = right_->getVariables();vars.insert(vars.end(), rightVars.begin(), rightVars.end());// 去重std::sort(vars.begin(), vars.end());vars.erase(std::unique(vars.begin(), vars.end()), vars.end());return vars;}const Expression* getLeft() const {return left_.get();}const Expression* getRight() const {return right_.get();}std::unique_ptr<Expression> clone() const override {return std::make_unique<OrExpression>(left_->clone(), right_->clone());}
};// 非终结符表达式:逻辑异或(XOR)
class XorExpression : public Expression {
private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;public:XorExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {if (!left_ || !right_) {throw std::invalid_argument("XorExpression 需要两个操作数");}}bool interpret(const Context& context) const override {bool leftVal = left_->interpret(context);bool rightVal = right_->interpret(context);return leftVal != rightVal; // 异或:不同为true,相同为false}std::string toString() const override {return "(" + left_->toString() + " XOR " + right_->toString() + ")";}ExpressionType getType() const override {return ExpressionType::XOR;}std::vector<std::string> getVariables() const override {auto vars = left_->getVariables();auto rightVars = right_->getVariables();vars.insert(vars.end(), rightVars.begin(), rightVars.end());// 去重std::sort(vars.begin(), vars.end());vars.erase(std::unique(vars.begin(), vars.end()), vars.end());return vars;}std::unique_ptr<Expression> clone() const override {return std::make_unique<XorExpression>(left_->clone(), right_->clone());}
};// 表达式解析器(构建抽象语法树)
class BooleanParser {
private:// 解析基本因子(变量、常量或括号表达式)std::unique_ptr<Expression> parseFactor(Context& context) {context.skipWhitespace();char current = context.peek();if (current == '(') {// 解析括号内的表达式context.consume(); // 消耗 '('auto expr = parseExpression(context);context.skipWhitespace();if (context.consume() != ')') {context.throwSyntaxError("缺少右括号");}return expr;} else if (current == '!') {// 解析非运算context.consume(); // 消耗 '!'return std::make_unique<NotExpression>(parseFactor(context));}else if (std::isalpha(current)) {// 解析变量或常量(true/false)std::string id = context.parseIdentifier();std::string lowerId = id;std::transform(lowerId.begin(), lowerId.end(), lowerId.begin(), ::tolower);if (lowerId == "true") {return std::make_unique<ConstantExpression>(true);}else if (lowerId == "false") {return std::make_unique<ConstantExpression>(false);}else {return std::make_unique<VariableExpression>(id);}}context.throwSyntaxError("遇到意外字符: " + std::string(1, current));}// 解析异或运算(优先级低于与运算,高于或运算)std::unique_ptr<Expression> parseXorExpression(Context& context) {auto expr = parseFactor(context);context.skipWhitespace();while (context.peek() == '^') {context.consume(); // 消耗 '^'auto right = parseFactor(context);expr = std::make_unique<XorExpression>(std::move(expr), std::move(right));context.skipWhitespace();}return expr;}// 解析与运算(优先级高于异或和或运算)std::unique_ptr<Expression> parseAndExpression(Context& context) {auto expr = parseXorExpression(context);context.skipWhitespace();while (context.peek() == '&') {// 检查是否是 && 操作符context.consume(); // 消耗第一个 &if (context.peek() == '&') {context.consume(); // 消耗第二个 &auto right = parseXorExpression(context);expr = std::make_unique<AndExpression>(std::move(expr), std::move(right));context.skipWhitespace();}else {context.throwSyntaxError("预期第二个 & 构成 && 操作符");}}return expr;}// 解析或运算(优先级最低)std::unique_ptr<Expression> parseExpression(Context& context) {auto expr = parseAndExpression(context);context.skipWhitespace();while (context.peek() == '|') {// 检查是否是 || 操作符context.consume(); // 消耗第一个 |if (context.peek() == '|') {context.consume(); // 消耗第二个 |auto right = parseAndExpression(context);expr = std::make_unique<OrExpression>(std::move(expr), std::move(right));context.skipWhitespace();}else {context.throwSyntaxError("预期第二个 | 构成 || 操作符");}}return expr;}public:// 解析表达式字符串并返回抽象语法树std::unique_ptr<Expression> parse(Context& context) {auto expr = parseExpression(context);if (!context.isAtEnd()) {context.throwSyntaxError("表达式解析不完整");}return expr;}// 解析表达式字符串(静态方法)static std::unique_ptr<Expression> parse(const std::string& expression) {Context context(expression);BooleanParser parser;return parser.parse(context);}
};// 表达式评估器:提供额外的评估功能
class ExpressionEvaluator {
private:std::unique_ptr<Expression> expression_;public:explicit ExpressionEvaluator(std::unique_ptr<Expression> expression): expression_(std::move(expression)) {if (!expression_) {throw std::invalid_argument("无效的表达式");}}// 使用提供的变量值评估表达式bool evaluate(const std::unordered_map<std::string, bool>& variables) const {Context context("");context.setVariables(variables);// 检查所有变量是否都已提供auto requiredVars = expression_->getVariables();for (const auto& var : requiredVars) {if (!context.hasVariable(var)) {throw std::runtime_error("缺少变量值: " + var);}}return expression_->interpret(context);}// 获取表达式中所有变量std::vector<std::string> getRequiredVariables() const {return expression_->getVariables();}// 生成表达式的字符串表示std::string getExpressionString() const {return expression_->toString();}// 获取表达式类型ExpressionType getExpressionType() const {return expression_->getType();}// 克隆评估器std::unique_ptr<ExpressionEvaluator> clone() const {return std::make_unique<ExpressionEvaluator>(expression_->clone());}// 打印真值表void printTruthTable() const {auto variables = getRequiredVariables();size_t varCount = variables.size();if (varCount > 5) {throw std::runtime_error("变量数量过多(>5),不适合生成真值表");}std::cout << "\n=== 真值表 ===" << std::endl;// 打印变量名for (const auto& var : variables) {std::cout << std::setw(6) << var;}std::cout << " | 结果" << std::endl;// 打印分隔线for (size_t i = 0; i < varCount; ++i) {std::cout << "------";}std::cout << "|------" << std::endl;// 生成所有可能的变量组合size_t totalCombinations = 1 << varCount; // 2^varCountfor (size_t i = 0; i < totalCombinations; ++i) {std::unordered_map<std::string, bool> vars;// 设置当前组合的变量值for (size_t j = 0; j < varCount; ++j) {bool value = (i & (1 << (varCount - j - 1))) != 0;vars[variables[j]] = value;std::cout << std::setw(6) << (value ? "true" : "false");}// 计算结果bool result = evaluate(vars);std::cout << " | " << std::setw(4) << (result ? "true" : "false") << std::endl;}}
};// 客户端代码
int main() {try {// 测试1: 基本逻辑运算(包含异或){std::string exprStr = "true && !false || (false && true) ^ true";auto expr = BooleanParser::parse(exprStr);ExpressionEvaluator evaluator(std::move(expr));std::cout << "表达式1: " << exprStr << std::endl;std::cout << "语法树1: " << evaluator.getExpressionString() << std::endl;std::cout << "结果1: " << (evaluator.evaluate({}) ? "true" : "false") << std::endl;}// 测试2: 带变量的表达式{std::string exprStr = "a && (b || !c)";auto expr = BooleanParser::parse(exprStr);ExpressionEvaluator evaluator(std::move(expr));std::cout << "\n表达式2: " << exprStr << std::endl;std::cout << "语法树2: " << evaluator.getExpressionString() << std::endl;std::unordered_map<std::string, bool> vars = {{"a", true}, {"b", false}, {"c", true}};std::cout << "变量值: a=true, b=false, c=true" << std::endl;std::cout << "结果2: " << (evaluator.evaluate(vars) ? "true" : "false") << std::endl;// 打印真值表evaluator.printTruthTable();}// 测试3: 复杂表达式与短路求值{std::string exprStr = "!(x || y) && z ^ (a || b)";auto expr = BooleanParser::parse(exprStr);ExpressionEvaluator evaluator(std::move(expr));std::cout << "\n表达式3: " << exprStr << std::endl;std::cout << "语法树3: " << evaluator.getExpressionString() << std::endl;std::unordered_map<std::string, bool> vars = {{"x", false}, {"y", false}, {"z", true},{"a", false}, {"b", false}};std::cout << "变量值: x=false, y=false, z=true, a=false, b=false" << std::endl;std::cout << "结果3: " << (evaluator.evaluate(vars) ? "true" : "false") << std::endl;}// 测试4: 错误处理测试(预期会抛出异常){std::cout << "\n测试错误处理:" << std::endl;try {BooleanParser::parse("a && (b || c"); // 缺少右括号} catch (const std::exception& e) {std::cout << "捕获预期错误: " << e.what() << std::endl;}try {auto expr = BooleanParser::parse("a || b");ExpressionEvaluator evaluator(std::move(expr));evaluator.evaluate({{"a", true}}); // 缺少变量b} catch (const std::exception& e) {std::cout << "捕获预期错误: " << e.what() << std::endl;}}} catch (const std::exception& e) {std::cerr << "\n发生错误: " << e.what() << std::endl;return 1;}return 0;
}
优化后的优势
- 更贴近实际应用
- 完善的错误处理机制使其可以应用于生产环境
- 短路求值等优化提升了执行效率
- 更强的分析能力
- 变量提取和真值表生成有助于理解和验证复杂表达式
- 适合用于规则验证、逻辑教学等场景
- 更好的可维护性
- 清晰的类层次结构和职责划分
- 详细的错误信息简化了调试过程
- 更高的灵活性
- 支持表达式克隆,便于构建复杂的表达式组合
- 易于扩展更多的逻辑运算符