当有语言要解释时,请使用解释器模式为语言创建解释器。
解释器模式的核心是解释器类,在解释器模式中一般会定义两种解释器:
终结符解释器(Terminal Expression Interpreter):终结符解释器用于解释语言中的基本单位,对应语法树中的叶子节点,比如变量、常量等。
非终结符解释器(Nonterminal Expression Interpreter):非终结符解释器用于解释一个语法规则,对应语法树中的非叶子节点,比如算术表达式、逻辑表达式等。
解释器模式优缺点
解释器模式的优点是可以扩展语法规则,只需要增加相应的解释器即可,而不需要修改已有的解释器。但是,解释器模式的缺点也很明显,由于每个语法规则都需要对应一个解释器,因此解释器模式在解析复杂语句时会造成类膨胀和系统性能下降。
案例:
基于前面的Duck类,现在把它用于儿童学习编程的教育工具。使用这个模拟器,每个孩子都能用一种简单的语言来控制一只鸭子,
eg:
right;让鸭子右转
while(daylight)fly;让鸭子整天都在飞翔
quack;让鸭子嘎嘎叫
定义好语法后,现在所需要做的就是解释语法中的句子,好让学生们可以看到用这个语言控制鸭子的效果。
类图:
实现如下:
duck.h:
#ifndef DUCK_H
#define DUCK_H
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Duck {
public:
void quack()
{
cout << "鸭子嘎嘎叫" << endl;
}
void right()
{
cout << "鸭子右转" << endl;
}
void left()
{
cout << "鸭子左转" << endl;
}
void fly()
{
cout << "鸭子飞" << endl;
}
};
#endif // DUCK_H
expression.h:
#ifndef EXPRESSION_H
#define EXPRESSION_H
#include "duck.h"
class Expression {
public:
virtual void interpret() = 0;
protected:
Duck* m_duck = new Duck();
};
class Quack : public Expression{
public:
virtual void interpret()
{
m_duck->quack();
}
};
class Left : public Expression{
public:
virtual void interpret()
{
m_duck->left();
}
};
#endif // EXPRESSION_H
main.cpp:
/*
* 解释器模式
*
* date:2023-9-20
*/
#include "expression.h"
int main()
{
vector<string> contexts;
string context;
cout << "输入表达式(!结尾):" << endl;
while(cin>>context)
{
if(context == "!") break;
contexts.push_back(context);
}
Expression* expressions;
for(int i = 0; i < contexts.size(); i++)
{
if(contexts[i] == "quack")
{
expressions = new Quack();
expressions->interpret();
}
else if(contexts[i] == "left")
{
expressions = new Left();
expressions->interpret();
}
}
}
运行截图: