cpp:Interpreter Pattern

25 篇文章 0 订阅
/*****************************************************************//**
 * \file   DuSimple.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef DUSIMPLE_H
#define DUSIMPLE_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
 
 
#include "DuExpression.h"
#include "ActionDuExpression.h"
#include "DirectionDuExpression.h"
#include "DistanceDuExpression.h"
#include "SentenceDuExpression.h"
#include "AndDuExpression.h"
 
#pragma warning(disable : 4996)
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    ///
    /// </summary>
    class DuSimple
    {
 
    private:
 
    public:
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="strExp"></param>
        /// <returns></returns>
        DuExpression* Analyse(string strExp);
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="expression"></param>
        void Release(DuExpression* expression);
    };
 
}
#endif
 
 
/*****************************************************************//**
 * \file   DuSimple.cpp
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#include "DuSimple.h"
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="strExp"></param>
    /// <returns></returns>
    DuExpression* DuSimple::Analyse(string strExp) //strExp:要计算结果的表达式字符串,比如"left walk 15 and down run 20"
    {
        stack<DuExpression*>  expStack;
        DuExpression* direction = nullptr; DuExpression* action = nullptr; DuExpression* distance = nullptr;
        DuExpression* left = nullptr;   DuExpression* right = nullptr;
 
        //机器人运动控制命令之间是用空格来分隔的,所以用空格作为分隔字符来对整个字符串进行拆分
        char* strc = new char[strlen(strExp.c_str()) + 1];
        strcpy(strc, strExp.c_str()); //若本行编译报错提醒使用strcpy_s,则可以在文件头增加代码行:#pragma warning(disable : 4996) strcpy
        vector<string> resultVec;  //#include <vector>
        char* tmpStr = strtok(strc, " "); //按空格来切割字符串
        while (tmpStr != nullptr)
        {
            resultVec.push_back(string(tmpStr));
            tmpStr = strtok(NULL, " ");
        }
        delete[] strc;
        for (auto iter = resultVec.begin(); iter != resultVec.end(); ++iter)
        {
            if ((*iter) == "and") //和
            {
                left = expStack.top(); //返回栈顶元素(左操作数)
                ++iter;
 
                direction = new DistanceDuExpression(*iter); //运动方向
                ++iter;
                action = new ActionDuExpression(*iter); //运动方式
                ++iter;
                distance = new DistanceDuExpression(*iter); //运动距离
                right = new SentenceDuExpression(direction, action, distance);
                expStack.push(new AndDuExpression(left, right));
            }
            else
            {
                direction = new DirectionDuExpression(*iter); //运动方向
                ++iter;
                action = new ActionDuExpression(*iter); //运动方式
                ++iter;
                distance = new DistanceDuExpression(*iter); //运动距离
                expStack.push(new SentenceDuExpression(direction, action, distance));
            }
        }
        DuExpression* expression = expStack.top(); //返回栈顶元素
        return expression;
    }
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="expression"></param>
    void DuSimple::Release(DuExpression* expression)
    {
        //释放表达式树的节点内存  
        SentenceDuExpression* pSE = dynamic_cast<SentenceDuExpression*>(expression);
        if (pSE)
        {
            Release(pSE->getDirection());
            Release(pSE->getAction());
            Release(pSE->getDistance());
        }
        else
        {
            AndDuExpression* pAE = dynamic_cast<AndDuExpression*>(expression);
            if (pAE)
            {
                Release(pAE->getLeft());
                Release(pAE->getRight());
            }
        }
        delete expression;
    }
 
}
 
/*****************************************************************//**
 * \file   DuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef DUEXPRESSION_H
#define DUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    /// 表达式父类
    /// </summary>
    class DuExpression
    {
 
    public:
        /// <summary>
        /// 做父类时析构函数应该为虚函数
        /// </summary>
        virtual ~DuExpression() {} //
 
    public:
             
 
        /// <summary>
        /// 解析语法树中的当前节点
        /// </summary>
        /// <returns></returns>
        virtual string interpret() = 0;
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   DirectionDuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
 
#ifndef DIRECTIONDUEXPRESSION_H
#define DIRECTIONDUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "DuExpression.h"
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
 
    /// <summary>
    /// 运动方向表达式(终结符表达式)
    /// </summary>
    class DirectionDuExpression :public DuExpression
    {
 
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="direction"></param>
        DirectionDuExpression(const string& direction)
        {
            mDirection = direction;
        }
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        virtual string interpret()
        {
            if (mDirection == "up")
            {
                return "向上";
            }
            else if (mDirection == "down")
            {
                return "向下";
            }
            else if (mDirection == "left")
            {
                return "向左";
            }
            else if (mDirection == "right")
            {
                return "向右";
            }
            else
            {
                return "运动方向错";
            }
        }
    private:
 
        /// <summary>
        /// 运动方向:up、down、left、right分别表示上、下、左、右
        /// </summary>
        string mDirection;
 
 
 
    };
 
}
#endif
 
/*****************************************************************//**
 * \file   ActionDuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ACTIONDUEXPRESSION_H
#define ACTIONDUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "DuExpression.h"
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    /// 运动方式表达式(终结符表达式)
    /// </summary>
    class ActionDuExpression :public DuExpression
    {
 
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="action"></param>
        ActionDuExpression(const string& action)
        {
            mAction = action;
        }
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        virtual string interpret()
        {
            if (mAction == "walk")
            {
                return "行走";
            }
            else if (mAction == "run")
            {
                return "奔跑";
            }
            else
            {
                return "运动方式错";
            }
        }
    private:
        /// <summary>
        /// 运动方式:walk、run分别表示行走、奔跑
        /// </summary>
        string mAction;
 
 
    };
 
}
#endif
 
/*****************************************************************//**
 * \file   DistanceDuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef DISTANCEDUEXPRESSION_H
#define DISTANCEDUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "DuExpression.h"
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    /// 运动距离表达式(终结符表达式)
    /// </summary>
    class DistanceDuExpression :public DuExpression
    {
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="distance"></param>
        DistanceDuExpression(const string& distance)
        {
            mDistance = distance;
        }
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        virtual string interpret()
        {
            return mDistance + "米";
        }
 
    private:
        /// <summary>
        /// 运动距离,用字符串表示即可
        /// </summary>
        string mDistance;
 
 
    };
 
}
 
#endif
 
 
/*****************************************************************//**
 * \file   SentenceDuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef SENTENCEDUEXPRESSION_H
#define SENTENCEDUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "DuExpression.h"
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    /// “句子”表达式(非终结符表达式),“运动方向 运动方式 运动距离”构成
    /// </summary>
    class SentenceDuExpression :public DuExpression
    {
 
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="action"></param>
        /// <param name="distance"></param>
        SentenceDuExpression(DuExpression* direction, DuExpression* action, DuExpression* distance) :mDirection(direction), mAction(action), mDistance(distance) {}
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        DuExpression* getDirection() { return mDirection; }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        DuExpression* getAction() { return mAction; }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        DuExpression* getDistance() { return mDistance; }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        virtual string interpret()
        {
            return mDirection->interpret() + mAction->interpret() + mDistance->interpret();
        }
 
 
    private:
 
        /// <summary>
        /// 运动方向
        /// </summary>
        DuExpression* mDirection;
 
        /// <summary>
        /// 运动方式
        /// </summary>
        DuExpression* mAction;  
 
        /// <summary>
        /// 运动距离
        /// </summary>
        DuExpression* mDistance;
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   AndDuExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ANDDUEXPRESSION_H
#define ANDDUEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "DuExpression.h"
 
using namespace std;
 
 
 
namespace DuInterpreterPattern
{
 
    /// <summary>
    /// “和”表达式(非终结符表达式)
    /// </summary>
    class AndDuExpression :public DuExpression
    {
 
    public:
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        AndDuExpression(DuExpression* left, DuExpression* right) :mLeft(left), mRight(right) {}
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        DuExpression* getLeft() { return mLeft; }
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        DuExpression* getRight() { return mRight; }
 
         
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        virtual string interpret()
        {
            return mLeft->interpret() + "再" + mRight->interpret();
        }
    private:
        //左右各有一个操作数
 
        /// <summary>
        ///
        /// </summary>
        DuExpression* mLeft;
        /// <summary>
        ///
        /// </summary>
        DuExpression* mRight;
 
    };
}
 
#endif
 
/*****************************************************************//**
 * \file   GoldExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef GOLDEXPRESSION_H
#define GOLDEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    /// 小表达式(节点)父类
    /// </summary>
    class GoldExpression
    {
 
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="num"></param>
        /// <param name="sign"></param>
        GoldExpression(int num, char sign) :mNum(num), mSign(sign) {}
 
        /// <summary>
        /// 做父类时析构函数应该为虚函数
        /// </summary>
        virtual ~GoldExpression() {}
 
    public:
        /// <summary>
        /// 解析语法树中的当前节点
        /// </summary>
        /// <param name="var"></param>
        /// <returns></returns>
        virtual int interpret(map<char, int> var) = 0; //#include <map>,map容器中的键值对用于保存变量名及对应的值
 
    public:
        //以下两个成员变量是为程序跟踪调试时观察某些数据方便而引入
 
        /// <summary>
        /// 创建该对象时的一个编号,用于记录本对象是第几个创建的
        /// </summary>
        int mNum;          
        /// <summary>
        /// 标记本对象的类型,可能是个字符v代表变量(终结符表达式),也可能是个加减号(非终结符表达式)
        /// </summary>
        char mSign;
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   VarGoldExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef VARGOLDEXPRESSION_H
#define VARGOLDEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "GoldExpression.h"
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    /// 变量表达式(终结符表达式)
    /// </summary>
    class VarGoldExpression :public GoldExpression
    {
 
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key"></param>
        /// <param name="num"></param>
        /// <param name="sign"></param>
        VarGoldExpression(const char& key, int num, char sign) :GoldExpression(num, sign)
        {
            mkey = key;
        }
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="var"></param>
        /// <returns>返回变量名对应的数值</returns>
        virtual int interpret(map<char, int> var)
        {
            return var[mkey];
        }
 
    private:
 
        /// <summary>
        /// 变量名,本范例中诸如a、b、c、d都是变量名
        /// </summary>
        char mkey;
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   SymbolGoldExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef SYMBOLGOLDEXPRESSION_H
#define SYMBOLGOLDEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "GoldExpression.h"
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    /// 运算符表达式(非终结符表达式)父类
    /// </summary>
    class SymbolGoldExpression :public GoldExpression
    {
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="num"></param>
        /// <param name="sign"></param>
        SymbolGoldExpression(GoldExpression* left, GoldExpression* right, int num, char sign) :mLeft(left), mRight(right), GoldExpression(num, sign) {}
 
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        GoldExpression* getLeft() { return mLeft; }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        GoldExpression* getRight() { return mRight; }
 
 
 
 
    protected:
        //左右各有一个操作数
 
        /// <summary>
        ///
        /// </summary>
        GoldExpression* mLeft;
        /// <summary>
        ///
        /// </summary>
        GoldExpression* mRight;
 
 
 
 
    };
 
}
#endif
 
/*****************************************************************//**
 * \file   AddGoldExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ADDGOLDEXPRESSION_H
#define ADDGOLDEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "GoldExpression.h"
#include "SymbolGoldExpression.h"
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    /// 加法运算符表达式(非终结符表达式)
    /// </summary>
    class AddGoldExpression :public SymbolGoldExpression
    {
     
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="num"></param>
        /// <param name="sign"></param>
        AddGoldExpression(GoldExpression* left, GoldExpression* right, int num, char sign) :SymbolGoldExpression(left, right, num, sign) {}
        /// <summary>
        ///
        /// </summary>
        /// <param name="var"></param>
        /// <returns>返回两个变量相加的结果</returns>
        virtual int interpret(map<char, int> var)
        {
            //分步骤拆开写,方便理解和观察
            int value1 = mLeft->interpret(var); //递归调用左操作数的interpret方法
            int value2 = mRight->interpret(var); //递归调用右操作数的interpret方法
            int result = value1 + value2;
            return result;
        }
 
 
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   SubGoldExpression.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef SUBGOLDEXPRESSION_H
#define SUBGOLDEXPRESSION_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
 
#include "GoldExpression.h"
#include "SymbolGoldExpression.h"
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    /// 减法运算符表达式(非终结符表达式)
    /// </summary>
    class SubGoldExpression :public SymbolGoldExpression
    {
    public:
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="num"></param>
        /// <param name="sign"></param>
        SubGoldExpression(GoldExpression* left, GoldExpression* right, int num, char sign) :SymbolGoldExpression(left, right, num, sign) {}
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="var"></param>
        /// <returns>返回两个变量相减的结果</returns>
        virtual int interpret(map<char, int> var)
        {
            int value1 = mLeft->interpret(var);
            int value2 = mRight->interpret(var);
            int result = value1 - value2;
            return result; //
        }
 
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   GoldSimple.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef GOLDSIMPLE_H
#define GOLDSIMPLE_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
 
 
 
#include "GoldExpression.h"
#include "SymbolGoldExpression.h"
#include "AddGoldExpression.h"
#include "SubGoldExpression.h"
#include "SymbolGoldExpression.h"
#include "VarGoldExpression.h"
 
 
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    ///
    /// </summary>
    class GoldSimple
    {
 
    private:
 
    public:
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="expression"></param>
        void Release(GoldExpression* expression);
        /// <summary>
        ///
        /// </summary>
        /// <param name="strExp"></param>
        /// <returns></returns>
        GoldExpression* Analyse(string strExp);
 
    };
 
}
 
#endif
 
/*****************************************************************//**
 * \file   GoldSimple.cpp
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#include "GoldSimple.h"
 
 
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
 
    //分析—创建语法树(表达式树)
    GoldExpression* GoldSimple::Analyse(string strExp) //strExp:要计算结果的表达式字符串,比如"a-b+c+d"
    {
        stack<GoldExpression*>  expStack;//#include <stack>,这里用到了栈这种顺序容器
        GoldExpression* left = nullptr;
        GoldExpression* right = nullptr;
        int icount = 1;
        for (size_t i = 0; i < strExp.size(); ++i)//循环遍历表达式字符串中的每个字符
        {
            switch (strExp[i])
            {
            case '+':
                //加法运算符表达式(非终结符表达式)
                left = expStack.top(); //返回栈顶元素(左操作数)
                ++i;
                right = new VarGoldExpression(strExp[i], icount++, 'v'); //v代表是个变量节点
                //在栈顶增加元素
                expStack.push(new AddGoldExpression(left, right, icount++, '+')); //'+'代表是个减法运算符节点
                break;
            case '-':
                //减法运算符表达式(非终结符表达式)
                left = expStack.top(); //返回栈顶元素
                ++i;
                right = new VarGoldExpression(strExp[i], icount++, 'v');
                expStack.push(new SubGoldExpression(left, right, icount++, '-')); //'-'代表是个减法运算符节点
                break;
            default:
                //变量表达式(终结符表达式)
                expStack.push(new VarGoldExpression(strExp[i], icount++, 'v'));
                break;
            } //end switch
        } //end for
        GoldExpression* expression = expStack.top(); //返回栈顶元素
        return expression;
    }
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="expression"></param>
    void GoldSimple::Release(GoldExpression* expression)
    {
        //释放表达式树的节点内存
        SymbolGoldExpression* pSE = dynamic_cast<SymbolGoldExpression*>(expression); //此处代码有优化空间(不使用dynamic_cast),留给读者思考
        if (pSE)
        {
            Release(pSE->getLeft());
            Release(pSE->getRight());
        }
        delete expression;
    }
 
}
 
/*****************************************************************//**
 * \file   GeovinDu.h
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef GEOVINDU_H
#define GEOVINDU_H
 
#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
 
 
 
#include "GoldExpression.h"
#include "SymbolGoldExpression.h"
#include "AddGoldExpression.h"
#include "SubGoldExpression.h"
#include "SymbolGoldExpression.h"
#include "VarGoldExpression.h"
 
#include "GoldSimple.h"
 
#include "DuExpression.h"
#include "ActionDuExpression.h"
#include "DirectionDuExpression.h"
#include "DistanceDuExpression.h"
#include "SentenceDuExpression.h"
#include "AndDuExpression.h"
 
#include "DuSimple.h"
 
using namespace std;
using namespace DuInterpreterPattern;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    ///
    /// </summary>
    class GeovinDu
    {
 
    private:
 
    public:
 
        /// <summary>
        ///
        /// </summary>
        void displaySimple();
        /// <summary>
        ///
        /// </summary>
        void displayDuSimple();
 
    };
 
}
#endif
 
/*****************************************************************//**
 * \file   GeovinDu.cpp
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#include "GeovinDu.h"
 
using namespace std;
 
 
 
namespace DuJewelryInterpreterPattern
{
 
    /// <summary>
    ///
    /// </summary>
 
    void GeovinDu::displaySimple()
    {
        string strExp = "a-b+c+d";   //将要求值的字符串表达式
        map<char, int> varmap;
        //下面是给字符串表达式中所有参与运算的变量一个对应的数值
        varmap.insert(make_pair('a', 7)); //类似于赋值语句a = 7
        varmap.insert(make_pair('b', 9)); //类似于赋值语句b = 9
        varmap.insert(make_pair('c', 3)); //类似于赋值语句c = 3
        varmap.insert(make_pair('d', 2)); //类似于赋值语句d = 2
 
 
        GoldSimple simple;
         
        DuJewelryInterpreterPattern::GoldExpression* expression = simple.Analyse(strExp);  //调用analyse函数创建语法树
        int result = expression->interpret(varmap); //调用interpret接口求解字符串表达式的结果
        cout << "字符串表达式\"a - b + c + d\"的计算结果为:" << result << endl; //输出字符串表达式结果
 
        //释放内存
        simple.Release(expression);
 
    }
 
    /// <summary>
    ///
    /// </summary>
    void GeovinDu::displayDuSimple()
    {
        string strExp = "left walk 15 and down run 20";
 
        DuSimple simple;
 
        DuInterpreterPattern::DuExpression* expression = simple.Analyse(strExp);  //调用analyse函数创建语法树
        cout << expression->interpret() << endl;
 
        //释放内存
        simple.Release(expression);
 
    }
 
}

调用:

/*****************************************************************//**
 * \file   ConsoleDuInterpreterPattern.cpp
 * \brief  Interpreter Pattern  解释器模式  C++ 14
 * 2023年6月10日 涂聚文 Geovin Du Visual Studio 2022 edit.文章来源《C++新经典设计模式》 王健伟编著 清华大学出版社
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
// ConsoleDuInterpreterPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _UNICODE
 
 
#include <iostream>
#include "GeovinDu.h"
 
 
using namespace std;
using namespace DuJewelryInterpreterPattern;
 
#pragma warning(disable : 4996)
 
#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif
 
 
 
int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口
    std::cout << "Hello World!涂聚文 Geovin Du\n";
    GeovinDu geovindu;
    geovindu.displaySimple();
 
    cout << "*************" << endl;
    geovindu.displayDuSimple();
 
 
 
 
 
    system("pause");
    return 0;
}
 
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
 
// 入门使用技巧:
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
#define UNICODE

输出:

Hello World!涂聚文 Geovin Du
字符串表达式"a - b + c + d"的计算结果为:3
*************
向左行走15米再down米奔跑20米
请按任意键继续. . .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值