POJ-2314(简单C语言虚拟机)
来源:互联网 发布:cacti 监控linux流量 编辑:程序博客网 时间:2024/05/16 02:10
题目:http://poj.org/problem?id=2314
是道很好的题目,牵扯到设计模式、状态机、名称空间、函数重载等,debug时还可以用到拦截器的思想,用心做的话可以学习或练习到很多东西:
(1)命令模式:设计一个公共基类Expression作为接口,则几种Expression便对应了各个实体command,分别实现自己的语法和语义,用户类Program则只需要包含基类Expression的句柄(指针),即可run
(2)状态机:载入程序时,边载入边进行语义分析,递归(DFS)调用载入程序
(3)拦截器:由于所有变量都是global的,可以利用STL map类似数组的用法结合C++操作符重载的特性,在变量access时,可以打印access前(后)global scope的状态
#include <cstdio>#include <cctype>#include <string>#include <map>#include <vector>#include <functional>#include <algorithm>using namespace std;bool isNumber(const string& s){//if s is an integer if(s.empty()) return false; for(int i = 0; i < s.size(); ++i){ if(!isdigit(s[i])) return false; } return true;}int toNumber(const string& s){//parse s as an integer int n; sscanf(s.c_str(), "%d", &n); return n;}struct Expression{ virtual ~Expression(){} virtual void execute(){};};class Scope{private: map<string,int> nameValueMap; map<string,int>::const_iterator iter; void intercept(const string& name){ printf("before access \"%s\"\n", name.c_str()); for(iter = nameValueMap.begin(); iter != nameValueMap.end(); ++iter){ printf("%s = %d\n", iter->first.c_str(), iter->second); } }public: int& operator [] (const string& name){// intercept(name); return nameValueMap[name]; }} global;bool Terminate = false;struct Special : public Expression{ string variable; Special(const string& s) : variable(s){} virtual void execute(){ ::Terminate = true; printf("%d\n", global[variable]); }};struct Assignment : public Expression{ string A, B, OP, C; //A = B or A = B OP C Assignment(const string& s){// printf("new Assignment: %s\n", s.c_str()); string::size_type equalSign = s.find('='); A = s.substr(0, equalSign); string::size_type op = s.find_first_of("+-*", equalSign+1); if(op == string::npos) B = s.substr(equalSign+1); else{ B = s.substr(equalSign+1, op-equalSign-1); OP.push_back(s[op]); C = s.substr(op+1); } if(isNumber(B)) global[B] = toNumber(B); if(isNumber(C)) global[C] = toNumber(C); } virtual void execute(){// printf("execute %s=%s%s%s\n", A.c_str(), B.c_str(), OP.c_str(), C.c_str()); if(OP.empty()) global[A] = global[B]; else if(OP == "+") global[A] = global[B] + global[C]; else if(OP == "-") global[A] = global[B] - global[C]; else global[A] = global[B] * global[C]; }};struct Judgement : public Expression{ string A, OP, B; bool result; Judgement(const string& s){// printf("new Judgement: %s\n", s.c_str()); string::size_type pos = s.find_first_of("<="); if(s[pos+1] == '='){//<= or == A = s.substr(0, pos); OP = s.substr(pos, 2); B = s.substr(pos+2); } else{//< A = s.substr(0, pos); OP.push_back(s[pos]); B = s.substr(pos+1); } if(isNumber(A)) global[A] = toNumber(A); if(isNumber(B)) global[B] = toNumber(B); } virtual void execute(){// printf("execute %s%s%s\n", A.c_str(), OP.c_str(), B.c_str()); if(OP == "<") result = global[A] < global[B]; else if(OP == "==") result = global[A] == global[B]; else result = global[A] <= global[B]; } bool judge(){ execute(); return result; }};struct IfSuite : public Expression{ Judgement condition; vector<Expression*> clause; IfSuite(const string& s) : condition(s){} ~IfSuite(){ for(int i = 0; i < clause.size(); ++i) delete clause[i]; } void addClause(Expression* exp){ clause.push_back(exp); } virtual void execute(){ if(!::Terminate && condition.judge()){// for(int i = 0; i < clause.size(); ++i) clause[i]->execute(); for_each(clause.begin(), clause.end(), mem_fun(&Expression::execute)); } }};struct WhileSuite : public Expression{ Judgement condition; vector<Expression*> clause; WhileSuite(const string& s) : condition(s){} ~WhileSuite(){ for(int i = 0; i < clause.size(); ++i) delete clause[i]; } void addClause(Expression* exp){ clause.push_back(exp); } virtual void execute(){ while(!::Terminate && condition.judge()){// for(int i = 0; i < clause.size(); ++i) clause[i]->execute(); for_each(clause.begin(), clause.end(), mem_fun(&Expression::execute)); } }};class Program{private: vector<Expression*> clause;private: Expression* loadSpecial(){ char c; string name; while((c = getchar()) != ';'){ if(!isspace(c)) name.push_back(c); } return new Special(name); } Expression* loadIf(){ char c; string condition; while((c = getchar()) != ')'){ if(!isspace(c)) condition.push_back(c); } IfSuite* suite = new IfSuite(condition); while(getchar() != '{') ; load(suite->clause, '}'); return suite; } Expression* loadWhile(){ char c; string condition; while((c = getchar()) != ')'){ if(!isspace(c)) condition.push_back(c); } WhileSuite* suite = new WhileSuite(condition); while(getchar() != '{') ; load(suite->clause, '}'); return suite; } void load(vector<Expression*>& v, int endTag = -1){ int c; string s; while((c = getchar()) != endTag){//read till end if(isspace(c)) continue; if(c == '('){//suite begins if(s == "if") v.push_back(loadIf()); else v.push_back(loadWhile()); s.clear(); } else if(c == '#'){//special begins v.push_back(loadSpecial()); s.clear(); } else if(c == ';'){//assignment ends if(!s.empty()){ v.push_back(new Assignment(s)); s.clear(); } } else s.push_back(c);//part of expression } }public: ~Program(){ for(int i = 0; i < clause.size(); ++i) delete clause[i]; } void load(){ load(clause); } void run(){// printf("\nabout to execute %u clause:\n\n", clause.size()); for_each(clause.begin(), clause.end(), mem_fun(&Expression::execute)); }};int main(){ Program tiny; tiny.load(); tiny.run(); return 0;}
0 0
- POJ-2314(简单C语言虚拟机)
- poj-2801-填词-C语言-简单计算
- poj-3237-鸡兔同笼-C语言-简单计算
- POJ 2431 C语言
- c语言简单应用
- C语言简单认识
- C语言简单摘要
- C语言简单编程
- C语言简单程序
- C语言简单程序
- 简单C语言应用
- C语言简单解密
- 简单的c语言
- C语言简单进程
- c语言简单设计
- 【C语言】简单成绩表
- C语言简单运算
- c语言简单程序
- 浙江诸暨市中医医院招聘2人公告
- 学习笔记_android四种点击事件方法
- 使用游标查询的方法SQL2005
- Java实现的SSO单点登录
- CodeForces-50A-Domino piling
- POJ-2314(简单C语言虚拟机)
- 新能源汽车免购置税实施 浙江企业有望分一杯羹
- iOS导航控制器的使用
- JAVA 实现栈 (这次是用链表实现)
- sonar的安装
- 关于离职和再找工作
- 常用adb命令
- ldap search all ou, throws exception
- 加快vs编译速度(vs2008+cf3.5)