bzoj4020: 未来程序·改
只需写一个解释器
第一次预处理将输入进行分词,分割出 关键字,运算符,变量/函数名,整数常量,并对变量/函数名离散化以便处理
第二次预处理建语法树,每个节点存节点类型,变量定义表等信息
运行时在语法树上递归处理,维护一个栈存运行中用到的变量
- #include<cstdio>
- #include<map>
- #include<string>
- #include<vector>
- #include<cstring>
- using namespace std;
- int mem[],*mp=mem;
- char buf[],*ptr=buf;
- char stk[];
- int stp=;
- map<string,int>ops,kws,vars;
- int vid=;
- int rk[]={,,,,,,,,,,,,,,,,,,,,,,,,,,,};
- int rka[];
- struct token{
- int tp;//operator:0 integer:1 var_name:2 keyword:3
- int v;
- void init2(){
- tp=;
- string a(stk);
- if(kws.find(a)!=kws.end()){
- tp=;
- v=kws[a];
- }else if(vars.find(a)!=vars.end()){
- v=vars[a];
- }else{
- v=vars[a]=++vid;
- }
- }
- void init1(int x){
- tp=;
- v=x;
- }
- void init0(){
- tp=;
- v=ops[string(stk)];
- if((v==||v==)&&(this[-].tp==||this[-].tp==||this[-].eq(,)||this[-].eq(,)))v+=;
- }
- bool eq(int a,int b){
- return tp==a&&v==b;
- }
- }ts[];
- int tp=,tptr=;
- bool isname(char x){
- return isalpha(x)||isdigit(x)||x=='_'||x=='$';
- }
- int _n,__in[],_inp=;
- int _ri(){
- int x=,f=;
- while(!isdigit(*ptr))*ptr++=='-'?f=-:;
- while(isdigit(*ptr))x=x*+*ptr++-;
- return x*f;
- }
- void pre(){
- _n=_ri();
- for(int i=;i<_n;++i)__in[i]=_ri();
- for(;*ptr!=';';++ptr);++ptr;
- while(){
- for(;*ptr!=-&&*ptr<;++ptr);
- if(*ptr==-)break;
- stp=;
- if(isalpha(*ptr)){
- for(;isname(*ptr);stk[stp++]=*ptr++);stk[stp]=;
- ts[tp++].init2();
- }else if(isdigit(*ptr)){
- ts[tp++].init1(_ri());
- }else{
- stk[stp++]=*ptr++;
- stk[]=*ptr;
- stk[]=;
- if(ops.find(string(stk))!=ops.end())++ptr;
- else stk[]=;
- ts[tp].init0();++tp;
- }
- }
- }
- #define ptr __
- struct var{
- int id,*dat,sz;
- vector<int>dsz;
- var(){sz=,id=;}
- void newdim(int x){
- dsz.push_back(x);
- sz*=x;
- }
- };
- vector<var>var_now[];
- struct varlist{
- std::vector<var>vs;
- void def(bool init=){
- for(int i=;i<vs.size();++i){
- var&w=vs[i];
- if(init)memset(mp,,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=;i<vs.size();++i){
- var&w=vs[i];
- memset(mp,,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=;i<vs.size();++i){
- var_now[vs[i].id].pop_back();
- mp-=vs[i].sz;
- }
- }
- void undefs(){
- int mx=*--mp;
- for(int i=;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(,);tptr+=)w.newdim(ts[tptr+].v);
- vs.push_back(w);
- }
- void Rs(){
- for(++tptr;;){
- R();
- if(ts[tptr++].v==)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=,v=ts[tptr++].v;}
- void Rint(){tp=,v=ts[tptr++].v;}
- void setop(int w){tp=,v=w;}
- void Rcall(){
- tp=;
- v=ts[tptr].v;
- tptr+=;
- while(!ts[tptr-].eq(,))rspb().Rexpr();
- }
- void setvdim(int L,int R,varlist&w){
- tp=;
- for(int i=L;i<R;++i)vs.vs.push_back(w.vs[i]);
- }
- void Rexpr(){
- tp=;
- vector<int>ops;
- ops.push_back();
- while(){
- if(ts[tptr].tp==){//oper
- if(ts[tptr].v>=){
- while(ops.back()){
- rspb().setop(ops.back());
- ops.pop_back();
- }
- break;
- }
- int v=ts[tptr].v;
- if(v==||v==)ops.push_back(v);
- else if(v==){
- while(ops.back()){
- rspb().setop(ops.back());
- ops.pop_back();
- }
- ops.pop_back();
- if(ops.empty())break;
- }else if(v==){
- int c;
- do{
- c=ops.back();
- rspb().setop(c);
- ops.pop_back();
- }while(c!=);
- }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==)rspb().Rint();//int
- else if(ts[tptr+].eq(,))rspb().Rcall();//call func
- else rspb().Rvar();//var
- }
- ++tptr;
- }
- void Rkw(){
- if(ts[tptr].v==){//if
- tp=;
- tptr+=;
- rspb().Rexpr();
- rspb().Rblock();
- if(ts[tptr].eq(,)){//else
- ++tptr;
- rspb().Rblock();
- }
- }else if(ts[tptr].v==){//while
- tp=;
- tptr+=;
- rspb().Rexpr();
- rspb().Rblock();
- }else if(ts[tptr].v==){//for
- tp=;
- tptr+=;
- rspb();
- if(ts[tptr].eq(,))vs.Rs(),rs.back().tp=;
- else rs.back().Rexpr();
- rspb().Rexpr();
- rspb().Rexpr();
- rspb().Rblock();
- }else{//return
- tp=;
- ++tptr;
- rspb().Rexpr();
- }
- }
- void Rblock(){
- if(!ts[tptr].eq(,)){
- if(ts[tptr].tp==)Rkw();
- else Rexpr();
- return;
- }
- tp=;
- ++tptr;
- while(!ts[tptr].eq(,)){
- if(ts[tptr].tp==){
- if(ts[tptr].v==){
- 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=;
- tptr+=;
- if(ts[tptr].eq(,))++tptr;
- else do{
- ++tptr;
- vs.R();
- }while(!ts[tptr++].eq(,));
- rspb().Rblock();
- }
- }funcs[];
- #define run(x) _runs[x.tp](x)
- int (*_runs[])(node&);
- void (*_ops[])();
- bool ret_flag=;
- int _func(node&w){
- w.vs.def();
- int r=run(w.rs[]);
- w.vs.undef();
- ret_flag=;
- void push(int);
- push(r);
- return r;
- }
- int _block(node&w){
- *mp++=;
- int r=;
- for(int i=;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 ;
- for(int i=;i<w.rs.size();++i)run(w.rs[i]);
- int&pop();
- return pop();
- }
- int _if(node&w){
- int r=;
- if(run(w.rs[]))r=run(w.rs[]);
- else if(w.rs.size()==)r=run(w.rs[]);
- return r;
- }
- int _while(node&w){
- int r=;
- while(!ret_flag&&run(w.rs[]))r=run(w.rs[]);
- return r;
- }
- int _for(node&w){
- int r=;
- w.vs.def();
- for(run(w.rs[]);!ret_flag&&run(w.rs[]);run(w.rs[]))r=run(w.rs[]);
- w.vs.undef();
- return r;
- }
- int _ret(node&w){
- int r=run(w.rs[]);
- ret_flag=;
- return r;
- }
- int _var(node&w){
- mp[]=w.v;
- mp[]=;
- mp[]=;
- mp+=;
- }
- void push(int x){
- mp[]=-;
- mp[]=x;
- mp[]=;
- mp+=;
- }
- int _int(node&w){
- push(w.v);
- }
- int _nod(node&w){}
- int _call(node&w){
- for(int i=;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-=;
- return *mp<?mp[]:var_now[*mp].back().dat[mp[]];
- }
- void _arr(){
- int x=pop();
- mp[-]*=var_now[mp[-]].back().dsz[mp[-]++];
- mp[-]+=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==)
- 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[]==)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+].tp==&&ts[tptr+].v==)funcs[ts[tptr+].v].Rfunc();
- else glob_var.Rs();
- }
- }
- int main(){
- _runs[]=_func;
- _runs[]=_block;
- _runs[]=_expr;
- _runs[]=_if;
- _runs[]=_while;
- _runs[]=_for;
- _runs[]=_ret;
- _runs[]=_var;
- _runs[]=_int;
- _runs[]=_call;
- _runs[]=_op;
- _runs[]=_pc;
- _runs[]=_nod;
- _runs[]=_vdim;
- _ops[]=_arr;
- _ops[]=_not;_ops[]=_pos;_ops[]=_neg;
- _ops[]=_mul;_ops[]=_div;_ops[]=_mod;
- _ops[]=_add;_ops[]=_sub;
- _ops[]=_leq;_ops[]=_meq;_ops[]=_lss;_ops[]=_mre;
- _ops[]=_eq;_ops[]=_neq;
- _ops[]=_xor;
- _ops[]=_and;
- _ops[]=_or;
- _ops[]=_set;
- _ops[]=_out;
- _ops[]=_in;
- rka[]=rka[]=rka[]=rka[]=;
- ops["("]=;ops[")"]=;
- ops["["]=;ops["]"]=;
- ops["{"]=;ops["}"]=;
- ops["!"]=;ops["+"]=;ops["-"]=;
- ops["*"]=;ops["/"]=;ops["%"]=;
- ops["<="]=;ops[">="]=;ops["<"]=;ops[">"]=;
- ops["=="]=;ops["!="]=;
- ops["^"]=;
- ops["&&"]=;
- ops["||"]=;
- ops["="]=;
- ops["<<"]=;ops[">>"]=;
- ops[","]=;
- ops[";"]=;
- kws["if"]=;
- kws["else"]=;
- kws["while"]=;
- kws["for"]=;
- kws["int"]=;
- kws["return"]=;
- vars["cin"]=++vid;
- vars["cout"]=++vid;
- vars["endl"]=++vid;
- funcs[vars["putchar"]=++vid].tp=;
- fread(buf,,sizeof(buf),stdin)[buf]=-;
- pre();
- pre2();
- glob_var.ins();
- glob_var.ins();
- glob_var.ins();
- glob_var.def();
- run(funcs[vars["main"]]);
- return ;
- }
bzoj4020: 未来程序·改的更多相关文章
- 如何A掉未来程序改
话说有这样一道神题:[集训队互测2015]未来程序·改. 大意是要求写一个简单的C++解释器!这里去掉了C++的许多特性,连简单的break和continue都没有了! 话说NOI被屠了之后,一时心血 ...
- uoj98未来程序改 纯暴力不要想了
暴力模拟A了,数据还是良(shui)心(shui)的 90分的地方卡了半天最后发现一个局部变量被我手抖写到全局去了,,, 心碎*∞ 没什么好解释的,其实只要写完表达式求值(带函数和变量的),然后处理一 ...
- 问题-某个程序改了ICO图标后编译后还是显示老图标?
问题现象:某个程序改了ICO图标后编译后还是显示老图标? 问题原原:可能是因为系统的缓存问题. 问题处理:把程序的EXE放在别的路径下打开就可以了. 问题相关人员:QQ253120114(朋友) Q ...
- uoj#73 【WC2015】未来程序
在 2047 年,第 64 届全国青少年信息学奥林匹克冬令营前夕,B君找到了 2015 年,第 32 届冬令营的题目来练习. 他打开了第三题 “未来程序” 这道题目: 本题是一道提交答案题,一共 10 ...
- Uoj 73 未来程序
Uoj 73 未来程序 神仙提答. Subtask 1 仔细阅读,发现是要计算 \(a*b\ \%\ c\).用龟速乘或者 \(python\) 直接算. Subtask 2 仔细阅读并手算一下,发现 ...
- VS2013中,将Qt的GUI程序改为控制台程序
在Visual studio 中创建QT GUI程序是不带Console的,但是调试时候常常需要查看打印信息,可以通过如下设置显示控制台 方法一.在vs中直接创建控制台程序方法二.当你通过设置你的应用 ...
- 昨晚值班将发dla的程序改好后放入正式环境
可是在修改的topic的发送文件中出现有节点没有对应,整个过程陆续调至有20分钟最后11电把新程序换掉.
- 四则运算程序扩展:将程序改为java语言,并允许用户输入,对输入结果进行验证
题目 每个同学选一个方向,把程序扩展一下:1.让程序能接受用户输入答案,并判定对错.最后给出总共对/错 的数量.2.把程序变成一个网页程序,用户通过设定参数,就可以得到各种题目.3.把程序变成一个Wi ...
- 小程序--改变子级别页面导航栏信息 / navigationBarTitleText
微信小程序在公共文件app.json中设置了导航栏相关样式如下: 其中 navigationBarTitleText 为设置导航栏名称,若是想子级页面和父页面的header页面不同,则在子级文件中新 ...
随机推荐
- ACM/ICPC 2018亚洲区预选赛北京赛站网络赛-B:Tomb Raider(二进制枚举)
时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, the fiercely independent daughter of a missing adv ...
- 2017.5.11 MapReduce运行机制
和HDFS一样,MapReduce也是采用Master/Slave的架构 MapReduce1包含4个部分:Client.JobTracker.TaskTracker和Task Client 将JAR ...
- 实验吧—安全杂项——WP之 flag.xls
点击链接下载文件,是一个xls文件 打开: 需要密码的 下一步,我将后缀名改为TXT,然后搜素关键词“flag”,一个一个查找就可以发现啦~!!!(这是最简单的一种方法)
- hdu2886 Lou 1 Zhuang 数学/快速幂
All members of Hulafly love playing the famous network game called 'Lou 1 Zhuang' so much that Super ...
- Sencha Touch app example -- oreilly app 分析
from: 2013/8/30的笔记 使用development.js 读取 app.json 配置文件 app.json 配置了app.js文件 app.js lauch function ,首先用 ...
- 手把手教你用MATLAB画灰度直方图
hist =[1,2,3,4,5,6,7,8,7,6,5,4,3,2,1] %15个元素 这个行矩阵(数组)输入到命令行 bar(hist) 用列矩阵也行 hist_im=imhis ...
- Python——psutil的使用(获取系统性能信息)
>>> import psutil #导入psutil >>> a=psutil.virtual_memory() >>> a.total #总虚 ...
- readv与writev
[root@bogon mycode]# cat writev.c #include<stdio.h> #include<string.h> #include<unist ...
- MySQL Replication--复制异常1
============================================== 问题描述: 1.从库环境:MySQL 5.7.19,主从都开启GTID模式 2.MySQL数据目录所有者被 ...
- lapis 1.7.0 更好的openresty 版本兼容以及安全数据库支持
lapis 1.7.0 今年4月2号就发布了,一直没有注意,今天看到changelog就简单的进行了一个 测试(主要是与openresty版本的测试,新变更后边会有) 使用docker-compose ...