cpp: Interpreter Pattern

 

/*****************************************************************//**
 * \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米
请按任意键继续. . .

  

posted @ 2023-06-11 22:16  ®Geovin Du Dream Park™  阅读(13)  评论(0编辑  收藏  举报