设计模式:interpreter模式

理解:可以广义的理解为创造一种语言,实现该语言的解释器,然后用创造的语言编写程序

对比:如xml就是一种语言,解析xml的代码就是解释器

例子:

//目标:定义4中几种命令,使用C++解析
//如下:
//command go end
//command back end
//command right end
//command left end
//repeat 4 go back end
//command left left left end
class Command
{
public:
	virtual void excute() = 0;
};

class GoCommand: public Command
{
public:
	virtual void excute()
	{
		cout << "Go";
	}
};

class BackCommand: public Command
{
public:
	virtual void excute()
	{
		cout << "Back";
	}
};

class LeftCommand: public Command
{
public:
	virtual void excute()
	{
		cout << "Left";
	}
};

class RightCommand: public Command
{
public:
	virtual void excute()
	{
		cout << "Right";
	}
};

class CommandList: public Command
{
protected:
	vector<Command*> v;
public:
	virtual void excute()
	{
		for(vector<Command*>::iterator it=v.begin(); it!=v.end(); ++it)
		{
			cout << "  ";
			(*it)->excute();
			cout << endl;
		}
	}
	
	void addCommand(Command* command)
	{
		v.push_back(command);
	}
	
	~CommandList()
	{
		for(vector<Command*>::iterator it=v.begin(); it!=v.end(); ++it)
		{
			delete (*it);
		}
	}
};

class RepeatCommand: public CommandList
{
	int repeat;
public:
	RepeatCommand(int repeat)
	{
		this->repeat = repeat;
	}
	
	virtual void excute()
	{
		for(int i=0; i<repeat; i++)
		{
			for(vector<Command*>::iterator it=v.begin(); it!=v.end(); ++it)
			{
				cout << "  ";
				(*it)->excute();
			}
		}
	}
};
CommandList *program = NULL;

void SplitString(const string& s, vector<string>& v, const string& c)
{
    string::size_type pos1, pos2;
    pos2 = s.find(c);
    pos1 = 0;
    while(string::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2-pos1));
         
        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }
    if(pos1 != s.length())
        v.push_back(s.substr(pos1));
	return;
}

void ParseLine(vector<string>& v, CommandList* commandList)
{
	if(v.front() == string("command"))
	{
		if(v.back() == string("end"))
		{
			vector<string> sub(v);
			sub.erase(sub.begin());
			sub.erase(sub.end());
			ParseLine(sub, commandList);
		}
		else
		{
			cout << "Parse error1" << endl;
		}
		
	}
	else if(v.front() == string("repeat"))
	{
		if(v.back() == string("end"))
		{
			vector<string> sub(v);
			sub.erase(sub.begin());
			sub.erase(sub.end());
			
			istringstream is(sub[0]);
			int i = 0; 
			is >> i;
			
			RepeatCommand* reptCmd = new RepeatCommand(i);
			commandList->addCommand(reptCmd);
			
			sub.erase(sub.begin());
			ParseLine(sub, reptCmd);
			
		}
		else
		{
			cout << "Parse error1" << endl;
		}
	}
	else if(v.front() == string("go"))
	{
		commandList->addCommand(new GoCommand);
		vector<string> sub(v);
		sub.erase(sub.begin());
		if(sub.size() > 0)
		{
			ParseLine(sub, commandList);
		}
	}
	else if(v.front() == string("back"))
	{
		commandList->addCommand(new BackCommand);
		vector<string> sub(v);
		sub.erase(sub.begin());
		if(sub.size() > 0)
		{
			ParseLine(sub, commandList);
		}
	}
	else if(v.front() == string("left"))
	{
		commandList->addCommand(new LeftCommand);
		vector<string> sub(v);
		sub.erase(sub.begin());
		if(sub.size() > 0)
		{
			ParseLine(sub, commandList);
		}
	}
	else if(v.front() == string("right"))
	{
		commandList->addCommand(new RightCommand);
		vector<string> sub(v);
		sub.erase(sub.begin());
		if(sub.size() > 0)
		{
			ParseLine(sub, commandList);
		}
	}
	else
	{
		cout << "Parse error0" << endl;
	}
}

void Parse(string name)
{
	program = new CommandList();
	
	ifstream infile(name.c_str());
	string cmd;
	vector<string> v;
	while(getline(infile, cmd))
	{
		v.clear();
		SplitString(cmd, v, " ");
		ParseLine(v, program);
	}
	infile.close();
}
int main() 
{
	Parse(string("abc.txt"));
	program->excute();

	return 0;
}
posted @ 2019-08-30 14:34  Yong_无止境  阅读(267)  评论(0编辑  收藏  举报