BrainF**k的C解释器

啦啦啦转载自coolshell.cn,作者陈皓

BF语言介绍

Brainfuck,是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。这种语言有时被称为brainf**kbrainf***,甚至被简称为BF。这种 语言,是一种按照“Turing complete(完整图灵机)”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言,BrainF**k 语言只有八种符号,所有的操作都由这八种符号的组合来完成。

BF基于一个简单的机器模型,除了八个指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。

下面是这八种指令的描述,其中每个指令由一个字符标识:

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

(按照更节省时间的简单说法,]也可以说成“向后跳转到对应的[状态”。这两解释是一样的。)

(第三种同价的说法,[意思是"向前跳转到对应的]“,]意思是”向后跳转到对应的[指令的次一指令处,如果指针指向的字节非零。”)

Brainfuck程序可以用下面的替换方法翻译成C语言(假设ptrchar*类型):

Brainfuck C
> ++ptr;
< --ptr;
+ ++*ptr;
- --*ptr;
. putchar(*ptr);
, *ptr =getchar();
[ while (*ptr) {
] }

BF解释器

#include <stdio.h>
#include <stdlib.h>//exit()函数的头文件

/*hello_world_BF.txt 
out.txt 
*/
int  p, r, q;
char a[5000], f[5000], b, o, *s=f;
 
void interpret(char *c)
{
    char *d;
 
    r++;
    while( *c ) {
        //if(strchr("<>;+-,.[]\n",*c))printf("%c",*c);
        switch(o=1,*c++) {
            case ‘<‘: p--;        break;
            case ‘>‘: p++;       break;
            case ‘+‘: a[p]++;     break;
            case ‘-‘: a[p]--;     break;
            case ‘.‘: putchar(a[p]); fflush(stdout); break;
            case ‘,‘: a[p]=getchar();fflush(stdout); break;
            case ‘[‘:
                for( b=1,d=c; b && *c; c++ )
                b+=*c==‘[‘, b-=*c==‘]‘;
                if(!b) {
                    c[-1]=0;
                    while( a[p] )
                    interpret(d);
                    c[-1]=‘]‘;
                    break;
                }
            case ‘]‘:
                puts("UNBALANCED BRACKETS"), exit(0);
            case ‘#‘:
                if(q>2)
                printf("%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n%*s\n",
                *a,a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],3*p+2,"^");
                break;
            default: o=0;
        }
        if( p<0 || p>100)
            puts("RANGE ERROR"), exit(0);
    }
    r--;
    //        chkabort();
}
 
int main(int argc,char *argv[])
{
    FILE *z;
 
    q=argc;
 
//    if(z=fopen(argv[1],"r")) {
    if(z=fopen("hello_world_BF.txt","r")) {
        while( (b=getc(z))>0 )
            *s++=b;
        *s=0;
        interpret(f);
    }
    
    fclose(z);
    
    return 0;
}

测试样例:

$ cat hello_world_BF.txt

+++ +++ +++ +           initialize counter (cell #0) to 10
[                       use loop to set the next four cells to 70/100/30/10
    > +++ +++ +             add  7 to cell #1
    > +++ +++ +++ +         add 10 to cell #2
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
    <<< < -                 decrement counter (cell #0)
]
>++ .                   print ‘H‘
>+.                     print ‘e‘
+++ +++ +.              print ‘l‘
.                       print ‘l‘
+++ .                   print ‘o‘
>++ .                   print ‘ ‘
<<+ +++ +++ +++ +++ ++. print ‘W‘
>.                      print ‘o‘
+++ .                   print ‘r‘
--- --- .               print ‘l‘
--- --- --.             print ‘d‘
>+.                     print ‘!‘
>.                      print ‘\n‘

Hello World!
$

时间: 2024-09-28 05:20:15

BrainF**k的C解释器的相关文章

Brainf**k(一位数求max)

题目大意:给你两个一位数,要你求出其中的较大值(使用$Brainf**k$) ($Brainf**k$简介,相当于有一个数组和一个指针, 题解:我还是太菜,想了$20$分钟.我构造了一个序列(标号从$0$开始),如下(上面的数字表示这一位的值,$a$为输入的第一个数,$b$为输入的第二个数:下面的数字表示这个位置的标号) 读入时的数列(`>+>,>,,`): $$0\qquad 1\qquad 0\qquad b\qquad 0\qquad 0\qquad 0\\0\qquad 1\qq

6个变态的C语言Hello World程序 之 雷人的程序语言

以下的六个程序片段主要完毕这些事情: 输出Hello, World 混乱C语言的源码 以下的全部程序都能够在GCC下编译通过,仅仅有最后一个须要动用C++的编译器g++才干编程通过. hello1.c 1 2 3 4 5 6 7 8 9 10 11     #define _________ }     #define ________putchar     #define _______ main     #define _(a) ________(a);     #define ______

CTF中那些脑洞大开的编码和加密

0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到类似这样的问题:表哥,你知道这是什么加密吗?其实CTF中脑洞密码题(非现代加密方式)一般都是各种古典密码的变形,一般出题者会对密文进行一些处理,但是会给留一些线索,所以写此文的目的是想给小伙伴做题时给一些参考,当然常在CTF里出现的编码也可以了解一下.本来是想尽快写出参考的文章,无奈期间被各种事情耽搁导致文章断断续续写了2个月,文章肯定有许多没有提及到,欢迎小伙伴补充,总之,希望对小伙伴们有帮助吧! 0x01 目录 1 2 3

所有计算机编程语言的一句话概括

A+:阵列编程语言,由摩根·斯坦利公司在1980年代在APL的基础上开发起来的,现在使用GPL授权. Ada:是一种表现能力很强的通用程序设计语言,它能大大改善软件系统的清晰性, 可靠性, 有效性, 可维护性. Assembly language(汇编语言):是用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,又为符号语言. B语言:是贝尔实验室开发的一种通用的程序设计语言. BF:Brainfuck(BF)是一种极小化的计算机语言,因为f*ck在英语中是脏话,这种语言有时被称为br

介绍一个在线编程和编译网站

在线编程网站 http://www.compileonline.com/ 提供了各种语言编译.运行环境,可大大简化客户端程序安装配置的复杂度,实现即时编程的目的; 当然,如果你想用这些机器的计算资源,也是一个好的途径. 支持的语言包括: Ada (Gnat) Algol-68 Assembly Awk Bash Shell Basic Befunge Brainf**k C C99 Strict COBOL C++ C++11 C++0x C# Clojure Dart D Language E

引入在线编程和编译站点

在线编程网站 http://www.compileonline.com/ 它提供了各种语言的编译器.执行环境.可以大大简化client在安装配置的复杂性.即时编程目的; 当然,假设你想使用这些机器的计算资源,这也是一个好办法. 支持的语言包含: Ada (Gnat) Algol-68 Assembly Awk Bash Shell Basic Befunge Brainf**k C C99 Strict COBOL C++ C++11 C++0x C# Clojure Dart D Langua

BZOI 1507 [NOI2003] Editor

Background After trying to solve problem EDIT1(Editor) and being ****ed by Brainf**k, Blue Mary decided to set another difficult problem about editor. Description Some definations: Text: It's a sequence that consists characters whose ASCII code is in

SPOJ PON - Prime or Not

题目链接:http://www.spoj.com/problems/PON/ 题目大意:判断N是不是素数,N<264-1. 解题思路:需要用到拉宾-米勒素性判定. (选自数论书籍)合数的拉宾-米勒测试:设n是奇素数,记n-1=2kq,q为奇数.对不被n整除的某个a,如果下述两个条件都成立,则n是合数. a): aq !≡ 1 (mod n),  即a的q次方不与1模n同余 b): 对所有i = 0,1,2,--,k-1, a2^i * q !≡ -1 (mod n) 所以可以打出100个素数表然

SPOJ Prime or Not - 快速乘 - 快速幂

Given the number, you are to answer the question: "Is it prime?" Solutions to this problem can be submitted in C, C++, Pascal, Perl, Python, Ruby, Lisp, Hask, Ocaml, Prolog, Whitespace, Brainf**k and Intercal only. Input t – the number of test c