设计模式之解释器模式

  解释器模式


  一、UML图

 

二、解释器模式简介(Brief Introduction)

解释器模式(Interpreter Pattern),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。使用了解释器模式,可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类容易直接编写。

三、解决的问题(What To Solve)

如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子,这样就可以构建一个解释器,该解释器通过解释这些句子来解决问题。

四、解释器模式分析(Analysis)

AbstractExpression:定义解释器的接口,约定解释器的操作
TerminalExpression:终结符解释器,用来实现语法规则中和终结符相关的操作,
不再包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器
NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作,通常一个解释器对应一个语法规则,可以包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象。可以有多种非终结符解释器
Context:上下文,通常包含各个解释器需要的数据或是公共的功能
Client:客户端,指的是使用解释器的客户端,通常在这里将按照语言的语法做的表达式转换成为使用解释器对象描述的抽象语法树,然后调用解释操作


五、代码示例(该代码示例根据大话设计模式一书改进而来)

#include <iostream>
#include <string>
using namespace std;

class PlayContext
{
public:
	void setPlayText(string text)
	{
		_text = text;
	}
	string getPlayText() const
	{
		return _text;
	}

private:
	string _text;
};

class Expression
{
public:
	void interpret(PlayContext& context)
	{
		if (context.getPlayText().length() == 0)
		{
			return;
		}
		else
		{
			string playKey = context.getPlayText().substr(0,1);
			context.setPlayText(context.getPlayText().substr(2));
			double playValue = atof(context.getPlayText().substr(0,context.getPlayText().find_first_of(' ')).c_str());
			context.setPlayText(context.getPlayText().substr(context.getPlayText().find_first_of(' ')+1));

			excute(playKey,playValue);
		}
	}
	virtual void excute(string key,double value){}
};

class Note :public Expression
{
public:
	void excute(string key,double value)
	{
		string note = "";
		char str = key.c_str()[0];
		switch (str)
		{
		case 'C':
			note = "1";
			break;
		case 'D':
			note = "2";
			break;
		case 'E':
			note = "3";
			break;
		case 'F':
			note = "4";
			break;
		case 'G':
			note = "5";
			break;
		case 'A':
			note = "6";
			break;
		case 'B':
			note = "7";
			break;
		}
		cout << note << " " <<endl;
	}
};

class Scale : public Expression
{
public:
	void excute(string key,double value)
	{
		string scale = "";
		switch((int)value)
		{
		case 1:
			scale = "低音";
			break;
		case 2:
			scale = "中音";
			break;
		case 3:
			scale = "高音";
			break;
		}
		cout << scale << " " << endl;
	}
};

int main()
{
	PlayContext *context = new PlayContext();
	context->setPlayText("O 2 E 0.5 G 0.5 O 3 ");
	Expression *expression = NULL;
	while(context->getPlayText().length() > 0)
	{
		string str = context->getPlayText().substr(0,1);
		switch(str[0])
		{
		case 'O':
			expression = new Scale();
			break;
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'A':
		case 'B':
		case 'P':
			expression = new Note();
			break;
		}
		expression->interpret(*context);
		delete expression;
	}

	getchar();
	return 0;
}
本人享有博客文章的版权,转载请标明出处 http://blog.youkuaiyun.com/wenchao126

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值