我从未见过如此厚颜无耻之题

chen_zhe 沙雕 2021-03-24 19:05:15 2021-03-24 19:08:22 1

大家都知道 未来程序 吧。

众所周知这是一道十分锻炼代码能力,调试能力,心理素质与如何不骂死出题人的《经 典 好 题》。

但是看到了用正儿八经的方法过着题的一份代码。觉得很吓人。

不信你可以复制一下看看要拖多久才能拖到底。还有各种指针等等容易RE的东西。估计也是个施工几个月~一年的工程。

这个一千行和写游戏的一千行不是一个概念,写游戏一千行的困难程度可能只顶的上下面这份代码的一百五十行左右(不要问我为什么知道,我尝试做过大膜你)


#include<cstdio>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<string>

#include<map>

#include<set>

#include<vector>

#include<iostream>

using namespace std;

char symbol_list[26][3]={

"+","-","*","/","%","=",

"(",")","[","]","{","}",

"!","<=",">=","<",">",

"==","!=","^","&&","||","<<",">>",

",",";"

};

set<string> symbolSet;

string code;

vector<int> nxt;

vector<int> sta;

int inputSize;

vector<int> Input;

int Curr;

enum nodeType{

  NONE,CODE,FUNCTION,DEFINEVAR,VAR,BLOCK,

  IF,IFELSE,FOR,WHILE,BLANK,RETURN,INP,OUP,CPY,

  OR,AND,XOR,EQU,DIFF,LE,LEQ,RE,REQ,ADD,SUB,MUL,

  DVD,MOD,POS,NEG,NOT,ENDL,NUM,FUNCCALL

};

enum tokenType{

  Number,String,Symbol

};

struct AST{

  vector< AST * > argv;

  vector< string > requ;

  vector< int > siz;

  nodeType type;

  string str;

};

struct Token{

  tokenType type;

  int st,ed;

  Token(tokenType type=Number,int st=0,int ed=0)

:type(type),st(st),ed(ed){}

};

inline int getNum(int st){

  while(code[st]=='+' || code[st]=='-')  ++st;

  while(code[st]>='0' && code[st]<='9')  ++st;

  return st-1;

}

inline int Str2Num(string str){

  int ret=0,flag=1,st=0;

  while(str[st]=='+' || str[st]=='-'){if(str[st]=='-')  flag*=-1;++st;

  }

  while(str[st]){

​    ret=ret*10+(str[st]-'0');++st;

  }

  return ret*flag;

}

inline int runNum(int st,int ed){

  int ret=0,flag=1;

  while(code[st]=='+' || code[st]=='-'){if(code[st]=='-')  flag*=-1;++st;

  }

  while(st<=ed){

​    ret=ret*10+(code[st]-'0');++st;

  }

  return ret*flag;

}

inline bool isName(char c){

  return ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_');

}

inline int getName(int st){

  while(isName(code[st])) ++st;

  return st-1;

}

inline string runName(int st,int ed){

  string ret="";

  for(int i=st;i<=ed;i++) ret+=code[i];

  return ret;

}

inline string getStr(Token a){

  return runName(a.st,a.ed);

}

inline int getVal(Token a){ 

  return runNum(a.st,a.ed);

}

struct Pool{

  map<string,vector<int> > info;

  map<string,int> index;

  vector<int> memory;

  int nw;

  void clear(){

​    nw=1;

​    memory.clear();

​    memory.push_back(0);

​    index.clear();

​    info.clear();

  }

  void addVar(AST * a){int allLen=1;for(int i=0,j=a->siz.size();i<j;i++)

​      allLen*=a->siz[i];

​    index[a->str]=nw;

​    info[a->str]=a->siz;

​    nw+=allLen;for(int i=0;i<allLen;i++)  memory.push_back(0);

  }

  int findNum(string name,vector<int> argv){int id=index[name],qwq=1;

​    vector<int> rr=info[name];for(int i=argv.size()-1;i>=0;i--){

​      id+=qwq*argv[i];

​      qwq*=rr[i];}return memory[id];

  }

  void deleteVar(string name){

​    index[name]=0;

  }

  void modifyNum(string name,vector<int> argv,int ii){int id=index[name],qwq=1;

​    vector<int> rr=info[name];for(int i=argv.size()-1;i>=0;i--){

​      id+=qwq*argv[i];

​      qwq*=rr[i];}

​    memory[id]=ii;

  }

  bool exist(string name){return index[name]!=0;

  }

}globalVar;

struct Runner{

  bool isRet;

  int num;

  Runner(bool isRet=false,int num=0)

:isRet(isRet),num(num){}

};

vector<Token> codeToken;

map<string,AST *> functionList;

AST * Expression(int , int);

int getElse(int st){

  if(code[codeToken[st].st]=='{')return nxt[st];

  if(getStr(codeToken[st])=="for"

  || getStr(codeToken[st])=="while"){

​    st=nxt[st+1]+1;if(code[codeToken[st].st]=='{')return nxt[st];else  return getElse(st);

  }

  else if(getStr(codeToken[st])=="if"){

​    st=nxt[st+1]+1;if(code[codeToken[st].st]=='{')

​      st=nxt[st];else  st=getElse(st);if(getStr(codeToken[st+1])!="else") return st;return getElse(st+2);

  }

  else{while(code[codeToken[st].st]!=';') ++st;return st;

  }

  return -1;

}

AST * NewVar(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str=getStr(codeToken[st]);

  ret->type=VAR;

  for(int i=st+2;i<=ed;i+=3)

​    ret->siz.push_back(getVal(codeToken[i]));

  return ret;

}

AST * DefineVar(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str=""; 

  ret->type=DEFINEVAR;

  ++st;

  for(int i=st;i<=ed;i++)if(code[codeToken[i].st]==',' || code[codeToken[i].st]==';'){

​      ret->argv.push_back(NewVar(st,i-1));

​      st=i+1;}

  return ret;

}

AST * Unit0(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  if(getStr(codeToken[st])=="endl"){

​    ret->type=ENDL;return ret; 

  }

  if(getStr(codeToken[st])=="("){while(nxt[st]==ed) st++,ed--;return Expression(st,ed);

  }

  if(code[codeToken[st].st]>='0'

  && code[codeToken[st].st]<='9'){

​    ret->type=NUM;

​    ret->str=getStr(codeToken[st]);return ret;

  }

  if(st==ed){

​    ret->type=VAR;

​    ret->str=getStr(codeToken[st]);return ret;

  }

  if(code[codeToken[st+1].st]=='['){

​    ret->type=VAR;

​    ret->str=getStr(codeToken[st]);++st;while(st<=ed){

​      ret->argv.push_back(Expression(st+1,nxt[st]-1));

​      st=nxt[st]+1;}return ret;

  }

  ret->type=FUNCCALL;

  ret->str=getStr(codeToken[st]);

  st+=2;

  for(int i=st;i<ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(code[codeToken[i].st]==','){

​      ret->argv.push_back(Expression(st,i-1));

​      st=i+1;}

  }

  if(st<=ed-1)

​    ret->argv.push_back(Expression(st,ed-1));

  return ret;

}

AST * Unit1(int st,int ed){

  if(getStr(codeToken[st])!="+"

  && getStr(codeToken[st])!="-"

  && getStr(codeToken[st])!="!")return Unit0(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  if(getStr(codeToken[st])=="+") ret->type=POS;

  if(getStr(codeToken[st])=="-") ret->type=NEG;

  if(getStr(codeToken[st])=="!") ret->type=NOT;

  ret->argv.push_back(Unit1(st+1,ed));

  return ret;

}

AST * Unit2(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="*"|| getStr(codeToken[i])=="/"|| getStr(codeToken[i])=="%")  hav=true;

  }

  if(!hav)  return Unit1(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  nodeType lst;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="*"|| getStr(codeToken[i])=="/"|| getStr(codeToken[i])=="%"){if(ret->argv.size()<2) ret->argv.push_back(Unit1(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit1(st,i-1));

​        ret=ret1;}

​      ret->type=lst;if(getStr(codeToken[i])=="*")  lst=MUL;if(getStr(codeToken[i])=="/")  lst=DVD;if(getStr(codeToken[i])=="%")  lst=MOD;

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit1(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit1(st,ed));

​    ret=ret1;

  }

  ret->type=lst;

  return ret;

}

AST * Unit3(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(i!=st

​    && (getStr(codeToken[i])=="+"|| getStr(codeToken[i])=="-")&& (codeToken[i-1].type!=Symbol

​    || code[codeToken[i-1].st]==')'|| code[codeToken[i-1].st]==']'))  hav=true;

  }

  if(!hav)  return Unit2(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  nodeType lst;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(i!=st

​    && (getStr(codeToken[i])=="+"|| getStr(codeToken[i])=="-")&& (codeToken[i-1].type!=Symbol

​    || code[codeToken[i-1].st]==')'|| code[codeToken[i-1].st]==']')){if(ret->argv.size()<2) ret->argv.push_back(Unit2(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit2(st,i-1));

​        ret=ret1;}

​      ret->type=lst;

​      lst=(getStr(codeToken[i])=="+"?ADD:SUB);

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit2(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit2(st,ed));

​    ret=ret1;

  }

  ret->type=lst;

  return ret;

}

AST * Unit4(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])==">"|| getStr(codeToken[i])=="<"|| getStr(codeToken[i])==">="|| getStr(codeToken[i])=="<=") hav=true;

  }

  if(!hav)  return Unit3(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  nodeType lst;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])==">"|| getStr(codeToken[i])=="<"|| getStr(codeToken[i])==">="|| getStr(codeToken[i])=="<="){if(ret->argv.size()<2) ret->argv.push_back(Unit3(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit3(st,i-1));

​        ret=ret1;}

​      ret->type=lst;if(getStr(codeToken[i])==">")  lst=RE;if(getStr(codeToken[i])=="<")  lst=LE;if(getStr(codeToken[i])==">=") lst=REQ;if(getStr(codeToken[i])=="<=") lst=LEQ;

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit3(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit3(st,ed));

​    ret=ret1;

  }

  ret->type=lst;

  return ret;

}

AST * Unit5(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="=="|| getStr(codeToken[i])=="!=") hav=true;

  }

  if(!hav)  return Unit4(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  nodeType lst;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="=="|| getStr(codeToken[i])=="!="){if(ret->argv.size()<2) ret->argv.push_back(Unit4(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit4(st,i-1));

​        ret=ret1;}

​      ret->type=lst;

​      lst=(getStr(codeToken[i])=="=="?EQU:DIFF);

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit4(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit4(st,ed));

​    ret=ret1;

  }

  ret->type=lst;

  return ret;

}

AST * Unit6(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="^")  hav=true;

  }

  if(!hav)  return Unit5(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  ret->type=XOR;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="^"){if(ret->argv.size()<2) ret->argv.push_back(Unit5(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->type=XOR;

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit5(st,i-1));

​        ret=ret1;}

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit5(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit5(st,ed));

​    ret=ret1;

  }

  ret->type=XOR;

  return ret;

}

AST * Unit7(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="&&") hav=true;

  }

  if(!hav)  return Unit6(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  ret->type=AND;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="&&"){if(ret->argv.size()<2) ret->argv.push_back(Unit6(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->type=AND;

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit6(st,i-1));

​        ret=ret1;}

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit6(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit6(st,ed));

​    ret=ret1;

  }

  ret->type=AND;

  return ret;

}

AST * Unit8(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="||") hav=true;

  }

  if(!hav)  return Unit7(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  ret->type=OR;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="||"){if(ret->argv.size()<2) ret->argv.push_back(Unit7(st,i-1));else{

​        AST * ret1=new AST();

​        ret1->argv.clear();

​        ret1->requ.clear();

​        ret1->siz.clear();

​        ret1->str="";

​        ret1->type=OR;

​        ret1->argv.push_back(ret);

​        ret1->argv.push_back(Unit7(st,i-1));

​        ret=ret1;}

​      st=i+1;}

  }

  if(ret->argv.size()<2) ret->argv.push_back(Unit7(st,ed));

  else{

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->argv.push_back(ret);

​    ret1->argv.push_back(Unit7(st,ed));

​    ret=ret1;

  }

  ret->type=OR;

  return ret;

}

AST * Unit9(int st,int ed){

  bool hav=false;

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="=")  hav=true;

  }

  if(!hav)  return Unit8(st,ed);

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  ret->type=CPY;

  vector<int> eq;

  eq.clear();eq.push_back(st-1);

  for(int i=st;i<=ed;i++){if(nxt[i]!=-1){

​      i=nxt[i];continue;}if(getStr(codeToken[i])=="=")  eq.push_back(i);

  }

  eq.push_back(ed+1);

  int l1=eq.size();

  int q1=eq[l1-3],q2=eq[l1-2],q3=eq[l1-1];

  ret->argv.push_back(Unit8(q1+1,q2-1));

  ret->argv.push_back(Unit8(q2+1,q3-1));

  for(int i=eq.size()-4;i>=0;i--){

​    AST * ret1=new AST();

​    ret1->argv.clear();

​    ret1->requ.clear();

​    ret1->siz.clear();

​    ret1->str="";

​    ret1->type=CPY;

​    ret1->argv.push_back(Unit8(eq[i]+1,eq[i+1]-1));

​    ret1->argv.push_back(ret);

​    ret=ret1;

  }

  return ret;

}

AST * Expression(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->str="";

  if(st>ed){

​    ret->type=BLANK;return ret;

  }

  if(getStr(codeToken[st])=="cin"){

​    ret->type=INP;st+=2;for(int i=st;i<=ed;i++){if(getStr(codeToken[i])==">>"){

​        ret->argv.push_back(Unit9(st,i-1));

​        st=i+1;}}if(st<=ed)

​      ret->argv.push_back(Unit9(st,ed));

  }

  else if(getStr(codeToken[st])=="cout"){

​    ret->type=OUP;st+=2;for(int i=st;i<=ed;i++){if(getStr(codeToken[i])=="<<"){

​        ret->argv.push_back(Unit9(st,i-1));

​        st=i+1;}}if(st<=ed)

​      ret->argv.push_back(Unit9(st,ed));

  }

  else  return Unit9(st,ed);

  return ret;

}

AST * Block(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->siz.clear();

  ret->type=BLOCK;

  while(nxt[st]==ed) ++st,--ed;

  if(st>ed){

​    ret->type=BLANK;return ret;

  }

  while(st<=ed){if(code[codeToken[st].st]=='{'){

​      ret->argv.push_back(Block(st,nxt[st]));

​      st=nxt[st]+1;continue;}if(getStr(codeToken[st])=="int"){int e=st;while(code[codeToken[st].st]!=';') ++st;

​      ret->argv.push_back(DefineVar(e,st));++st;continue;}if(getStr(codeToken[st])=="if"){

​      AST * ad=new AST();

​      ad->argv.clear();

​      ad->requ.clear();

​      ad->type=IF;++st;

​      ad->argv.push_back(Expression(st+1,nxt[st]-1));

​      st=nxt[st]+1;int ender=st;if(code[codeToken[st].st]=='{'){

​        ender=nxt[st];

​        ad->argv.push_back(Block(st,ender));

​        st=nxt[st]+1;}else{

​        ender=getElse(ender);

​        ad->argv.push_back(Block(st,ender));

​        st=ender+1;}if(getStr(codeToken[st])=="else"){

​        ad->type=IFELSE;++st;int u=getElse(st);

​        ad->argv.push_back(Block(st,u));

​        st=u+1;}

​      ret->argv.push_back(ad);continue;}if(getStr(codeToken[st])=="for"){

​      AST * ad=new AST();

​      ad->argv.clear();

​      ad->requ.clear();

​      ad->type=FOR;int qwq=nxt[st+1];st+=2;int u=st;while(code[codeToken[u].st]!=';')  ++u;if(getStr(codeToken[st])=="int")

​        ad->argv.push_back(DefineVar(st,u));else

​        ad->argv.push_back(Expression(st,u-1));

​      st=u+1;u=st;while(code[codeToken[u].st]!=';')  ++u;

​      ad->argv.push_back(Expression(st,u-1));

​      st=u+1;u=qwq;if(getStr(codeToken[st])=="int"){

​        code[codeToken[u].st]=';';

​        ad->argv.push_back(DefineVar(st,u));

​        code[codeToken[u].st]=')';}else

​        ad->argv.push_back(Expression(st,u-1));

​      st=u+1;u=st;if(code[codeToken[st].st]=='{'){

​        ad->argv.push_back(Block(st,nxt[st]));

​        st=nxt[st]+1;}else{

​        u=getElse(u);

​        ad->argv.push_back(Block(st,u));

​        st=u+1;}

​      ret->argv.push_back(ad);continue;}if(getStr(codeToken[st])=="while"){

​      AST * ad=new AST();

​      ad->argv.clear();

​      ad->requ.clear();

​      ad->type=WHILE;++st;

​      ad->argv.push_back(Expression(st+1,nxt[st]-1));

​      st=nxt[st]+1;int ender=st;if(code[codeToken[st].st]=='{'){

​        ender=nxt[st];

​        ad->argv.push_back(Block(st,ender));

​        st=nxt[st]+1;}else{

​        ender=getElse(st);

​        ad->argv.push_back(Block(st,ender));

​        st=ender+1;}

​      ret->argv.push_back(ad);continue;}if(getStr(codeToken[st])=="return"){

​      AST * ad=new AST();

​      ad->argv.clear();

​      ad->requ.clear();

​      ad->type=RETURN;++st;int u=st;while(code[codeToken[u].st]!=';')  ++u;

​      ad->argv.push_back(Expression(st,u-1));

​      ret->argv.push_back(ad);

​      st=u+1;continue;}int u=st;while(code[codeToken[u].st]!=';')  ++u;

​    ret->argv.push_back(Expression(st,u-1));

​    st=u+1;

  }

  return ret;

}

AST * Function(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->requ.clear();

  ret->str=getStr(codeToken[st+1]);

  ret->type=FUNCTION;

  st+=2;

  int i;

  for(i=st+2;i<=nxt[st];i+=3)

​    ret->requ.push_back(getStr(codeToken[i]));

  while(code[codeToken[i].st]!='{')  --i;

  st=i;

  if(st<=ed)

​    ret->argv.push_back(Block(st,ed));

  return ret;

}

AST * Code(int st,int ed){

  AST * ret=new AST();

  ret->argv.clear();

  ret->type=CODE;

  while(st<=ed){if(code[codeToken[st+2].st]=='('){int t=nxt[st+2];

​      t=nxt[t+1];

​      ret->argv.push_back(Function(st,t));

​      st=t+1;}else{int i;for(i=st;code[codeToken[i].st]!=';';++i);

​      ret->argv.push_back(DefineVar(st,i));

​      st=i+1;}

  }

  return ret;

}

void codeAnalysis(){

  int le=code.size();

  for(int i=0;code[i];i++){if(code[i]==' ' || code[i]=='\t')  continue;if(code[i]>='0' && code[i]<='9'){int u=getNum(i);

​      codeToken.push_back(Token(Number,i,u));

​      i=u;continue;}if(isName(code[i])){int u=getName(i);

​      codeToken.push_back(Token(String,i,u));

​      i=u;continue;}if(le>i+1 && symbolSet.count(code.substr(i,2))){

​      codeToken.push_back(Token(Symbol,i,i+1));++i;continue;}if(le>i && symbolSet.count(code.substr(i,1))){

​      codeToken.push_back(Token(Symbol,i,i));continue;}return;

  }

}

int getRealNum(string name,vector<int> argv,Pool & pa){

  if(pa.exist(name)) return pa.findNum(name,argv);

  return globalVar.findNum(name,argv);

}

void modifyRealNum(string name,vector<int> argv,int ii,Pool & pa){

  if(pa.exist(name)) pa.modifyNum(name,argv,ii);

  else globalVar.modifyNum(name,argv,ii);

}

\#define MakeNumber for(int i=0,j=curr->argv.size();i<j;i++){\

​    argv1.push_back(runAST(curr->argv[i],pa));\

​    argv2.push_back(argv1.back().num);\

  }

Runner runAST(AST * curr,Pool & pa){

  vector<Runner> argv1;

  vector<int> argv2;

  if(curr->type==DEFINEVAR){for(int i=0,j=curr->argv.size();i<j;i++)

​      pa.addVar(curr->argv[i]);return Runner(false,0);

  }

  if(curr->type==VAR){

​    MakeNumber

​    return Runner(false,getRealNum(curr->str,argv2,pa));

  }

  if(curr->type==BLOCK){

​    vector<string> needToKill;

​    needToKill.clear();for(int i=0,j=curr->argv.size();i<j;i++){if(curr->argv[i]->type==DEFINEVAR){

​        AST * uu=curr->argv[i];for(int k=0,l=uu->argv.size();k<l;k++)

​          needToKill.push_back(uu->argv[k]->str);}

​      Runner gg=runAST(curr->argv[i],pa);if(gg.isRet){for(int i=needToKill.size()-1;i>=0;i--)

​          pa.deleteVar(needToKill[i]);return gg;}}for(int i=needToKill.size()-1;i>=0;i--)

​      pa.deleteVar(needToKill[i]);return Runner(false,0);

  }

  if(curr->type==IF){

​    Runner gg=runAST(curr->argv[0],pa);if(gg.num!=0){

​      Runner gg=runAST(curr->argv[1],pa);if(gg.isRet)  return gg;}return Runner(false,0);

  }

  if(curr->type==IFELSE){

​    Runner gg=runAST(curr->argv[0],pa);if(gg.num!=0){

​      Runner gg=runAST(curr->argv[1],pa);if(gg.isRet)  return gg;}else{

​      Runner gg=runAST(curr->argv[2],pa);if(gg.isRet)  return gg;}return Runner(false,0);

  }

  if(curr->type==FOR){

​    vector<string> needToKill;

​    needToKill.clear();runAST(curr->argv[0],pa);if(curr->argv[0]->type==DEFINEVAR){

​      AST * uu=curr->argv[0];for(int i=0,j=uu->argv.size();i<j;i++)

​        needToKill.push_back(uu->argv[i]->str);}if(curr->argv[2]->type==DEFINEVAR){

​      AST * uu=curr->argv[2];for(int i=0,j=uu->argv.size();i<j;i++)

​        needToKill.push_back(uu->argv[i]->str);}while(curr->argv[1]->type==BLANK

​    || runAST(curr->argv[1],pa).num!=0){

​      Runner gg=runAST(curr->argv[3],pa);if(gg.isRet){for(int i=needToKill.size()-1;i>=0;i--)

​          pa.deleteVar(needToKill[i]);return gg;}runAST(curr->argv[2],pa);}for(int i=needToKill.size()-1;i>=0;i--)

​      pa.deleteVar(needToKill[i]);return Runner(false,0);

  }

  if(curr->type==WHILE){while(runAST(curr->argv[0],pa).num!=0){

​      Runner gg=runAST(curr->argv[1],pa);if(gg.isRet)  return gg;}return Runner(false,0);

  }

  if(curr->type==BLANK)return Runner(false,0);

  if(curr->type==INP){

​    vector<int> u;for(int i=0,j=curr->argv.size();i<j;i++){if(Curr==inputSize) return Runner(false,0);

​      string name=curr->argv[i]->str;

​      u.clear();for(int k=0,l=curr->argv[i]->argv.size();k<l;k++)

​        u.push_back(runAST(curr->argv[i]->argv[k],pa).num);modifyRealNum(name,u,Input[Curr++],pa);}return Runner(false,1);

  }

  if(curr->type==RETURN){

​    MakeNumber

​    return Runner(true,argv2[0]);

  }

  if(curr->type==OUP){

​    MakeNumber

​    int ret=0;for(int i=0,j=curr->argv.size();i<j;i++){if(curr->argv[i]->type==ENDL)  ret=bool(cout << endl);else  ret=bool(cout << argv2[i]);}return Runner(false,ret);

  }

  if(curr->type==CPY){

​    Runner gg=runAST(curr->argv[1],pa);if(gg.isRet)  return gg;int ii=gg.num;

​    vector<int> u;u.clear();for(int i=0,j=curr->argv[0]->argv.size();i<j;i++)

​      u.push_back(runAST(curr->argv[0]->argv[i],pa).num);modifyRealNum(curr->argv[0]->str,u,ii,pa);return Runner(false,ii);

  }

  if(curr->type==OR){

​    MakeNumber

​    return Runner(false,argv2[0]||argv2[1]);

  }

  if(curr->type==AND){

​    MakeNumber

​    return Runner(false,argv2[0]&&argv2[1]);

  }

  if(curr->type==XOR){

​    MakeNumber

​    return Runner(false,(!argv2[0])+(!argv2[1])==1);

  }

  if(curr->type==EQU){

​    MakeNumber

​    return Runner(false,argv2[0]==argv2[1]);

  }

  if(curr->type==DIFF){

​    MakeNumber

​    return Runner(false,argv2[0]!=argv2[1]);

  }

  if(curr->type==LE){

​    MakeNumber

​    return Runner(false,argv2[0]<argv2[1]);

  }

  if(curr->type==LEQ){

​    MakeNumber

​    return Runner(false,argv2[0]<=argv2[1]);

  }

  if(curr->type==RE){

​    MakeNumber

​    return Runner(false,argv2[0]>argv2[1]);

  }

  if(curr->type==REQ){

​    MakeNumber

​    return Runner(false,argv2[0]>=argv2[1]);

  }

  if(curr->type==ADD){

​    MakeNumber

​    return Runner(false,argv2[0]+argv2[1]);

  }

  if(curr->type==SUB){

​    MakeNumber

​    return Runner(false,argv2[0]-argv2[1]);

  }

  if(curr->type==MUL){

​    MakeNumber

​    return Runner(false,argv2[0]*argv2[1]);

  }

  if(curr->type==DVD){

​    MakeNumber

​    return Runner(false,argv2[0]/argv2[1]);

  }

  if(curr->type==MOD){

​    MakeNumber

​    return Runner(false,argv2[0]%argv2[1]);

  }

  if(curr->type==POS){

​    MakeNumber

​    return Runner(false,argv2[0]);

  }

  if(curr->type==NEG){

​    MakeNumber

​    return Runner(false,-argv2[0]);

  }

  if(curr->type==NOT){

​    MakeNumber

​    return Runner(false,!argv2[0]);

  }

  if(curr->type==ENDL)return Runner(false,10);

  if(curr->type==NUM)return Runner(false,Str2Num(curr->str));

  if(curr->type==FUNCCALL){

​    MakeNumber

​    if(curr->str=="putchar"){

​      cout << (char)argv2[0];return Runner(false,argv2[0]);}

​    Pool pb;pb.clear();

​    AST * y=new AST();

​    y->siz.clear();

​    y->type=VAR;

​    AST * aaa=functionList[curr->str];for(int i=0,j=argv2.size();i<j;i++){

​      y->str=aaa->requ[i];

​      pb.addVar(y);

​      pb.memory.pop_back();

​      pb.memory.push_back(argv2[i]);}

​    Runner gg=runAST(aaa->argv[0],pb);

​    pb.clear();if(gg.isRet)  return Runner(false,gg.num);return Runner(false,0);

  }

  return Runner(false,0);

}

int main(){

  std::ios::sync_with_stdio(false);

  scanf("%d",&inputSize);

  for(int i=0,a;i<inputSize;i++){scanf("%d",&a);

​    Input.push_back(a);

  }

  for(int i=0;i<26;i++)

​    symbolSet.insert(symbol_list[i]);

  char c;int qwq=0;

  while(scanf("%c",&c)!=EOF){if(c=='\r' || c=='\n') continue;++qwq;if(qwq==54) break;

  }

  while(scanf("%c",&c)!=EOF){if(c=='\r' || c=='\n') continue;

​    code+=c;

  }

  string coder=code;

  code="";

  for(int i=0;coder[i];i++){if(coder[i]=='+' || coder[i]=='-'){bool isPos=true;for(;coder[i]=='+' || coder[i]=='-'|| coder[i]==' ' || coder[i]=='\t';i++)

​        isPos^=(coder[i]=='-');

​      code+=(isPos?'+':'-');--i;}else  code+=coder[i];

  }

  codeAnalysis();

  for(int i=0,j=codeToken.size();i<j;i++){

​    nxt.push_back(-1);if(code[codeToken[i].st]==')'|| code[codeToken[i].st]==']'|| code[codeToken[i].st]=='}'){

​      nxt[sta.back()]=i;

​      sta.pop_back();}else{if(code[codeToken[i].st]=='('|| code[codeToken[i].st]=='['|| code[codeToken[i].st]=='{')

​        sta.push_back(i);}

  }

  AST * root=Code(0,codeToken.size()-1);

  for(int i=0,j=root->argv.size();i<j;i++){if(root->argv[i]->type==FUNCTION)

​      functionList[root->argv[i]->str]=root->argv[i];else{

​      AST * uu=root->argv[i];for(int k=0,l=uu->argv.size();k<l;k++)

​        globalVar.addVar(uu->argv[k]);}

  }

  Pool pa;pa.clear();

  runAST(functionList["main"]->argv[0],pa);

}

{{ vote && vote.total.up }}

共 2 条回复

root 站长

666666666666

JupHamaster 木星拜

我愿称为《绝世好题》