zoukankan      html  css  js  c++  java
  • 设计模式: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;
    }
  • 相关阅读:
    VML编程之shape多边型.shapetype模版.shape与curve曲线《VML极道教程》原著:沐缘华
    VML编程之image图片《VML极道教程》原著:沐缘华
    软件开发项目的风险管理 (转)
    VML编程之polyline多边型《VML极道教程》原著:沐缘华
    VML编程之标记实战与line线《VML极道教程》原著:沐缘
    xml操作类,封装了常用的对XML文件的操作功能....
    Bugzilla 安装手册
    IT项目管理之<<少林练步拳>>(转)
    Atlas学习手记(8):调用本地Web Service简单介绍(转摘)
    WF从设计器出发,到对从设计器出来的工作流的调用加载,已经完成了整个工作流的详细设计,目前工作流设计器已经完成!
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11434872.html
Copyright © 2011-2022 走看看