解释器模式及优化

解释器模式(Interpreter Pattern)是一种行为型设计模式,核心是将特定语言的语法解析为一个抽象语法树(AST),然后通过遍历这棵树来解释执行相应的操作。这种模式通过将语法规则表示为类的层次结构,使得我们可以通过组合这些类来解析和执行复杂的语法结构。

一、介绍

核心角色
  1. 抽象表达式(Abstract Expression) 声明一个抽象的解释操作方法,是所有具体表达式的父类。
  2. 终结符表达式(Terminal Expression) 实现与语法规则中终结符相关的解释操作,通常是语法中的基本元素。
  3. 非终结符表达式(Non-terminal Expression) 实现与语法规则中非终结符相关的解释操作,通常由多个终结符或非终结符组成。 |
  4. 上下文(Context) 存储解释器的全局信息,提供解释过程中需要的数据或方法。
  5. 客户端(Client) 根据语法规则构建抽象语法树,调用解释操作执行解析。
优点
  1. 易于扩展和修改语法
    • 每一条语法规则都被封装在一个类中,添加新的规则只需添加新的类
    • 修改现有规则只需修改对应的表达式类,符合开闭原则
  2. 语法规则清晰可见
    • 将语法规则表示为类的层次结构,使语法结构更加清晰易懂
    • 便于开发人员理解和维护复杂的语法解析逻辑
  3. 可组合性强
    • 可以通过组合简单的表达式来构建复杂的语法结构
    • 利用递归组合可以表示任意复杂的语法规则
  4. 便于实现语法分析
    • 将语法解析过程分解为多个小步骤,每个步骤由特定的表达式类处理
    • 降低了复杂语法解析的实现难度
适用场景
  1. 需要解析和执行特定语言的场景
    • 自定义领域特定语言(DSL),如配置文件解析器、查询语言等
    • 简单的脚本语言解释器或表达式计算器
  2. 语法规则相对简单的场景
    • 当语法规则不复杂且易于表示为类的层次结构时
    • 例如:简单的数学表达式、正则表达式引擎、路由规则解析
  3. 需要频繁扩展语法规则的场景
    • 当需要不断添加新的语法规则,且这些规则可以独立扩展时
    • 例如:过滤器表达式、条件判断语句解析器
  4. 重复出现的问题可以用简单语言描述的场景
    • 当系统中存在许多重复的操作,这些操作可以用一种简单的语言来描述和执行时
    • 例如:报表生成器中的数据处理规则、工作流引擎中的流程定义

二、实现

以一个简单布尔表达式解析器的为例,支持逻辑运算(与、或、非)和变量

cpp 复制代码
#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
应用场景
  1. 表达式解析器
    • 计算器中的数学表达式解析
    • 电子表格中的公式计算(如Excel公式)
  2. 规则引擎
    • 业务规则引擎中的条件表达式解析
    • 权限控制系统中的访问规则判断
  3. 查询语言
    • 数据库查询语句(SQL)的部分解析
    • 搜索引擎中的过滤条件解析
  4. 配置文件解析
    • 自定义配置文件格式的解析器
    • 构建工具中的依赖规则解析
  5. 自然语言处理
    • 简单的自然语言命令解析
    • 聊天机器人中的意图识别规则

三、优化

优化点
  1. 增强功能完整性
    • 添加了异或(XOR)运算支持,丰富了逻辑运算类型
    • 实现了操作符优先级:NOT > AND > XOR > OR,符合常规逻辑运算规则
    • 增加了短路求值优化:AND在左操作数为false时不再计算右操作数,OR在左操作数为true时不再计算右操作数
  2. 完善的错误处理
    • 提供详细的语法错误信息,包含行列位置,便于调试
    • 检查变量是否已定义,避免使用未初始化的变量
    • 验证表达式结构的有效性(如确保二元操作符有两个操作数)
  3. 增强的表达式分析能力
    • 添加getVariables()方法,可提取表达式中所有使用的变量
    • 实现真值表生成功能,便于验证逻辑表达式的正确性
    • 提供ExpressionEvaluator类封装评估功能,支持变量批量设置
  4. 扩展性提升
    • 所有表达式类实现clone()方法,支持表达式的复制
    • 使用ExpressionType枚举明确标识表达式类型
    • 解析器支持静态parse()方法,简化使用流程
  5. 用户体验优化
    • 格式化输出真值表,清晰展示所有变量组合及结果
    • 提供更友好的语法树表示
    • 支持下划线作为变量名的一部分,符合常见命名习惯
cpp 复制代码
#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^varCount
        for (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;
}
优化后的优势
  1. 更贴近实际应用
    • 完善的错误处理机制使其可以应用于生产环境
    • 短路求值等优化提升了执行效率
  2. 更强的分析能力
    • 变量提取和真值表生成有助于理解和验证复杂表达式
    • 适合用于规则验证、逻辑教学等场景
  3. 更好的可维护性
    • 清晰的类层次结构和职责划分
    • 详细的错误信息简化了调试过程
  4. 更高的灵活性
    • 支持表达式克隆,便于构建复杂的表达式组合
    • 易于扩展更多的逻辑运算符
相关推荐
ajassi20002 分钟前
开源 C++ QT Widget 开发(七)线程--多线程及通讯
linux·c++·qt·开源
秋难降8 分钟前
代码界的 “建筑师”:建造者模式,让复杂对象构建井然有序
java·后端·设计模式
mit6.82424 分钟前
8.27 网格memo
c++·算法
jeffery89232 分钟前
4056:【GESP2403八级】接竹竿
数据结构·c++·算法
Forward♞37 分钟前
Qt——界面美化 QSS
开发语言·c++·qt
岁忧3 小时前
(LeetCode 每日一题) 498. 对角线遍历 (矩阵、模拟)
java·c++·算法·leetcode·矩阵·go
kyle~4 小时前
C/C++---前缀和(Prefix Sum)
c语言·c++·算法
##学无止境##6 小时前
Java设计模式-观察者模式
java·观察者模式·设计模式
YxVoyager6 小时前
【C++标准库】<ios>详解基于流的 I/O
c语言·c++