《大话设计模式》读书笔记之C++实现--chapter27解释器模式

来源:互联网 发布:域名国外申请做跳转 编辑:程序博客网 时间:2024/04/30 10:26

关于解释器模式看到了一篇讲解的十分好的博客行为型模式—解释器模式 ,自己写了一遍实现,首先要看懂UML类图,理解终结符解释器和非终结符解释器的作用,然后要掌握抽象语法树的构建,理解了这几点之后就很容易利用解释器模式构造自己的解释器

#include <iostream>#include <string>#include <map>#include <stack>using namespace std;//抽象解释器(是终结符解释器和非终结符解释器的父类)class Expression{public:    virtual int Interpret(map<string,int>& context) = 0;    virtual ~Expression(){}};//终结符解释器(在本例中为运算元素解释器)class VarExpression:public Expression{public:    VarExpression(string key):m_key(key){}    int Interpret(map<string, int> &context)    {        if(context.end() == context.find(m_key))        {            cout << "未定义运算元素" << m_key <<endl;            return -1;        }        else            return context[m_key];    }    ~VarExpression()    {        cout << "~VarExpression()" << endl;    }private:    string m_key;};//非终结符解释器(在本例中为运算符解释器)class SymbolExpression:public Expression{public:    SymbolExpression(Expression *leftExp,Expression *rightExp):m_pLeftExp(leftExp),m_pRightExp(rightExp){}    Expression* GetLeftExp()    {        return m_pLeftExp;    }    Expression* GetRightExp()    {        return m_pRightExp;    }protected:    Expression *m_pLeftExp;    Expression *m_pRightExp;};//加法符号解释器class AddExpression:public SymbolExpression{public:    AddExpression(Expression *leftExp,Expression *rightExp):SymbolExpression(leftExp,rightExp){}    int Interpret(map<string, int> &context)    {        return m_pLeftExp->Interpret(context) + m_pRightExp->Interpret(context);    }    ~AddExpression()    {        cout << "~AddExpression()" << endl;    }};/**************如果要添加语义则继承SymbolExpression并重写interpret函数即可**********************///Calculator构建抽象语法树,利用二叉树的栈结构来递归实现class Calculator{public:    Calculator(string strExp):m_pResultExp(NULL)    {        //用于存放临时结果的栈        stack<Expression*> resultStack;        Expression *leftExp;        Expression *rightExp;        /*从左到向分析表达式(如:a+b-c),最终的语法树如下:                 *           -                 *         /   \                 *       +     c                 *     /   \                 *    a     b                */        for(size_t i=0;i<strExp.size();i++)        {            switch (strExp[i])            {            case '+':                //取出栈顶元素作为左操作数                leftExp = resultStack.top();                resultStack.pop();                //取出下一元素作为右操作数                rightExp = new VarExpression(strExp.substr(++i,1));                //将结果所得存入栈中,此处为AddExp对象                resultStack.push(new AddExpression(leftExp,rightExp));                break;            default:                //如果为终结符解释器,则直接推入栈中                resultStack.push(new VarExpression(strExp.substr(i,1)));                break;            }        }        if(!resultStack.empty())        {            m_pResultExp = resultStack.top();            resultStack.pop();        }    }    //删除抽象语法树    void DeleteTree(Expression *delExp)    {        SymbolExpression *node = dynamic_cast<SymbolExpression*>(delExp);        if(node == NULL)        {            delete delExp;        }        else        {            DeleteTree(node->GetLeftExp());            DeleteTree(node->GetRightExp());            delete delExp;        }    }    int GetResult(map<string,int>& context)    {        return (m_pResultExp == NULL) ? 0 : m_pResultExp->Interpret(context);    }    ~Calculator()    {        DeleteTree(m_pResultExp);        m_pResultExp = NULL;    }private:    Expression *m_pResultExp;};int main(int argc,char** argv){    string strExp = "a+b+c";    map<string,int> context;    context["a"] = 100;    context["b"] = 50;    context["c"] = 80;    Calculator cal(strExp);    cout << strExp << "的解释结果为: " << cal.GetResult(context) <<endl;    return 0;}
原创粉丝点击