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

关于解释器模式看到了一篇讲解的十分好的博客行为型模式—解释器模式 ,自己写了一遍实现,首先要看懂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;

}

猜你喜欢

转载自blog.csdn.net/wingwc/article/details/78288517