BrainFuck--只有八种指令、符合图灵完全思想的编程语言
2011-11-27 22:01 会被淹死的鱼 阅读(3785) 评论(2) 编辑 收藏 举报官方网站: http://www.muppetlabs.com/~breadbox/bf/
BrainFuck, (An Eight-Instruction Turing-Complete Programming Language), 这个语言本身的语言模型很简单, 有一个byte指针, 有一个初始化为0长度为30000 bytes的数组, byte指针可以在数组内任意移动, 支持下面的八种操作, 指针初始化指向数组的开始. 这个语言只是作者为了写一个很简单的编译器, 才设计的一门语言, 语言和名字一样, 很难读懂, 简单的一些操作用BrainFuck来写都很复杂难读.
八种操作符定义如下(来自百度百科):
字符 | 含义 |
> | 指针加一 |
< | 指针减一 |
+ | 指针指向的字节的值加一 |
- | 指针指向的字节的值减一 |
. | 输出指针指向的单元内容(ASCII码) |
, | 输入内容到指针指向的单元(ASCII码) |
[ | 如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处 |
] | 如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处 |
Brainfuck程序可以用下面的替换方法翻译成C语言(假设ptr是char*类型):
Brainfuck | C |
> | ++ptr; |
< | --ptr; |
+ | ++*ptr; |
- | --*ptr; |
. | putchar(*ptr); |
, | *ptr =getchar(); |
[ | while (*ptr) { |
] | } |
下面看一下BrainFuck的Hello World!程序代码
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.
这段代码看似很诡异, 但是在BrainFuck编译器中输出的确实是Hello World!
字符输出是根据ASCII表.
百度百科上有一些基本操作的介绍, 我这里主要就解释一下这个Hello World!程序的结构.
一个简单的循环结构
++[>++<-]>.
上面使用了两个byte, 第一个byte用来存储循环的次数, []表示一个循环, >移到了第二个比娅特上, 操作第二个byte, 连加两次,<回到第一个byte上减1, 保证可以退出循环. 这就是2X2次循环, 就是第二个byte变成4, 第一个byte变成0. >移到第二个byte上, .是输出这个byte.
byte输出字符是依照了ASSIC表的, H是72, 所以输出H就可以这样写
++++++++[>+++++++++<-]>.
把第一个byte和第二个byte调换一下位置, 第二个byte作为循环条件判断, 操作第一个byte并输出.
>++++++++[<+++++++++>-]<.
输出H也可以使用蛮力的方式, 72个+, 然后输出就是H, 不过这种东西更难读懂了.
上面的Hello World!就是循环操作, 还有几种其他Hello World!的写法.
1.
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
<.>+++++++++++[<++++++++>-]<-.--------.+++.------.--------.[-]>++++++++[<++++>-
]<+.[-]++++++++++.
2.
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.
都是大同小异的, 上面两个用到了一个这样的操作[-], 这个操作是清零当前byte, []退出的条件是当前byte为0, 减到0才会退出循环.
可以尝试着看看, 这个语言还是挺有意思的, 和名字一样, 真的是很难看懂.
下载:
BrainFuck解析器(带有一些例子): DBFI.zip
里面的例子有加法等, 也有HelloWorld的例子, 而且有多种版本, 有兴趣的可以研究下.