只需写一个解释器

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

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

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

#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: 未来程序·改的更多相关文章

  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. 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态

    https://blog.csdn.net/kyjl888/article/details/71305149

  2. java list 的遍历

    import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.I ...

  3. POJ 3468:A Simple Problem with Integers(线段树区间更新模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 141093 ...

  4. Laravel学习--时间

    date("Y-m-d H:i:s"); list($usec, $sec) = explode(" ", microtime()); $time = (flo ...

  5. C++学习(二十六)(C语言部分)之 结构体3(联合,枚举)

    结构体 struct 类型定义点运算符 . 变量名.成员 成员是数组的时候不能用等于号赋值箭头运算符 -> 指针->成员 作用 存放多个不同类型的有关联的数据 与结构体类似的类型1.联合作 ...

  6. String、StringBuffer、StringBuidler 知识整理

    String.StringBuffer.StringBuidler.这三个家伙,大家都不陌生,肯定也都会用.三者异同大家都能说出来,但是其根本原因是什么呢?带着下面问题,学习一下. 第一.String ...

  7. Java定时任务调度工具Timer Quartz

      -----------------------------------Timer PS:Timer是 jdk中的:Quartz是第三方的 PS:也即是返回执行任务时候的时间 ----------- ...

  8. sqlyog数据库管理软件下载

    下载安装包 一路next 链接:https://pan.baidu.com/s/1tdIwtYEW11MNWk--Hqd3dw 提取码:0ffp 复制这段内容后打开百度网盘手机App,操作更方便哦 然 ...

  9. linux运维发展路线

  10. h5新增内容

    1.新的input type值 email url search tel color range number date month week time datetime datetime-local ...