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编译器的主要内容,如果未能解决你的问题,请参考以下文章

Notepad++编辑器——Verilog代码片段直接编译

如何有条件地将 C 代码片段编译到我的 Perl 模块?

导致资产预编译在heroku部署上失败的代码片段

iOS代码片段CodeSnippets

C++ 解释器/控制台/片段编译器

损坏的顶点和片段着色器