Brainfuck

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

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

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

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

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

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

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

// brianfuck to C
#include 
#include 
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 \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'   ';
}

编译运行上述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

你可能感兴趣的:(计算机科学)