模式定义
解释器模式(Interpreter Pattern)是一种行为型设计模式,用于为特定语言(如数控系统的G代码)定义文法规则,并构建解释器来解析和执行该语言的语句。它通过将语法规则分解为多个类,实现复杂指令的逐层解析。
模式结构
抽象表达式(Abstract Expression)
- 定义
interpret()
接口,声明解释操作的抽象方法(如void interpret(Context& context)
)。
终结符表达式(Terminal Expression) - 实现文法中的基本元素(如G代码指令
G00
、G01
),直接处理具体操作。
非终结符表达式(Non-terminal Expression) - 处理复合语法结构(如嵌套指令组合),通过递归调用子表达式实现复杂逻辑。
上下文(Context) - 存储解释器所需的全局信息(如机床坐标、刀具状态)。
适用场景
数控系统G代码解析:将G00 X100 Y200
等指令转换为机床运动控制。
数学公式计算:解析并执行如(3+5)*2
的表达式。
自定义脚本引擎:实现简单控制逻辑的脚本语言。
C++示例(数控G代码解析)
场景说明:
设计一个解释器,解析数控系统的G代码指令(如G00
快速定位、G01
直线插补),并更新机床坐标。
#include
#include
#include
#include
// 上下文类:存储机床坐标
class Context {
public:
float x, y;
Context() : x(0), y(0) {}
};
// 抽象表达式
class Expression {
public:
virtual void interpret(Context& context) = 0;
virtual ~Expression() = default;
};
// 终结符表达式:G00指令(快速移动)
class G00Command : public Expression {
private:
float targetX, targetY;
public:
G00Command(float x, float y) : targetX(x), targetY(y) {}
void interpret(Context& context) override {
context.x = targetX;
context.y = targetY;
std::cout << "快速定位至 (" << context.x << ", " << context.y << ")\n";
}
};
// 终结符表达式:G01指令(直线插补)
class G01Command : public Expression {
private:
float targetX, targetY;
public:
G01Command(float x, float y) : targetX(x), targetY(y) {}
void interpret(Context& context) override {
context.x = targetX;
context.y = targetY;
std::cout << "直线插补至 (" << context.x << ", " << context.y << ")\n";
}
};
// 解析器:将字符串指令转换为表达式对象
Expression* parseCommand(const std::string& input) {
std::istringstream iss(input);
std::string cmd;
float x, y;
iss >> cmd >> x >> y;
if (cmd == "G00") return new G00Command(x, y);
else if (cmd == "G01") return new G01Command(x, y);
return nullptr;
}
// 客户端使用
int main() {
Context context;
std::string code = "G00 100 200\nG01 300 150"; // 模拟G代码输入
std::istringstream stream(code);
std::string line;
while (std::getline(stream, line)) {
Expression* expr = parseCommand(line);
if (expr) {
expr->interpret(context);
delete expr;
}
}
return 0;
}
代码解析
上下文类:存储机床的当前坐标x
和y
。
表达式类:
G00Command
和G01Command
为终结符表达式,直接修改坐标并输出动作。
解析逻辑:parseCommand
将输入字符串拆解为指令和参数,生成对应表达式对象。
执行过程:逐行解析G代码,调用interpret()
更新坐标状态。