第二十七章-解释器模式

解释器模式(Interpreter): 给定一个语言,定义它的文法中的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

图片

解释器模式的好处

通常当有一个语言需要解释执行,并且你可以将该预言中的句子表示为一个抽象语法树时,可使用解释器模式。
用了解释器模式,就意味着可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。
但解释器模式也有不足,解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他的技术如语法分析程序或编译器生成器来处理。

音乐解释器

图片

图片

#include <iostream>
#include<vector>
#include<string>
#include<ctime>
#include<unordered_map>

using namespace std;

class PlayContext
{
private:
	string text;
public:
	string getText() { return text; }
	void setText(string text_t) { text = text_t; }
};

class Expression
{
public:
	virtual void Interpret(PlayContext* context)
	{
		if (context->getText().size() == 0)
			return;
		else
		{
			string playKey = context->getText().substr(0, 1);
			context->setText(context->getText().substr(2));
			int i = 0, j = 0;
			string tmp = context->getText();
			while (j<tmp.size() && tmp[j] != ' ')
				j++;
			double playValue = stod(tmp.substr(i, j - i + 1));
			if(j < tmp.size())
				context->setText(tmp.substr(j + 1));
			else
				context->setText("");
			Excute(playKey[0], playValue);
		}
	}

	virtual void Excute(char key, double value) = 0;
};

class Note :public Expression
{
public:
	void Excute(char key, double value)
	{
		string note;
		switch (key)
		{
		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 << " ";
	}
};

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

class Speed :public Expression
{
public:
	void Excute(char key, double value)
	{
		string speed;
		if (value < 500)
			speed = "快速";
		else if (value >= 1000)
			speed = "慢速";
		else
			speed = "中速";
		cout << speed << " ";
	}
};


int main()
{
	PlayContext* context = new PlayContext();

	cout << "上海滩:" << endl;

	context->setText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3");
	Expression* expression = nullptr;
 	while (context->getText().size())
	{
		string str = context->getText().substr(0, 1);
		switch (str[0])
		{
		case 'O':
			expression = new Scale();
			break;
		case 'T':
			expression = new Speed();
			break;
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'A':
		case 'B':
		case 'P':
			expression = new Note();
			break;
		}
		expression->Interpret(context);
	}
	
	

	

	system("pause");
	return 0;
}
posted @ 2019-12-18 15:57  微风吹过165  阅读(127)  评论(0编辑  收藏  举报