Brain-Fuck编译器
Posted happyzym
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Brain-Fuck编译器相关的知识,希望对你有一定的参考价值。
用法详见这里
___
为了防止注释中出现关键字,添加了用一对大括号表示注释的功能(注意!这不是BrainFuck语言标准所定义的!),注释范围从{
开始到第一个}
结尾(注释中有右大括号请用}
)
如这个程序就是输入一行小写字母,并转化为大写字母输出:
,----------{判断是否为换行}[----------------------{转化成大写}.,----------]
,{延迟退出}
这个程序也是合法的:
,----------{判断是否为换行{1,2,3}}[----------------------{转化成大写}.,----------]
{ -------这是注释--------- }
,{延迟退出}
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<stack>
#include<vector>
using namespace std;
char *pro,*p; int len;
char **nxt,**pre;
int file_size(char* filename)
{
FILE *fp=fopen(filename,"r");
if(!fp) return -1;
fseek(fp,0,SEEK_END);
int size=ftell(fp);
fclose(fp);
return size;
}
void compile()
{
nxt=new char*[len+5]; pre=new char*[len+5];
stack<int> stk;
for(int i=0;i<len;i++)
{
switch(pro[i])
{
case ‘[‘: stk.push(i); break;
case ‘]‘:
assert(stk.size());
nxt[stk.top()]=pro+i;
pre[i]=pro+stk.top();
stk.pop();
break;
case ‘{‘:
int pos=i++;
while(i<len&&!(pro[i]==‘}‘&&pro[i-1]!=‘\‘)) i++;
assert(i<len);
nxt[pos]=pro+i;
break;
}
}
}
void run()
{
compile();
vector<unsigned char> mem; mem.push_back(0);
auto it=mem.begin(); p=pro;
while(p<pro+len)
{
switch(*p)
{
case ‘+‘: (*it)++; break;
case ‘-‘: (*it)--; break;
case ‘>‘:
it++;
if(it==mem.end()) { mem.push_back(0); it=mem.end()-1; }
break;
case ‘<‘:
assert(it!=mem.begin());
it--;
break;
case ‘.‘: putchar(*it); break;
case ‘,‘: *it=getchar(); break;
case ‘[‘:
if(!(*it)) p=nxt[p-pro];
break;
case ‘]‘:
if(*it) p=pre[p-pro];
break;
case ‘{‘: p=nxt[p-pro]; break;
}
p++;
}
delete[] nxt; delete[] pre;
}
int main(int argc,char** argv)
{
if(argc==2)
{
char* fname=argv[1];
len=file_size(fname);
pro=new char[len+5]; memset(pro,0,len+5);
FILE *fin=fopen(fname,"rb");
fread(pro,len,1,fin);
run();
}
else
{
const int maxn=10000000;
pro=new char[maxn];
while(fgets(pro,maxn,stdin))
{
len=strlen(pro);
run();
}
}
return 0;
}
以上是关于Brain-Fuck编译器的主要内容,如果未能解决你的问题,请参考以下文章