码迷,mamicode.com
首页 > 其他好文 > 详细

Brain-Fuck编译器

时间:2018-08-27 14:12:26      阅读:405      评论:0      收藏:0      [点我收藏+]

标签:har   tor   cpp   put   cassert   signed   case   strlen   判断   

用法详见这里
___
为了防止注释中出现关键字,添加了用一对大括号表示注释的功能(注意!这不是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编译器

标签:har   tor   cpp   put   cassert   signed   case   strlen   判断   

原文地址:https://www.cnblogs.com/happyZYM/p/9541634.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!