解释器模式(Interpreter Pattern)是一种行为型设计模式,核心是将特定语言的语法解析为一个抽象语法树(AST),然后通过遍历这棵树来解释执行相应的操作。这种模式通过将语法规则表示为类的层次结构,使得我们可以通过组合这些类来解析和执行复杂的语法结构。
一、介绍
核心角色
- 抽象表达式(Abstract Expression) 声明一个抽象的解释操作方法,是所有具体表达式的父类。
- 终结符表达式(Terminal Expression) 实现与语法规则中终结符相关的解释操作,通常是语法中的基本元素。
- 非终结符表达式(Non-terminal Expression) 实现与语法规则中非终结符相关的解释操作,通常由多个终结符或非终结符组成。 |
- 上下文(Context) 存储解释器的全局信息,提供解释过程中需要的数据或方法。
- 客户端(Client) 根据语法规则构建抽象语法树,调用解释操作执行解析。
优点
- 易于扩展和修改语法
- 每一条语法规则都被封装在一个类中,添加新的规则只需添加新的类
- 修改现有规则只需修改对应的表达式类,符合开闭原则
- 语法规则清晰可见
- 将语法规则表示为类的层次结构,使语法结构更加清晰易懂
- 便于开发人员理解和维护复杂的语法解析逻辑
- 可组合性强
- 可以通过组合简单的表达式来构建复杂的语法结构
- 利用递归组合可以表示任意复杂的语法规则
- 便于实现语法分析
- 将语法解析过程分解为多个小步骤,每个步骤由特定的表达式类处理
- 降低了复杂语法解析的实现难度
适用场景
- 需要解析和执行特定语言的场景
- 自定义领域特定语言(DSL),如配置文件解析器、查询语言等
- 简单的脚本语言解释器或表达式计算器
- 语法规则相对简单的场景
- 当语法规则不复杂且易于表示为类的层次结构时
- 例如:简单的数学表达式、正则表达式引擎、路由规则解析
- 需要频繁扩展语法规则的场景
- 当需要不断添加新的语法规则,且这些规则可以独立扩展时
- 例如:过滤器表达式、条件判断语句解析器
- 重复出现的问题可以用简单语言描述的场景
- 当系统中存在许多重复的操作,这些操作可以用一种简单的语言来描述和执行时
- 例如:报表生成器中的数据处理规则、工作流引擎中的流程定义
二、实现
以一个简单布尔表达式解析器的为例,支持逻辑运算(与、或、非)和变量
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
应用场景
- 表达式解析器
- 计算器中的数学表达式解析
- 电子表格中的公式计算(如Excel公式)
- 规则引擎
- 业务规则引擎中的条件表达式解析
- 权限控制系统中的访问规则判断
- 查询语言
- 数据库查询语句(SQL)的部分解析
- 搜索引擎中的过滤条件解析
- 配置文件解析
- 自定义配置文件格式的解析器
- 构建工具中的依赖规则解析
- 自然语言处理
- 简单的自然语言命令解析
- 聊天机器人中的意图识别规则
三、优化
优化点
- 增强功能完整性
- 添加了异或(XOR)运算支持,丰富了逻辑运算类型
- 实现了操作符优先级:NOT > AND > XOR > OR,符合常规逻辑运算规则
- 增加了短路求值优化:
AND
在左操作数为false
时不再计算右操作数,OR
在左操作数为true
时不再计算右操作数
- 完善的错误处理
- 提供详细的语法错误信息,包含行列位置,便于调试
- 检查变量是否已定义,避免使用未初始化的变量
- 验证表达式结构的有效性(如确保二元操作符有两个操作数)
- 增强的表达式分析能力
- 添加
getVariables()
方法,可提取表达式中所有使用的变量 - 实现真值表生成功能,便于验证逻辑表达式的正确性
- 提供
ExpressionEvaluator
类封装评估功能,支持变量批量设置
- 添加
- 扩展性提升
- 所有表达式类实现
clone()
方法,支持表达式的复制 - 使用
ExpressionType
枚举明确标识表达式类型 - 解析器支持静态
parse()
方法,简化使用流程
- 所有表达式类实现
- 用户体验优化
- 格式化输出真值表,清晰展示所有变量组合及结果
- 提供更友好的语法树表示
- 支持下划线作为变量名的一部分,符合常见命名习惯
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;
}
优化后的优势
- 更贴近实际应用
- 完善的错误处理机制使其可以应用于生产环境
- 短路求值等优化提升了执行效率
- 更强的分析能力
- 变量提取和真值表生成有助于理解和验证复杂表达式
- 适合用于规则验证、逻辑教学等场景
- 更好的可维护性
- 清晰的类层次结构和职责划分
- 详细的错误信息简化了调试过程
- 更高的灵活性
- 支持表达式克隆,便于构建复杂的表达式组合
- 易于扩展更多的逻辑运算符