理解:可以广义的理解为创造一种语言,实现该语言的解释器,然后用创造的语言编写程序
对比:如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; }