Brainfuck

Brainfuck 是一门非常简单甚至可以说是最简单的编程语言,wikipedia

它的语法由一个8个字符的字符集组成,即><+=.,[]八个字符。brainfuck的模型还包括一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。
这八个字符每一个都是一条指令:

 >    指针加一
 <    指针减一
 +    指针指向的字节的值加一
 -    指针指向的字节的值减一
 .    按ASCII码输出指针指向字节内容
 ,    按ASCII码输入内容到指针指向字节
 [    如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处
 ]    如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处

brainfuck 是图灵完备的,你可以用它来实现你想实现的任何功能。
brainfuck的hello world程序:

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]
>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

而从上面的语法来看,我们可以将其完全地等效为对应的C语言。

此处输入图片的描述

基于上述语法等效我们可以来写一个brainfuck to C的解释器。其实就是读取字符处理就OK了,一个switch...case不能更简单。再简单处理一下对齐,保持良好的可读性(然而这并不会使我们更容易理解brainfuck编译出来的c程序)。
实现:

// brianfuck to C
#include <fstream>
#include <string>
using namespace std;
const int max_box_size = 3000;

ifstream fin;
ofstream fout;
void translate_to_c(const char * file_name);
void retract(int n);

int main(int argc, char const *argv[])
{
    for (int i = 0; i < argc; ++i)
    {
        translate_to_c(argv[i]);
    }
    return 0;
}

void translate_to_c(const char * file_name)
{
    fin.open(file_name);
    string target_file_name = file_name;
    target_file_name += ".c";
    fout.open(target_file_name);
    fout << "// file_name : " << target_file_name << endl;
    fout << "// This file is a c soucrce file interpreted from brainfuck souce file " << file_name << ".\n";
    fout << "#include <stdio.h>\n" << "#define max_box_size " << max_box_size << endl;
    fout << "char box[max_box_size];\n";
    fout << "char *ptr = box;\n";
    fout << "int main()\n{\n";
    char ch;
    int retract_num = 1;
    while(fin.get(ch))
    {
        switch(ch)
        {
            case '>': retract(retract_num); fout << "++ptr;\n";  break;
            case '<': retract(retract_num); fout << "--ptr;\n";  break;
            case '+': retract(retract_num); fout << "++*ptr;\n"; break;
            case '-': retract(retract_num); fout << "--*ptr;\n"; break;
            case '.': retract(retract_num); fout << "putchar(*ptr);\n";   break;
            case ',': retract(retract_num); fout << "*ptr=getchar();\n";  break;
            case '[': retract(retract_num++); fout << "while (*ptr) {\n";   break;
            case ']': retract(--retract_num); fout << "}\n"; break;
        }
    }
    fout << "\n return 0;" << endl;
    fout << "}\n";
    fin.close();
    fout.close();
}

void retract(int n)
{
    for(int i=0;i<n;i++)
        fout << '   ';
}

编译运行上述cpp程序,得到可执行文件,命令行环境下将待解释的brainfuck文件作为参数,执行命令便可得到对应的C程序。保存上述文件为bftoc.cpp,helloworld存为hello.bf

g++ -o bftoc bftoc.cpp
./bftoc hello.bf
gcc -o hello.out hello.bf.c
./hello.out

hello world!

一个在线的brainfuck可视化执行工具:brainfuck-visualizer

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值