只需写一个解释器
第一次预处理将输入进行分词,分割出 关键字,运算符,变量/函数名,整数常量,并对变量/函数名离散化以便处理
第二次预处理建语法树,每个节点存节点类型,变量定义表等信息
运行时在语法树上递归处理,维护一个栈存运行中用到的变量
#include<cstdio> #include<map> #include<string> #include<vector> #include<cstring> using namespace std; int mem[10000007],*mp=mem; char buf[10007],*ptr=buf; char stk[10007]; int stp=0; map<string,int>ops,kws,vars; int vid=0; int rk[28]={100,100,101,101,2,2,3,3,3,4,4,4,5,5,6,6,6,6,7,7,8,9,10,11,12,12,13,14}; int rka[28]; struct token{ int tp;//operator:0 integer:1 var_name:2 keyword:3 int v; void init2(){ tp=2; string a(stk); if(kws.find(a)!=kws.end()){ tp=3; v=kws[a]; }else if(vars.find(a)!=vars.end()){ v=vars[a]; }else{ v=vars[a]=++vid; } } void init1(int x){ tp=1; v=x; } void init0(){ tp=0; v=ops[string(stk)]; if((v==7||v==8)&&(this[-1].tp==1||this[-1].tp==2||this[-1].eq(0,1)||this[-1].eq(0,3)))v+=5; } bool eq(int a,int b){ return tp==a&&v==b; } }ts[7007]; int tp=0,tptr=0; bool isname(char x){ return isalpha(x)||isdigit(x)||x=='_'||x=='$'; } int _n,__in[10007],_inp=0; int _ri(){ int x=0,f=1; while(!isdigit(*ptr))*ptr++=='-'?f=-1:0; while(isdigit(*ptr))x=x*10+*ptr++-48; return x*f; } void pre(){ _n=_ri(); for(int i=0;i<_n;++i)__in[i]=_ri(); for(;*ptr!=';';++ptr);++ptr; while(1){ for(;*ptr!=-1&&*ptr<33;++ptr); if(*ptr==-1)break; stp=0; if(isalpha(*ptr)){ for(;isname(*ptr);stk[stp++]=*ptr++);stk[stp]=0; ts[tp++].init2(); }else if(isdigit(*ptr)){ ts[tp++].init1(_ri()); }else{ stk[stp++]=*ptr++; stk[1]=*ptr; stk[2]=0; if(ops.find(string(stk))!=ops.end())++ptr; else stk[1]=0; ts[tp].init0();++tp; } } } #define ptr __ struct var{ int id,*dat,sz; vector<int>dsz; var(){sz=1,id=0;} void newdim(int x){ dsz.push_back(x); sz*=x; } }; vector<var>var_now[7007]; struct varlist{ std::vector<var>vs; void def(bool init=1){ for(int i=0;i<vs.size();++i){ var&w=vs[i]; if(init)memset(mp,0,sizeof(int)*w.sz); w.dat=mp,mp+=w.sz; var_now[w.id].push_back(w); } } void defs(){ int mx=*--mp; for(int i=0;i<vs.size();++i){ var&w=vs[i]; memset(mp,0,sizeof(int)*w.sz); w.dat=mp,mp+=w.sz; var_now[w.id].push_back(w); } *mp++=mx+vs.size(); } void undef(){ for(int i=0;i<vs.size();++i){ var_now[vs[i].id].pop_back(); mp-=vs[i].sz; } } void undefs(){ int mx=*--mp; for(int i=0;i<mx;++i){ var_now[vs[i].id].pop_back(); mp-=vs[i].sz; } } void ins(int id){ var w; w.id=id; vs.push_back(w); } void R(){ var w; w.id=ts[tptr++].v; for(;ts[tptr].eq(0,2);tptr+=3)w.newdim(ts[tptr+1].v); vs.push_back(w); } void Rs(){ for(++tptr;;){ R(); if(ts[tptr++].v==27)break; } } }glob_var; struct node{ int tp,v; varlist vs; vector<node>rs; node&rspb(){ rs.push_back(node()); return rs.back(); } void Rvar(){tp=7,v=ts[tptr++].v;} void Rint(){tp=8,v=ts[tptr++].v;} void setop(int w){tp=10,v=w;} void Rcall(){ tp=9; v=ts[tptr].v; tptr+=2; while(!ts[tptr-1].eq(0,1))rspb().Rexpr(); } void setvdim(int L,int R,varlist&w){ tp=13; for(int i=L;i<R;++i)vs.vs.push_back(w.vs[i]); } void Rexpr(){ tp=2; vector<int>ops; ops.push_back(0); while(1){ if(ts[tptr].tp==0){//oper if(ts[tptr].v>=26){ while(ops.back()){ rspb().setop(ops.back()); ops.pop_back(); } break; } int v=ts[tptr].v; if(v==0||v==2)ops.push_back(v); else if(v==1){ while(ops.back()){ rspb().setop(ops.back()); ops.pop_back(); } ops.pop_back(); if(ops.empty())break; }else if(v==3){ int c; do{ c=ops.back(); rspb().setop(c); ops.pop_back(); }while(c!=2); }else{ while(ops.back()[rk]+v[rka]<=v[rk]){ rspb().setop(ops.back()); ops.pop_back(); } ops.push_back(v); } ++tptr; }else if(ts[tptr].tp==1)rspb().Rint();//int else if(ts[tptr+1].eq(0,0))rspb().Rcall();//call func else rspb().Rvar();//var } ++tptr; } void Rkw(){ if(ts[tptr].v==0){//if tp=3; tptr+=2; rspb().Rexpr(); rspb().Rblock(); if(ts[tptr].eq(3,1)){//else ++tptr; rspb().Rblock(); } }else if(ts[tptr].v==2){//while tp=4; tptr+=2; rspb().Rexpr(); rspb().Rblock(); }else if(ts[tptr].v==3){//for tp=5; tptr+=2; rspb(); if(ts[tptr].eq(3,4))vs.Rs(),rs.back().tp=12; else rs.back().Rexpr(); rspb().Rexpr(); rspb().Rexpr(); rspb().Rblock(); }else{//return tp=6; ++tptr; rspb().Rexpr(); } } void Rblock(){ if(!ts[tptr].eq(0,4)){ if(ts[tptr].tp==3)Rkw(); else Rexpr(); return; } tp=1; ++tptr; while(!ts[tptr].eq(0,5)){ if(ts[tptr].tp==3){ if(ts[tptr].v==4){ int L=vs.vs.size(); vs.Rs(); int R=vs.vs.size(); rspb().setvdim(L,R,vs); }else rspb().Rkw(); }else rspb().Rblock(); } ++tptr; } void Rfunc(){ tp=0; tptr+=3; if(ts[tptr].eq(0,1))++tptr; else do{ ++tptr; vs.R(); }while(!ts[tptr++].eq(0,1)); rspb().Rblock(); } }funcs[7007]; #define run(x) _runs[x.tp](x) int (*_runs[30])(node&); void (*_ops[30])(); bool ret_flag=0; int _func(node&w){ w.vs.def(0); int r=run(w.rs[0]); w.vs.undef(); ret_flag=0; void push(int); push(r); return r; } int _block(node&w){ *mp++=0; int r=0; for(int i=0;i<w.rs.size()&&!ret_flag;++i)r=run(w.rs[i]); w.vs.undefs(); return r; } int _expr(node&w){ if(w.rs.empty())return 1; for(int i=0;i<w.rs.size();++i)run(w.rs[i]); int&pop(); return pop(); } int _if(node&w){ int r=0; if(run(w.rs[0]))r=run(w.rs[1]); else if(w.rs.size()==3)r=run(w.rs[2]); return r; } int _while(node&w){ int r=0; while(!ret_flag&&run(w.rs[0]))r=run(w.rs[1]); return r; } int _for(node&w){ int r=0; w.vs.def(); for(run(w.rs[0]);!ret_flag&&run(w.rs[1]);run(w.rs[2]))r=run(w.rs[3]); w.vs.undef(); return r; } int _ret(node&w){ int r=run(w.rs[0]); ret_flag=1; return r; } int _var(node&w){ mp[0]=w.v; mp[1]=0; mp[2]=0; mp+=3; } void push(int x){ mp[0]=-1; mp[1]=x; mp[2]=0; mp+=3; } int _int(node&w){ push(w.v); } int _nod(node&w){} int _call(node&w){ for(int i=0;i<w.rs.size();++i){ int r=run(w.rs[i]); *mp++=r; } mp-=w.rs.size(); return run(funcs[w.v]); } int&pop(){ mp-=3; return *mp<0?mp[1]:var_now[*mp].back().dat[mp[2]]; } void _arr(){ int x=pop(); mp[-1]*=var_now[mp[-3]].back().dsz[mp[-2]++]; mp[-1]+=x; } void _not(){push(!pop());} void _pos(){push(pop());} void _neg(){push(-pop());} #define dop(x,y) void x(){int b=pop(),a=pop();push(y);} dop(_mul,a*b) dop(_div,a/b) dop(_mod,a%b) dop(_add,a+b) dop(_sub,a-b) dop(_leq,a<=b) dop(_meq,a>=b) dop(_lss,a<b) dop(_mre,a>b) dop(_eq,a==b) dop(_neq,a!=b) dop(_xor,!a+!b==1) dop(_and,a&&b) dop(_or,a||b) void _set(){ int b=pop(); pop()=b; push(b); } void _in(){ pop()=__in[_inp++]; } void _out(){ int x=pop(); if(mp[0]==3)puts(""); else printf("%d",x); } int _op(node&w){ _ops[w.v](); } int _vdim(node&w){ w.vs.defs(); } int _pc(node&w){ int c=*mp; putchar(c); push(c); return c; } void pre2(){ while(tptr<tp){ if(ts[tptr+2].tp==0&&ts[tptr+2].v==0)funcs[ts[tptr+1].v].Rfunc(); else glob_var.Rs(); } } int main(){ _runs[0]=_func; _runs[1]=_block; _runs[2]=_expr; _runs[3]=_if; _runs[4]=_while; _runs[5]=_for; _runs[6]=_ret; _runs[7]=_var; _runs[8]=_int; _runs[9]=_call; _runs[10]=_op; _runs[11]=_pc; _runs[12]=_nod; _runs[13]=_vdim; _ops[2]=_arr; _ops[6]=_not;_ops[7]=_pos;_ops[8]=_neg; _ops[9]=_mul;_ops[10]=_div;_ops[11]=_mod; _ops[12]=_add;_ops[13]=_sub; _ops[14]=_leq;_ops[15]=_meq;_ops[16]=_lss;_ops[17]=_mre; _ops[18]=_eq;_ops[19]=_neq; _ops[20]=_xor; _ops[21]=_and; _ops[22]=_or; _ops[23]=_set; _ops[24]=_out; _ops[25]=_in; rka[6]=rka[7]=rka[8]=rka[23]=1; ops["("]=0;ops[")"]=1; ops["["]=2;ops["]"]=3; ops["{"]=4;ops["}"]=5; ops["!"]=6;ops["+"]=7;ops["-"]=8; ops["*"]=9;ops["/"]=10;ops["%"]=11; ops["<="]=14;ops[">="]=15;ops["<"]=16;ops[">"]=17; ops["=="]=18;ops["!="]=19; ops["^"]=20; ops["&&"]=21; ops["||"]=22; ops["="]=23; ops["<<"]=24;ops[">>"]=25; ops[","]=26; ops[";"]=27; kws["if"]=0; kws["else"]=1; kws["while"]=2; kws["for"]=3; kws["int"]=4; kws["return"]=5; vars["cin"]=++vid; vars["cout"]=++vid; vars["endl"]=++vid; funcs[vars["putchar"]=++vid].tp=11; fread(buf,1,sizeof(buf),stdin)[buf]=-1; pre(); pre2(); glob_var.ins(1); glob_var.ins(2); glob_var.ins(3); glob_var.def(); run(funcs[vars["main"]]); return 0; }