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;
    }
  • 相关阅读:
    计算中文混合字符串长度(一)
    PHP截取含中文的混合字符串长度的函数
    获取星座的JS函数
    获取生日对应星座的PHP函数
    简单的 jQuery 浮动层随窗口滚动滑动插件实例
    MD5算法实现
    70. Climbing Stairs QuestionEditorial Solution
    167. Two Sum II
    167. Two Sum II
    303. Range Sum Query
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11434872.html
Copyright © 2011-2022 走看看