1、解析模式的提出
在软件开发的过程中,需要实现一种需求,该需求的结构稳定,但是需求的业务内容会频繁变化,如果使用普通语法实现需求,需要经常更新代码,不具有灵活性。可以使用解析器模式解决实现该类需求,解析器是实现一种能够解析该需求结构语法的功能代码,针对不同的业务调用对应的解析规则代码。
2、需求描述
有一个字符串的加减计算,如'a+b+c-d-e',其中a,b,c,d,e分别对应带计算的值。设计一个功能代码,可以实现该功能,且该代码可以适配不定个数的加减数运算。
3、功能实现
(1)UML图如下:
(2)代码实现如下:
#include <iostream>
#include <map>
#include <stack>class AbsExpression
{
public:bool isVarType = false;
public:void setExpressionType(bool bFlag){isVarType= bFlag;};virtual int interpreter(std::map<char,int>var)=0;virtual ~AbsExpression(){};
};//变量表达式
class ValExpression:public AbsExpression
{
private:char m_key;
public:ValExpression(const char&key){std::cout << "ValExpression " << std::endl;this->m_key = key;setExpressionType(true);}int interpreter(std::map<char, int> var) override{return var[m_key];}~ValExpression(){std::cout << "~ValExpression " << std::endl;}
};//符号表达式
class SymbolExpression:public AbsExpression
{
protected:AbsExpression* m_left;AbsExpression* m_right;public:SymbolExpression(AbsExpression* left,AbsExpression* right):m_left(left),m_right(right){}~SymbolExpression(){//left对象是直接取的栈容器的上一个top,故可以显式清理。//right的new对象不会直接push进栈容器,而是做了符号实例对象的成员变量。故需要对其进行对象释放if(m_right != nullptr){delete m_right;m_right = nullptr;}std::cout << "~SymbolExpression" << std::endl;}
};//加法运算符
class AddExpression:public SymbolExpression
{
public:AddExpression(AbsExpression* left,AbsExpression* right):SymbolExpression(left,right){std::cout << "AddExpression " << std::endl;}int interpreter(std::map<char,int>var){return m_left->interpreter(var) + m_right->interpreter(var);}
};
//减法运算符
class SubExpression:public SymbolExpression
{
public:SubExpression(AbsExpression* left,AbsExpression* right):SymbolExpression(left,right){std::cout << "SubExpression " << std::endl;}int interpreter(std::map<char,int>var){return m_left->interpreter(var) - m_right->interpreter(var);}
};std::stack<AbsExpression*> analyse(std::string strLanguage){std::stack<AbsExpression*>stackExp;AbsExpression* left = nullptr;AbsExpression* right = nullptr;for(size_t i = 0; i < strLanguage.length();i++){switch (strLanguage[i]) {case '+':{left = stackExp.top();right = new ValExpression(strLanguage[++i]);stackExp.push(new AddExpression(left,right));}break;case '-':{ left = stackExp.top();right = new ValExpression(strLanguage[++i]);stackExp.push(new SubExpression(left,right));}break;default:stackExp.push(new ValExpression(strLanguage[i]));}}return stackExp;
};void release( std::stack<AbsExpression*> exp)
{while (exp.size() > 0) {AbsExpression* it = exp.top();delete it;it = nullptr;exp.pop();}std::cout << "clear exp finshed " << std::endl;
}
class Client
{
public:void doWork(){std::string str = "a+b+c-d";std::map<char,int>mapVar;mapVar.insert(std::make_pair('a',1));mapVar.insert(std::make_pair('b',2));mapVar.insert(std::make_pair('c',3));mapVar.insert(std::make_pair('d',4));std::stack<AbsExpression*> exp = analyse(str);int ret = exp.top()->interpreter(mapVar);std::cout << "ret is " << ret << std::endl;release(exp);}
};int main()
{Client obj;obj.doWork();return 0;
}
运行结果如下:
注意:解析器适用于比较简单的语法解析,对于复杂的语法,可以使用语法分析生成器工具,具体的语法分析生成器用法可自行搜索查看。