Page personnelle de Nicolas Favre-Félix

Compilateur Brainfuck et dérivés

Description

Introduction

Cette page présente un projet de compilateur Brainfuck générant un programme exécutable ELF. L'exécutable généré se lance sur une plateforme Linux, et n'est lié avec aucune librairie externe. De par la nature des appels systèmes effectués, le programme généré n'est pas portable sur un autre système que Linux.

Introduction au langage

Le langage Brainfuck comporte 8 instructions, codées sur un octet chacune. Elles permettent de manipuler un tableau d'octets, à l'aide d'un pointeur. Le programmeur ne dispose que de ce pointeur pour faire toutes ses opérations.
Le langage Ook utilise les mêmes instructions, mais est destiné aux orang-outans.
Le langage Spoon utilise des mots composées des caractères 0 et 1.
Le langage F*ckF*ck utilise des jurons.
Tous ces langages sont équivalents.


BF Description
+ Incrémente l'élément pointé
- Décrémente l'élément pointé
> Pointe sur l'élément suivant
< Pointe sur l'élément précédent
, Lit un caractère au clavier et le range dans l'élément pointé
. Affiche à l'écran le caractère pointé
[ Commence une boucle
] Boucle tant que le caractère pointé n'est pas nul

Ook Description
Ook. Ook. Incrémente l'élément pointé
Ook! Ook! Décrémente l'élément pointé
Ook. Ook? Pointe sur l'élément suivant
Ook? Ook. Pointe sur l'élément précédent
Ook. Ook! Lit un caractère au clavier et le range dans l'élément pointé
Ook! Ook. Affiche à l'écran le caractère pointé
Ook! Ook? Commence une boucle
Ook? Ook! Boucle tant que le caractère pointé n'est pas nul

Spoon Description
1 Incrémente l'élément pointé
000 Décrémente l'élément pointé
010 Pointe sur l'élément suivant
011 Pointe sur l'élément précédent
0010110 Lit un caractère au clavier et le range dans l'élément pointé
001010 Affiche à l'écran le caractère pointé
00100 Commence une boucle
0011 Boucle tant que le caractère pointé n'est pas nul

F*ckF*ck Description
b**b Incrémente l'élément pointé
t**s Décrémente l'élément pointé
f**k Pointe sur l'élément suivant
s**g Pointe sur l'élément précédent
k**b Lit un caractère au clavier et le range dans l'élément pointé
c**k Affiche à l'écran le caractère pointé
a**e Commence une boucle
b**t Boucle tant que le caractère pointé n'est pas nul
! Répète le dernier mot

Exemples :

Hello, World en Brainfuck:

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

Hello, World en Ook:

Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook! Ook. Ook! Ook? Ook! Ook! Ook? Ook! Ook. Ook. Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook.Ook. Ook. Ook! Ook.

Hello, World en Spoon:

1 1 1 1 1 1 1 1 1 1 00100 010 1 1 1 1 1 1 1 010 1 1 1 1 1 1 1 1 1 1 010 1 1 1 010 1 011 011 011 011 000 0011 010 1 1 001010 010 1 001010 1 1 1 1 1 1 1 001010 001010 1 1 1 001010 010 1 1 001010 011 011 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 001010 010 001010 1 1 1 001010 000 000 000 000 000 000 001010 000 000 000 000 000 000 000 000 001010 010 1 001010 010 001010

Hello, World en F*ckF*ck:

B*ob B.ob B66b!!!!!!! aR5e f.ck Bccb!!!!!! fuck B''b!!!!! !!!! fsck B??b!! fnak Boob sh4g !!! t1ts boot fprk Banb ! c0kk ftck B11b c0ck B00b !!!!!! c0ck! Blob!! c0ck f0ck Bolb! c0ck sh3g! Bzob!!!!!!!!!!!!!! c0ck f.ck clik Bo ob!! c:ck t1ts!!!!! c% ck tips!!!!!!! czck fhck Bghb cick fhuk c%ck

L'éditeur ed [EN] en Brainfuck :

+[[,----------][-]+++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++.[-]++++++++++.+]

Analyseur syntaxique :

L'analyseur syntaxique et grammatical utilise GNU Flex et GNU Bison. Seules 8 règles sont utilisées, une par instruction. Les caractères ne faisant pas partie du langage sont ignorés. Le compilateur prend sur la ligne de commande une liste de fichiers source à compiler, et génère a.out, le programme ELF exécutable. Le binaire du ELF est généré à la volée, sans vérification de la validité des instructions, ou de la sécurité du programme.

Génération de code :

L'en-tête ELF est directement généré, la taille finale de l'exécutable étant précisée à la fin. Afin de rendre le programme le plus petit possible, des parties non indispensables de l'en-tête ont été supprimées. C'est pourquoi file prévient des erreurs :

$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, corrupted section header size

Il est toutefois possible de l'exécuter :

$ cat hw.bf
++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++. >.+++.------.--------.>+.>.
$ ./compilo-bf -B hw.bf
$ ./a.out
Hello World!
$ wc -c a.out
460 a.out

Le programme généré fait 460 octets.

Télécharger les sources

Au format tar.gz