只需写一个解释器

第一次预处理将输入进行分词,分割出 关键字,运算符,变量/函数名,整数常量,并对变量/函数名离散化以便处理

第二次预处理建语法树,每个节点存节点类型,变量定义表等信息

运行时在语法树上递归处理,维护一个栈存运行中用到的变量

  1. #include<cstdio>
  2. #include<map>
  3. #include<string>
  4. #include<vector>
  5. #include<cstring>
  6. using namespace std;
  7. int mem[],*mp=mem;
  8. char buf[],*ptr=buf;
  9. char stk[];
  10. int stp=;
  11. map<string,int>ops,kws,vars;
  12. int vid=;
  13. int rk[]={,,,,,,,,,,,,,,,,,,,,,,,,,,,};
  14. int rka[];
  15. struct token{
  16. int tp;//operator:0 integer:1 var_name:2 keyword:3
  17. int v;
  18. void init2(){
  19. tp=;
  20. string a(stk);
  21. if(kws.find(a)!=kws.end()){
  22. tp=;
  23. v=kws[a];
  24. }else if(vars.find(a)!=vars.end()){
  25. v=vars[a];
  26. }else{
  27. v=vars[a]=++vid;
  28. }
  29. }
  30. void init1(int x){
  31. tp=;
  32. v=x;
  33. }
  34. void init0(){
  35. tp=;
  36. v=ops[string(stk)];
  37. if((v==||v==)&&(this[-].tp==||this[-].tp==||this[-].eq(,)||this[-].eq(,)))v+=;
  38. }
  39. bool eq(int a,int b){
  40. return tp==a&&v==b;
  41. }
  42. }ts[];
  43. int tp=,tptr=;
  44. bool isname(char x){
  45. return isalpha(x)||isdigit(x)||x=='_'||x=='$';
  46. }
  47. int _n,__in[],_inp=;
  48. int _ri(){
  49. int x=,f=;
  50. while(!isdigit(*ptr))*ptr++=='-'?f=-:;
  51. while(isdigit(*ptr))x=x*+*ptr++-;
  52. return x*f;
  53. }
  54. void pre(){
  55. _n=_ri();
  56. for(int i=;i<_n;++i)__in[i]=_ri();
  57. for(;*ptr!=';';++ptr);++ptr;
  58. while(){
  59. for(;*ptr!=-&&*ptr<;++ptr);
  60. if(*ptr==-)break;
  61. stp=;
  62. if(isalpha(*ptr)){
  63. for(;isname(*ptr);stk[stp++]=*ptr++);stk[stp]=;
  64. ts[tp++].init2();
  65. }else if(isdigit(*ptr)){
  66. ts[tp++].init1(_ri());
  67. }else{
  68. stk[stp++]=*ptr++;
  69. stk[]=*ptr;
  70. stk[]=;
  71. if(ops.find(string(stk))!=ops.end())++ptr;
  72. else stk[]=;
  73. ts[tp].init0();++tp;
  74. }
  75. }
  76. }
  77. #define ptr __
  78. struct var{
  79. int id,*dat,sz;
  80. vector<int>dsz;
  81. var(){sz=,id=;}
  82. void newdim(int x){
  83. dsz.push_back(x);
  84. sz*=x;
  85. }
  86. };
  87. vector<var>var_now[];
  88. struct varlist{
  89. std::vector<var>vs;
  90. void def(bool init=){
  91. for(int i=;i<vs.size();++i){
  92. var&w=vs[i];
  93. if(init)memset(mp,,sizeof(int)*w.sz);
  94. w.dat=mp,mp+=w.sz;
  95. var_now[w.id].push_back(w);
  96. }
  97. }
  98. void defs(){
  99. int mx=*--mp;
  100. for(int i=;i<vs.size();++i){
  101. var&w=vs[i];
  102. memset(mp,,sizeof(int)*w.sz);
  103. w.dat=mp,mp+=w.sz;
  104. var_now[w.id].push_back(w);
  105. }
  106. *mp++=mx+vs.size();
  107. }
  108. void undef(){
  109. for(int i=;i<vs.size();++i){
  110. var_now[vs[i].id].pop_back();
  111. mp-=vs[i].sz;
  112. }
  113. }
  114. void undefs(){
  115. int mx=*--mp;
  116. for(int i=;i<mx;++i){
  117. var_now[vs[i].id].pop_back();
  118. mp-=vs[i].sz;
  119. }
  120. }
  121. void ins(int id){
  122. var w;
  123. w.id=id;
  124. vs.push_back(w);
  125. }
  126. void R(){
  127. var w;
  128. w.id=ts[tptr++].v;
  129. for(;ts[tptr].eq(,);tptr+=)w.newdim(ts[tptr+].v);
  130. vs.push_back(w);
  131. }
  132. void Rs(){
  133. for(++tptr;;){
  134. R();
  135. if(ts[tptr++].v==)break;
  136. }
  137. }
  138. }glob_var;
  139. struct node{
  140. int tp,v;
  141. varlist vs;
  142. vector<node>rs;
  143. node&rspb(){
  144. rs.push_back(node());
  145. return rs.back();
  146. }
  147. void Rvar(){tp=,v=ts[tptr++].v;}
  148. void Rint(){tp=,v=ts[tptr++].v;}
  149. void setop(int w){tp=,v=w;}
  150. void Rcall(){
  151. tp=;
  152. v=ts[tptr].v;
  153. tptr+=;
  154. while(!ts[tptr-].eq(,))rspb().Rexpr();
  155. }
  156. void setvdim(int L,int R,varlist&w){
  157. tp=;
  158. for(int i=L;i<R;++i)vs.vs.push_back(w.vs[i]);
  159. }
  160. void Rexpr(){
  161. tp=;
  162. vector<int>ops;
  163. ops.push_back();
  164. while(){
  165. if(ts[tptr].tp==){//oper
  166. if(ts[tptr].v>=){
  167. while(ops.back()){
  168. rspb().setop(ops.back());
  169. ops.pop_back();
  170. }
  171. break;
  172. }
  173. int v=ts[tptr].v;
  174. if(v==||v==)ops.push_back(v);
  175. else if(v==){
  176. while(ops.back()){
  177. rspb().setop(ops.back());
  178. ops.pop_back();
  179. }
  180. ops.pop_back();
  181. if(ops.empty())break;
  182. }else if(v==){
  183. int c;
  184. do{
  185. c=ops.back();
  186. rspb().setop(c);
  187. ops.pop_back();
  188. }while(c!=);
  189. }else{
  190. while(ops.back()[rk]+v[rka]<=v[rk]){
  191. rspb().setop(ops.back());
  192. ops.pop_back();
  193. }
  194. ops.push_back(v);
  195. }
  196. ++tptr;
  197. }else if(ts[tptr].tp==)rspb().Rint();//int
  198. else if(ts[tptr+].eq(,))rspb().Rcall();//call func
  199. else rspb().Rvar();//var
  200. }
  201. ++tptr;
  202. }
  203. void Rkw(){
  204. if(ts[tptr].v==){//if
  205. tp=;
  206. tptr+=;
  207. rspb().Rexpr();
  208. rspb().Rblock();
  209. if(ts[tptr].eq(,)){//else
  210. ++tptr;
  211. rspb().Rblock();
  212. }
  213. }else if(ts[tptr].v==){//while
  214. tp=;
  215. tptr+=;
  216. rspb().Rexpr();
  217. rspb().Rblock();
  218. }else if(ts[tptr].v==){//for
  219. tp=;
  220. tptr+=;
  221. rspb();
  222. if(ts[tptr].eq(,))vs.Rs(),rs.back().tp=;
  223. else rs.back().Rexpr();
  224. rspb().Rexpr();
  225. rspb().Rexpr();
  226. rspb().Rblock();
  227. }else{//return
  228. tp=;
  229. ++tptr;
  230. rspb().Rexpr();
  231. }
  232. }
  233. void Rblock(){
  234. if(!ts[tptr].eq(,)){
  235. if(ts[tptr].tp==)Rkw();
  236. else Rexpr();
  237. return;
  238. }
  239. tp=;
  240. ++tptr;
  241. while(!ts[tptr].eq(,)){
  242. if(ts[tptr].tp==){
  243. if(ts[tptr].v==){
  244. int L=vs.vs.size();
  245. vs.Rs();
  246. int R=vs.vs.size();
  247. rspb().setvdim(L,R,vs);
  248. }else rspb().Rkw();
  249. }else rspb().Rblock();
  250. }
  251. ++tptr;
  252. }
  253. void Rfunc(){
  254. tp=;
  255. tptr+=;
  256. if(ts[tptr].eq(,))++tptr;
  257. else do{
  258. ++tptr;
  259. vs.R();
  260. }while(!ts[tptr++].eq(,));
  261. rspb().Rblock();
  262. }
  263. }funcs[];
  264. #define run(x) _runs[x.tp](x)
  265. int (*_runs[])(node&);
  266. void (*_ops[])();
  267. bool ret_flag=;
  268. int _func(node&w){
  269. w.vs.def();
  270. int r=run(w.rs[]);
  271. w.vs.undef();
  272. ret_flag=;
  273. void push(int);
  274. push(r);
  275. return r;
  276. }
  277. int _block(node&w){
  278. *mp++=;
  279. int r=;
  280. for(int i=;i<w.rs.size()&&!ret_flag;++i)r=run(w.rs[i]);
  281. w.vs.undefs();
  282. return r;
  283. }
  284. int _expr(node&w){
  285. if(w.rs.empty())return ;
  286. for(int i=;i<w.rs.size();++i)run(w.rs[i]);
  287. int&pop();
  288. return pop();
  289. }
  290. int _if(node&w){
  291. int r=;
  292. if(run(w.rs[]))r=run(w.rs[]);
  293. else if(w.rs.size()==)r=run(w.rs[]);
  294. return r;
  295. }
  296. int _while(node&w){
  297. int r=;
  298. while(!ret_flag&&run(w.rs[]))r=run(w.rs[]);
  299. return r;
  300. }
  301. int _for(node&w){
  302. int r=;
  303. w.vs.def();
  304. for(run(w.rs[]);!ret_flag&&run(w.rs[]);run(w.rs[]))r=run(w.rs[]);
  305. w.vs.undef();
  306. return r;
  307. }
  308. int _ret(node&w){
  309. int r=run(w.rs[]);
  310. ret_flag=;
  311. return r;
  312. }
  313. int _var(node&w){
  314. mp[]=w.v;
  315. mp[]=;
  316. mp[]=;
  317. mp+=;
  318. }
  319. void push(int x){
  320. mp[]=-;
  321. mp[]=x;
  322. mp[]=;
  323. mp+=;
  324. }
  325. int _int(node&w){
  326. push(w.v);
  327. }
  328. int _nod(node&w){}
  329. int _call(node&w){
  330. for(int i=;i<w.rs.size();++i){
  331. int r=run(w.rs[i]);
  332. *mp++=r;
  333. }
  334. mp-=w.rs.size();
  335. return run(funcs[w.v]);
  336. }
  337. int&pop(){
  338. mp-=;
  339. return *mp<?mp[]:var_now[*mp].back().dat[mp[]];
  340. }
  341. void _arr(){
  342. int x=pop();
  343. mp[-]*=var_now[mp[-]].back().dsz[mp[-]++];
  344. mp[-]+=x;
  345. }
  346. void _not(){push(!pop());}
  347. void _pos(){push(pop());}
  348. void _neg(){push(-pop());}
  349. #define dop(x,y) void x(){int b=pop(),a=pop();push(y);}
  350. dop(_mul,a*b)
  351. dop(_div,a/b)
  352. dop(_mod,a%b)
  353. dop(_add,a+b)
  354. dop(_sub,a-b)
  355. dop(_leq,a<=b)
  356. dop(_meq,a>=b)
  357. dop(_lss,a<b)
  358. dop(_mre,a>b)
  359. dop(_eq,a==b)
  360. dop(_neq,a!=b)
  361. dop(_xor,!a+!b==)
  362. dop(_and,a&&b)
  363. dop(_or,a||b)
  364. void _set(){
  365. int b=pop();
  366. pop()=b;
  367. push(b);
  368. }
  369. void _in(){
  370. pop()=__in[_inp++];
  371. }
  372. void _out(){
  373. int x=pop();
  374. if(mp[]==)puts("");
  375. else printf("%d",x);
  376. }
  377. int _op(node&w){
  378. _ops[w.v]();
  379. }
  380. int _vdim(node&w){
  381. w.vs.defs();
  382. }
  383. int _pc(node&w){
  384. int c=*mp;
  385. putchar(c);
  386. push(c);
  387. return c;
  388. }
  389. void pre2(){
  390. while(tptr<tp){
  391. if(ts[tptr+].tp==&&ts[tptr+].v==)funcs[ts[tptr+].v].Rfunc();
  392. else glob_var.Rs();
  393. }
  394. }
  395. int main(){
  396. _runs[]=_func;
  397. _runs[]=_block;
  398. _runs[]=_expr;
  399. _runs[]=_if;
  400. _runs[]=_while;
  401. _runs[]=_for;
  402. _runs[]=_ret;
  403. _runs[]=_var;
  404. _runs[]=_int;
  405. _runs[]=_call;
  406. _runs[]=_op;
  407. _runs[]=_pc;
  408. _runs[]=_nod;
  409. _runs[]=_vdim;
  410. _ops[]=_arr;
  411. _ops[]=_not;_ops[]=_pos;_ops[]=_neg;
  412. _ops[]=_mul;_ops[]=_div;_ops[]=_mod;
  413. _ops[]=_add;_ops[]=_sub;
  414. _ops[]=_leq;_ops[]=_meq;_ops[]=_lss;_ops[]=_mre;
  415. _ops[]=_eq;_ops[]=_neq;
  416. _ops[]=_xor;
  417. _ops[]=_and;
  418. _ops[]=_or;
  419. _ops[]=_set;
  420. _ops[]=_out;
  421. _ops[]=_in;
  422. rka[]=rka[]=rka[]=rka[]=;
  423. ops["("]=;ops[")"]=;
  424. ops["["]=;ops["]"]=;
  425. ops["{"]=;ops["}"]=;
  426. ops["!"]=;ops["+"]=;ops["-"]=;
  427. ops["*"]=;ops["/"]=;ops["%"]=;
  428. ops["<="]=;ops[">="]=;ops["<"]=;ops[">"]=;
  429. ops["=="]=;ops["!="]=;
  430. ops["^"]=;
  431. ops["&&"]=;
  432. ops["||"]=;
  433. ops["="]=;
  434. ops["<<"]=;ops[">>"]=;
  435. ops[","]=;
  436. ops[";"]=;
  437. kws["if"]=;
  438. kws["else"]=;
  439. kws["while"]=;
  440. kws["for"]=;
  441. kws["int"]=;
  442. kws["return"]=;
  443. vars["cin"]=++vid;
  444. vars["cout"]=++vid;
  445. vars["endl"]=++vid;
  446. funcs[vars["putchar"]=++vid].tp=;
  447. fread(buf,,sizeof(buf),stdin)[buf]=-;
  448. pre();
  449. pre2();
  450. glob_var.ins();
  451. glob_var.ins();
  452. glob_var.ins();
  453. glob_var.def();
  454. run(funcs[vars["main"]]);
  455. return ;
  456. }

bzoj4020: 未来程序·改的更多相关文章

  1. 如何A掉未来程序改

    话说有这样一道神题:[集训队互测2015]未来程序·改. 大意是要求写一个简单的C++解释器!这里去掉了C++的许多特性,连简单的break和continue都没有了! 话说NOI被屠了之后,一时心血 ...

  2. uoj98未来程序改 纯暴力不要想了

    暴力模拟A了,数据还是良(shui)心(shui)的 90分的地方卡了半天最后发现一个局部变量被我手抖写到全局去了,,, 心碎*∞ 没什么好解释的,其实只要写完表达式求值(带函数和变量的),然后处理一 ...

  3. 问题-某个程序改了ICO图标后编译后还是显示老图标?

    问题现象:某个程序改了ICO图标后编译后还是显示老图标? 问题原原:可能是因为系统的缓存问题. 问题处理:把程序的EXE放在别的路径下打开就可以了. 问题相关人员:QQ253120114(朋友)  Q ...

  4. uoj#73 【WC2015】未来程序

    在 2047 年,第 64 届全国青少年信息学奥林匹克冬令营前夕,B君找到了 2015 年,第 32 届冬令营的题目来练习. 他打开了第三题 “未来程序” 这道题目: 本题是一道提交答案题,一共 10 ...

  5. Uoj 73 未来程序

    Uoj 73 未来程序 神仙提答. Subtask 1 仔细阅读,发现是要计算 \(a*b\ \%\ c\).用龟速乘或者 \(python\) 直接算. Subtask 2 仔细阅读并手算一下,发现 ...

  6. VS2013中,将Qt的GUI程序改为控制台程序

    在Visual studio 中创建QT GUI程序是不带Console的,但是调试时候常常需要查看打印信息,可以通过如下设置显示控制台 方法一.在vs中直接创建控制台程序方法二.当你通过设置你的应用 ...

  7. 昨晚值班将发dla的程序改好后放入正式环境

    可是在修改的topic的发送文件中出现有节点没有对应,整个过程陆续调至有20分钟最后11电把新程序换掉.

  8. 四则运算程序扩展:将程序改为java语言,并允许用户输入,对输入结果进行验证

    题目 每个同学选一个方向,把程序扩展一下:1.让程序能接受用户输入答案,并判定对错.最后给出总共对/错 的数量.2.把程序变成一个网页程序,用户通过设定参数,就可以得到各种题目.3.把程序变成一个Wi ...

  9. 小程序--改变子级别页面导航栏信息 / navigationBarTitleText

    微信小程序在公共文件app.json中设置了导航栏相关样式如下: 其中  navigationBarTitleText 为设置导航栏名称,若是想子级页面和父页面的header页面不同,则在子级文件中新 ...

随机推荐

  1. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛-B:Tomb Raider(二进制枚举)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, the fiercely independent daughter of a missing adv ...

  2. 2017.5.11 MapReduce运行机制

    和HDFS一样,MapReduce也是采用Master/Slave的架构 MapReduce1包含4个部分:Client.JobTracker.TaskTracker和Task Client 将JAR ...

  3. 实验吧—安全杂项——WP之 flag.xls

    点击链接下载文件,是一个xls文件 打开: 需要密码的 下一步,我将后缀名改为TXT,然后搜素关键词“flag”,一个一个查找就可以发现啦~!!!(这是最简单的一种方法)

  4. hdu2886 Lou 1 Zhuang 数学/快速幂

    All members of Hulafly love playing the famous network game called 'Lou 1 Zhuang' so much that Super ...

  5. Sencha Touch app example -- oreilly app 分析

    from: 2013/8/30的笔记 使用development.js 读取 app.json 配置文件 app.json 配置了app.js文件 app.js lauch function ,首先用 ...

  6. 手把手教你用MATLAB画灰度直方图

    hist =[1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]     %15个元素      这个行矩阵(数组)输入到命令行 bar(hist) 用列矩阵也行 hist_im=imhis ...

  7. Python——psutil的使用(获取系统性能信息)

    >>> import psutil #导入psutil >>> a=psutil.virtual_memory() >>> a.total #总虚 ...

  8. readv与writev

    [root@bogon mycode]# cat writev.c #include<stdio.h> #include<string.h> #include<unist ...

  9. MySQL Replication--复制异常1

    ============================================== 问题描述: 1.从库环境:MySQL 5.7.19,主从都开启GTID模式 2.MySQL数据目录所有者被 ...

  10. lapis 1.7.0 更好的openresty 版本兼容以及安全数据库支持

    lapis 1.7.0 今年4月2号就发布了,一直没有注意,今天看到changelog就简单的进行了一个 测试(主要是与openresty版本的测试,新变更后边会有) 使用docker-compose ...