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;
}

猜你喜欢

转载自www.cnblogs.com/happyZYM/p/9541634.html