Brainfuck コンパイラの自作 第1回 - 基本設計と環境構築
1. はじめに
Brainfuck は、極端にシンプルな命令セットを持つ難解プログラミング言語(esolang)です。本記事では、Brainfuck のコンパイラを自作する方法を解説します。
なぜ Brainfuck コンパイラを作るのか?
- 低レベルプログラミングの理解:Brainfuck は単純な命令セットを持ち、メモリ操作を学ぶのに適している
- コンパイラ設計の基礎:コードの解析・変換・最適化の流れを学ぶ
- 言語処理系の開発体験:小規模ながらも、実際に動作するコンパイラを作成できる
この記事で学べること
2. Brainfuck の基本
Brainfuck は以下の 8つの命令 しかありません。
コマンド | 説明 |
---|---|
> |
ポインタを右へ移動 |
< |
ポインタを左へ移動 |
+ |
ポインタの指す値を1増加 |
- |
ポインタの指す値を1減少 |
. |
ポインタの指す値をASCII文字として出力 |
, |
1文字入力し、ポインタの指すセルに格納 |
[ |
もし現在の値が0なら対応する ] へジャンプ |
] |
もし現在の値が0でなければ対応する [ へジャンプ |
例:Hello, World! を出力
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++. >++.<<+++++++++++++++.>.+++.------.--------.>+.>.
3. コンパイラの基本設計
Brainfuck コンパイラの役割は、Brainfuck のコードをより実行しやすい形式(例えば C 言語やアセンブリ)に変換することです。
コンパイラの主要な処理
- 字句解析(Lexing)
Brainfuck のコードを1文字ずつ読み取り、トークン(意味のある単位) に分解する - 構文解析(Parsing)
[
と]
の対応を解析し、適切なジャンプ処理を管理する - コード変換(Code Generation)
- 最適化(Optimization)(今回は基本設計のため省略)
コンパイル方式
今回は、Brainfuck を C 言語に変換し、C コンパイラを使って実行可能なバイナリを生成する方法を採用します。
4. 環境構築
必要なもの
コンパイラの開発ファイル
プロジェクト構成:
brainfuck_compiler/ ├── main.cpp (Brainfuck コンパイラのメインファイル) ├── parser.cpp (構文解析用) ├── generator.cpp (コード変換用) ├── Makefile (ビルド用)
main.cpp
(最小限の C++ のエントリポイント)
#include <iostream> #include <fstream> #include <string> int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "使い方: " << argv[0] << " <brainfuckファイル>\n"; return 1; } std::ifstream file(argv[1]); if (!file) { std::cerr << "ファイルを開けませんでした: " << argv[1] << "\n"; return 1; } std::string code((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); std::cout << "読み込んだコード:\n" << code << std::endl; return 0; }
これを g++
でコンパイルし、Brainfuck のコードを読み込むことができるか確認します。
g++ main.cpp -o bf_compiler ./bf_compiler sample.bf
5. まとめと次回の予定
今回は、Brainfuck コンパイラの基本設計と環境構築を行いました。
今回のまとめ
✅ Brainfuck の基本命令
✅ コンパイラの設計(Lexing, Parsing, Code Generation)
✅ C++ での開発環境構築