只需写一个解释器

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

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

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

#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. python------Json与pickle数据序列化

    一.json序列化 xml在被json取代,不同平台之间的语言转换,只能处理简单的.复杂的用pickle: pickle只能在python中用,而在Java中json也可以被识别. info = { ...

  2. oracle使用flashback时,没有显示undosql

    这是因为oracle11g没有开启这个功能 用管理员用户sys(也就是sysdba)执行以下语句即可 alter databases add supplemental log data; 如果我们想恢 ...

  3. 数学沉思录:古今数学思想的发展与演变 (Mario Livio 著)

    第1章 神秘的数学 (已看) 发现还是发明 第2章 神秘学:命理学家和哲学家 (已看) 毕达哥拉斯 进入柏拉图的洞穴 第3章 魔法师:大师和异端 (已看) 给我一个支点:我将撬起地球 阿基米德重写稿 ...

  4. Day 37 视图、存储过程、触发器、函数、事物、锁

    一 .存储过程 1 create view stu_view as select * from ren 视图:是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据 视图有 ...

  5. 对HTML中的文字的修饰

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 两个简单的API限流实现方案

    1, Ngnix限流 Nginx在架构中起到请求转发与负载均衡器的作用.外部req首先到Nginx监听的80端口,然后Nginx将req交给到监听8080端口的APP服务器处理.处理结果再经由Ngin ...

  7. py-day1-4 python基本数据类型2

    # replace 替换 text = 'xiaomafafafahaoyunlianlian' v = text.replace('fa','shun') x = text.replace('fa' ...

  8. golang bug Unknown load command 0x32 (50)

    问题 编译文件时报错: /usr/local/go/pkg/tool/darwin_amd64/link: /usr/local/go/pkg/tool/darwin_amd64/link: comb ...

  9. Linux yum仓库配置

    yum仓库配置 10.1 概述 YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包 ...

  10. Java MyBatis insert数据库数据后返回主键

    <selectKey keyProperty="id" resultType="java.lang.Long" order="AFTER&quo ...