解析器模式(Interpreter Pattern)是一种行为设计模式,它定义了一种语言的文法表示,并定义一个解释器来解释该语言中的句子。解析器模式通常用于设计一个简单的语言或表达式求值系统。
1.问题分析
解析器模式主要解决的问题是:如何为一种语言定义一个文法,并且如何解释该语言中的句子。它适用于以下场景:
- 需要解释一种语言的句子
- 需要将一个复杂的表达式分解为更简单的子表达式,并逐个解释
2.实现步骤
- 定义文法规则:确定语言的文法规则,并将其表示为类。
- 创建抽象表达式类:定义一个抽象类,包含一个解释方法。
- 创建具体表达式类:为文法中的每个规则创建具体的表达式类,实现解释方法。
- 构建语法树:根据具体的表达式类构建语法树。
- 解释表达式:通过遍历语法树来解释表达式。
3.代码示例
3.1.创建抽象表达式类
cpp
class Expression {
public:
virtual ~Expression() = default;
virtual int interpret(const std::unordered_map<std::string, int>& context) = 0;
};
3.2.创建具体表达式类
变量表达式类
cpp
class VariableExpression : public Expression {
public:
VariableExpression(const std::string& name) : name(name) {}
int interpret(const std::unordered_map<std::string, int>& context) override { return context.at(name); }
private:
std::string name;
};
常量表达式类
cpp
class ConstantExpression : public Expression {
public:
ConstantExpression(int value) : value(value) {}
int interpret(const std::unordered_map<std::string, int>& context) override { return value; }
private:
int value;
};
加法表达式类
cpp
class AddExpression : public Expression {
public:
AddExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right) : left(std::move(left)), right(std::move(right)) {}
int interpret(const std::unordered_map<std::string, int>& context) override {
return left->interpret(context) + right->interpret(context);
}
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
};
减法表达式类
cpp
class SubtractExpression : public Expression {
public:
SubtractExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
: left(std::move(left)), right(std::move(right)) {}
int interpret(const std::unordered_map<std::string, int>& context) override {
return left->interpret(context) - right->interpret(context);
}
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
};
3.3.构建解析器
cpp
class Parser {
public:
static std::unique_ptr<Expression> parse(const std::string& expression) {
std::istringstream iss(expression);
return parseExpression(iss);
}
private:
static std::unique_ptr<Expression> parseExpression(std::istringstream& iss) {
auto left = parseTerm(iss);
while (iss) {
char op = iss.peek();
if (op == '+' || op == '-') {
iss.get();
auto right = parseTerm(iss);
if (op == '+') {
left = std::make_unique<AddExpression>(std::move(left), std::move(right));
} else {
left = std::make_unique<SubtractExpression>(std::move(left), std::move(right));
}
} else {
break;
}
}
return left;
}
static std::unique_ptr<Expression> parseTerm(std::istringstream& iss) {
if (std::isdigit(iss.peek())) {
int value;
iss >> value;
return std::make_unique<ConstantExpression>(value);
} else {
std::string name;
iss >> name;
return std::make_unique<VariableExpression>(name);
}
}
};
3.4.解释表达式
cpp
int main() {
std::string expression = "x + 10 - y";
// 解析表达式
auto expr = Parser::parse(expression);
// 上下文
std::unordered_map<std::string, int> context = {{"x", 5}, {"y", 3}};
// 解释表达式
int result = expr->interpret(context);
std::cout << "Result: " << result << std::endl; // 输出结果应为 5 + 10 - 3 = 12
return 0;
}