设计模式之解释器模式

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

优点:容易改变和扩展文法,因为该模式使用类来表示文法规则,可以使用继承来改变或扩展该文法,比较容易实现文法,因为定义抽象语法树中各个节点的类实现大体类似,易于直接编写。

不足:解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。文法容易时,可使用。

解释器模式并不像前面的设计模式易懂。下面给出代码理解。

解释器模式范例:

#include<iostream>
#include <string>
#include <list>

using namespace std;

class Context;

class AbstractExpression
{
	public:
		virtual void Interpret(Context* context) = 0;
};

class TerminalExpression: public AbstractExpression
{
	public:
		void Interpret(Context* context)
		{
			cout << "终端解释器" << endl;
		}
};

class NonterminalExprssion : public AbstractExpression
{
	void Interpret(Context* context)
	{
		cout << "非终端解释器" << endl;
	}
};

class Context
{
	public:
		string getInput()
		{
			return input;
		}
		void setInput(string value)
		{
			input = value;
		}
		
		string getOutput()
		{
			return output;
		}
		void setOutput(string value)
		{
			output = value;
		}
			
	private:
		string input;
		string output;
};

int main()
{
	Context* context = new Context();
	
	list<AbstractExpression*> List;
	
	List.push_back(new TerminalExpression());
	List.push_back(new NonterminalExprssion());
	List.push_back(new TerminalExpression());
	List.push_back(new TerminalExpression());

	
	
	for(int i = 0;i < 4;i++)
	{
		AbstractExpression* exp = List.back();
		exp->Interpret(context);
		List.pop_back();
	}
	
	
	return 0;
}

解释器模式中会用到一些负责的算法,容器等一些知识。文法的实现比较难于理解,但过于复杂又不适合,如果文法非常复杂时,建议使用其他的技术,如语法分析程序或编译器生成器来处理。

解释器模式实例:

#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <typeinfo>

using namespace std;

class Expression
{
	public:
		virtual int interpreter(map<string,int>& var) = 0;
		virtual ~Expression(){}
};

class VarExpression : public Expression
{
	public:
		VarExpression(string key)
		{
			this->key = key;
		}
		int interpreter(map<string,int>& var)
		{
			return var[key];
		}
		~VarExpression()
		{
			//cout << "~VarExpression()" << endl;
		}
	private:
		string key;
};

class SymbolExpression : public Expression
{
	public:
		SymbolExpression(Expression* left,Expression* right)
		{
			this->left = left;
			this->right = right;
		}
		Expression* getLeft()
		{
			return left;
		}
		Expression* getRight()
		{
			return right;
		}
	protected:
		Expression* left;
		Expression* right;
};


class AddExpression : public SymbolExpression
{
	public:
		AddExpression(Expression* left,Expression* right) : SymbolExpression(left,right)
		{
			
		}
		int interpreter(map<string,int>& var)
		{
			return left->interpreter(var) + right->interpreter(var);
		}
		~AddExpression()
		{
			//cout << "~AddExpression()" << endl;
		}
	
};

class SubExpression : public SymbolExpression
{
	public:
		SubExpression(Expression* left,Expression* right) : SymbolExpression(left,right)
		{
			
		}
		int interpreter(map<string,int>& var)
		{
			return left->interpreter(var) - right->interpreter(var);
		}
		~SubExpression()
		{
			//cout << "~SubExpression()" << endl;
		}
	
};


class Calculator
{
	public:
		Calculator(string expStr)
		{
			expression = NULL;
			
			stack<Expression*> st;
			
			Expression* left = NULL;
			Expression* right = NULL;
			
			for(unsigned int i = 0;i < expStr.length();i++)
			{
				switch(expStr[i])
				{
					case '+':
						left = st.top();
						st.pop();
						right = new VarExpression(expStr.substr(++i,1));
						st.push(new AddExpression(left,right));
						break;
					case '-':
						left = st.top();
						st.pop();
						right = new VarExpression(expStr.substr(++i,1));
						st.push(new SubExpression(left,right));
						break;
					default:
						st.push(new VarExpression(expStr.substr(i,1)));
				}
			}
			if(!st.empty())
			{
				expression = st.top();
				st.pop();
			}
		}
		
		void deltree(Expression* expression)
		{
			SymbolExpression* branch = dynamic_cast<SymbolExpression*>(expression);
			if(branch == NULL)
			{
				delete expression;
			}
			else
			{
				deltree(branch->getLeft());
				deltree(branch->getRight());
				delete expression;
			}
		}
		~Calculator()
		{
			deltree(expression);
			expression = NULL;
		}
		int run(map<string,int>& var)
		{
			return (expression == NULL) ? 0 : expression->interpreter(var);
		}
	private:
		Expression* expression;
};

int main()
{
	string expStr = "a+b-c";
	
	map<string,int> var;
	var["a"] = 100;
	var["b"] = 20;
	var["c"] = 30;
	
	Calculator cal(expStr);
	
	cout << "运算结果为:" << expStr << "=" << cal.run(var) << endl;
	
	
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值