BrainFuck——C实现BrainFuck解释器

首先介绍一下吊炸天的语言——BrainFuck


Brainfuck是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf**k,甚至被简称为BF

这种语言基于一个简单的机器模型,除了指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。
这种语言,是一种按照“Turing complete(完整图灵机)”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言,BrainF**k 语言只有八种符号,所有的操作都由这八种符号的组合来完成


BrainFuck——C实现BrainFuck解释器_第1张图片


(按照更节省时间的简单说法,"]"也可以说成“向后跳转到对应的"["状态”。这两解释是一样的。)
(第三种同价的说法,"["意思是"向前跳转到对应的"]"",]意思是"向后跳转到对应的[指令的次一指令处,如果指针指向的字节非零。")
Brainfuck程序可以用下面的替换方法翻译成C语言(假设ptr是char*类型):


BrainFuck——C实现BrainFuck解释器_第2张图片


当前位置清零
[-] 将当前指针的值归零
之前位置清零
[[-]<] 将当前指针以及之前的指针归零
字符I/O
,. 从键盘读取一个字符并输出到屏幕上。
简单的循环
,[.,] 这是一个连续从键盘读取字符并回显到屏幕上的循环。注意,这里假定0表示输入结束,事实上有些系统并非如此。以-1和"未改变"作为判断依据的程序代码分别是",+[-.,+]"和",[.[-],]"。
指针维护
>,[.>,] 通过移动指针保存所有的输入,供后面的程序使用。
加法
[->+<]
把当前位置的值加到后面的单元中(破坏性的加,它导致左边的单元被归零)。



为了方便我们理解BrainFuck语言,大家可以下载一个很好的编译器,里面还有很多demo

http://download.csdn.net/detail/sm9sun/9721483

下面给出两个示例:


一、程序输出hello word!


BF代码:++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.

BrainFuck——C实现BrainFuck解释器_第3张图片


程序输出小于输入数字的所有质数

BF代码:>++++++++[<++++++++>-]<++++++++++++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++++.[-]>++++++++++[<++++++++++>-]<+++++.[-]>++++++++++[<++++++++++>-]<+++++++++.[-]>++++++++++[<++++++++++>-]<+.[-]>++++++++++[<++++++++++>-]<+++++++++++++++.[-]>+++++[<+++++>-]<+++++++.[-]>++++++++++[<++++++++++>-]<+++++++++++++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++.[-]>+++++[<+++++>-]<+++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++++++.[-]>++++++++++[<++++++++++>-]<+++++++++++.[-]>+++++++[<+++++++>-]<+++++++++.[-]>+++++[<+++++>-]<+++++++.[-]+[->,----------[<+>-------------------------------------->[>+>+<<-]>>[<<+>>-]<>>>+++++++++[<<<[>+>+<<-]>>[<<+>>-]<[<<+>>-]>>-]<<<[-]<<[>+<-]]<]>>[<<+>>-]<<>+<-[>+[>+>+<<-]>>[<<+>>-]<>+<-->>>>>>>>+<<<<<<<<[>+<-<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<<<>[>>+>+<<<-]>>>[<<<+>>>-]<<<<>>>[>+>+<<-]>>[<<+>>-]<<<[>>>>>+<<<[>+>+<<-]>>[<<+>>-]<[>>[-]<<-]>>[<<<<[>+>+<<-]>>[<<+>>-]<>>>-]<<<-<<-]+>>[<<[-]>>-]<<>[-]<[>>>>>>[-]<<<<<<-]<<>>[-]>[-]<<<]>>>>>>>>[-<<<<<<<[-]<<[>>+>+<<<-]>>>[<<<+>>>-]<<<>>[>+<-]>[[>+>+<<-]>>[<<+>>-]<>+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>-]<<-<-]+++++++++>[<->-]<[>+<-]<[>+<-]<[>+<-]>>>[<<<+>>>-]<>+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]>>>>[<<<<+>>>>-]<<<<>[-]<<+>]<[[>+<-]+++++++[<+++++++>-]<-><.[-]>>[<<+>>-]<<-]>++++[<++++++++>-]<.[-]>>>>>>>]<<<<<<<<>[-]<[-]<<-]++++++++++.[-]



BrainFuck——C实现BrainFuck解释器_第4张图片

BrainFuck——C实现BrainFuck解释器_第5张图片


是不是很神奇?


下面我们具体说一下思路:

假设我们要打印一个'A'  A对应的ascii码为65,当然我们也可以用65个+,不过这样比较LOW

我们先用++++++表示把第一个空间增加到6,然后以此为循环进入第二个空间

每次循环让其加10,即++++++ [ > ++++++++++ < - ] > 

此时我们在后面加一个.   运行一下++++++ [ > ++++++++++ < - ] > .输出的应该是一个<,即ascii为60

BrainFuck——C实现BrainFuck解释器_第6张图片


然后我们再在后面加5个+就能输出A了

BrainFuck——C实现BrainFuck解释器_第7张图片


好了下面我们输出一个I LOVE YOU试试

还是根据上面的原理,首先I(73),我们把他当作8*9+1来处理,即:++++++++ [ > +++++++++ < - ] > +.

之后我们可以将其变成空格(32),除了直接减去差值以外我们也可以将其归零然后重新赋值,用[-]归零,再加32

即:++++++++ [ > +++++++++ < - ] > +.[-]++++ [ > ++++++++ < - ] > .

然后写L(76),注意,当前值为32,我们可以使其加到38再*2,即:++++++++ [ > +++++++++ < - ] > +.[-]++++ [ > ++++++++ < - ] >.++++++[>++<-]>.

此时你应该输出的I L,看看是不是~~

BrainFuck——C实现BrainFuck解释器_第8张图片

所以~BrainFuck语言实现起来非常的自由,具体怎样写最简洁最大气就要看你的智商啦~~

接着我们再完成下面的字符输出

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

BrainFuck——C实现BrainFuck解释器_第9张图片



C语言实现解释器代码:

#define  _CRT_SECURE_NO_WARNINGS
#include 
#include 
char s[30000]={0};
char code[100000];
int len = 0;
int stack[100];
int stack_len=0;
int main(int argc,char**argv)
{
    char c;
    int i=0,j,k,x=0;
    FILE* f;
    char* p=s+10000;
   
    f=fopen(argv[1],"r");
        
    while(fread(&code[len],1,1,f)==1)
	{
        len++;
    }
    setbuf(stdout,NULL);
    while(i':
                p++;
                break;
            case '<':
                p--;
                break;
            case '.':
                putchar((int)(*p));
                //printf("put:%hdn",*p);
                break;
            case ',':
                *p=getchar();
                break;
            case '[':
                if(*p) {
                    stack[stack_len++]=i;
                } else {
                    for(k=i,j=0;k

注:网上相关代码很多,但是大多数都有一个BUG,就是对于嵌套循环即[[]]这样的处理有误。

大家也可以测试输出质数的这个源码,其正好有一个嵌套循环。

BrainFuck——C实现BrainFuck解释器_第10张图片






然后我们也可以把BF代码保存为二进制文本,后缀名为bf(随便你啦)

再将我们的程序关联上


BrainFuck——C实现BrainFuck解释器_第11张图片


最后再让我们输出一下I LOVE YOU


BrainFuck——C实现BrainFuck解释器_第12张图片BrainFuck——C实现BrainFuck解释器_第13张图片



好啦~大家现在又学会了一种语言说“我爱你”,还不赶紧去跟妹子表(zhuang)白(bi)~科科

BrainFuck——C实现BrainFuck解释器_第14张图片






你可能感兴趣的:(BrainFuck,C/C++,BrainFuck,另类语言,BF,BF解释器,C++)