首页 > 其他分享 >cpp: Interpreter Pattern

cpp: Interpreter Pattern

时间:2023-06-11 22:34:26浏览次数:40  
标签:GoldExpression Pattern namespace DuExpression 2023 cpp Interpreter include 表达式

 

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

  

标签:GoldExpression,Pattern,namespace,DuExpression,2023,cpp,Interpreter,include,表达式
From: https://www.cnblogs.com/geovindu/p/17473748.html

相关文章

  • 【八股cover#2】CPP语法 Q&A与知识点
    CPP语法Q&A与知识点简历cover1、熟练使用C的指针应用及内存管理指针与引用的区别指针是一个存储地址的变量,可以有多级,可以为空,并且在初始化后可以改变指向;引用是原变量的别名,只有一级,不能为NULL,必须在定义时初始化,并且一旦初始化后就不能再改变。指针在作为参数传递时不会......
  • 第17章 迭代器模式(Iterator Pattern)
    概述在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责......
  • 第16章 命令模式(Command Pattern)
    命令模式(CommandPattern)——.NET设计模式系列之十七TerryLee,2006年7月概述在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求......
  • 第13章 代理模式(Proxy Pattern)
    代理模式(ProxyPattern)——.NET设计模式系列之十四Terrylee,2006年5月摘要:在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来代替目标......
  • 第12章 享元模式(Flyweight Pattern)
    享元模式(FlyweightPattern)——.NET设计模式系列之十三Terrylee,2006年3月摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面......
  • 第10章 组合模式(Composite Pattern)
    组合模式(CompositePattern)——.NET设计模式系列之十一Terrylee,2006年3月概述组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。意图将对象组合......
  • 第8章 桥接模式(Bridge Pattern)
    桥接模式(BridgePattern)——.NET设计模式系列之九Terrylee,2006年2月概述在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridg......
  • 第7章 适配器模式(Adapter Pattern)
    适配器模式(AdapterPattern)——.NET设计模式系列之八Terrylee,2006年2月概述在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。那么如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能......
  • 第5章 原型模式(Protype Pattern)
    原型模式(PrototypePattern)——.NET设计模式系列之六Terrylee,2006年1月概述在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构。这时如果用工厂模式,则与产品类等级结构平行的工厂方法类也要随着这种变化而变化,显然不大合适。那么如何封装这种动态的变化......
  • 第11章 外观模式(Façade Pattern)
    外观模式(FaçadePattern)——.NET设计模式系列之十二Terrylee,2006年3月概述在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖......