Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
雰囲気でコンパイラを書いたら大変だった話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
MiZUP
October 20, 2017
Programming
2.5k
2
Share
雰囲気でコンパイラを書いたら大変だった話
2017年10月20日に発表した社内勉強会の資料です
MiZUP
October 20, 2017
More Decks by MiZUP
See All by MiZUP
RUBYでアッカーマン関数の計算をがんばる方法 / How to write ackermann function in ruby
mizukmb
0
1.6k
新卒がオンプレミスとクラウドコンピューティングを触って感じたこと
mizukmb
0
910
Other Decks in Programming
See All in Programming
Codex CLIのSubagentsによる並列API実装 / Parallel API Implementation with Codex CLI Subagents
takatty
2
820
ファインチューニングせずメインコンペを解く方法
pokutuna
0
260
Java 21/25 Virtual Threads 소개
debop
0
320
Reactive ❤️ Loom: A Forbidden Love Story
franz1981
2
220
車輪の再発明をしよう!PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体
h1r0
3
500
Vibe하게 만드는 Flutter GenUI App With ADK , 박제창, BWAI Incheon 2026
itsmedreamwalker
0
200
テレメトリーシグナルが導くパフォーマンス最適化 / Performance Optimization Driven by Telemetry Signals
seike460
PRO
2
220
iOS機能開発のAI環境と起きた変化
ryunakayama
0
140
AI時代の脳疲弊と向き合う ~言語学としてのPHP~
sakuraikotone
1
1.8k
20260320登壇資料
pharct
0
160
PHP 7.4でもOpenTelemetryゼロコード計装がしたい! / PHPerKaigi 2026
arthur1
1
490
The Monolith Strikes Back: Why AI Agents ❤️ Rails Monoliths
serradura
0
110
Featured
See All Featured
Believing is Seeing
oripsolob
1
100
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
330
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
68
38k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
670
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
210
Between Models and Reality
mayunak
3
260
Darren the Foodie - Storyboard
khoart
PRO
3
3.1k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
140
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.2k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.4k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
420
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.6k
Transcript
雰囲気でコンパイラを書いたら 大変だった話 @mizukmb 20, October
コンパイラとは ある規則に沿って書かれた文字列を機械可読可能なコードに翻訳すること var foo = 100; ~~~~~~ ソースコード コンパイル オブジェクト
コード
モチベーション - コンパイラ書いたことがない - コンピュータサイエンスをあまり勉強したことがない - プログラマとして、やっておくべきか… - 枯れた技術の習得 -
この辺の記事を読んで影響を受けている - [二週間で簡単なインタープリタ言語を実装してみた (日記) - プログラムモグモ グ](http://itchyny.hatenablog.com/entry/2017/01/23/100000) - [Cコンパイラをスクラッチから開発してみた(日記) - Qiita](https://qiita.com/ruiu/items/4d471216b71ab48d8b74)
コンパイラの動き
コンパイラの動き 原始プロ グラム 読み込み 字句解析 構文解析 中間語作 成 最適化 コード生成
目的プロ グラム
今回実装した部分 原始プロ グラム 読み込み 字句解析 構文解析 中間語作 成 最適化 コード生成
目的プロ グラム
今回実装した部分 原始プロ グラム 読み込み 字句解析 構文解析 中間語作 成 最適化 コード生成
目的プロ グラム 中間語から Ruby コードを呼び出して直接実行
成果物 mizukmb/my-compiler mizukmb/train-make-ruby-by-ruby - 読み込み〜字句解析〜構文解析〜中間語生成 まで - ↑中間語から Ruby コードを発行し、実行する
- 書籍 『RubyでつくるRuby ゼロから学びなおすプログラミ ング言語入門』 の写経
各処理の詳細
字句解析 規則に沿って並んだ文字や数字の列を意味のある単位に分解していく 空白・インデント・改行などはいい感じに削除する(意味を持たないので) `x = 1 + 10` x …
変数 = … 演算子 1 … 数値リテラル + … 演算子 10 … 数値リテラル
字句解析 - How? 決められた規則を定義する → 決定性有限オートマトンで表現 q2 q0 q1 ‘
英数字 ‘
字句解析 - How? 決められた規則を定義する → 決定性有限オートマトンで表現 →正規表現で書ける `/\A\w*\z/` q2 q0
q1 ‘ 英数字 ‘
字句解析 - How? 種類が定まったらラベルを付けたペアとしてトークンにする ‘foo’ -> (字句解析) -> [‘lit’, ‘foo’]
構文解析 字句解析したトークン列を構文木に変換する [ [ ‘lit’, 1 ], [ ‘op_plus, ‘+’
], [ ‘lit’, 2 ] ] ‘+’ 2 1
構文解析 - How? 解析手法はいっぱいある - 再帰的下向き構文解析 - 上向き構文解析 - LR
構文解析
構文解析 - How? 解析手法はいっぱいある - 再帰的下向き構文解析 ←今回はこれを採用 - 上向き構文解析 -
LR 構文解析
再帰的下向き構文解析 - 解析木を上(根)から下向き(葉に向かって)に作り上げていく - 比較的わかりやすいプログラムが書ける - バックトラック、左再帰性といった問題がある + * 5
[ [ ‘lit’, 5 ], [ ‘op_multi, ‘+’ ], [ ‘lit’, 10 ], [ ‘op_multi’, ‘*’ ], ... ]
再帰的下向き構文解析 - 左再帰性 文法を表現する際、即座に自分自身を呼び出して、無限再帰に陥る問題 ``` E -> E + T
E() { E(); // <- 無限再帰が発生 ‘+’; T(); } ```
再帰的下向き構文解析 - 左再帰性 - 解決策 自分自身を後で読み込むように書き換えれば良い ``` E -> TE’
E’ -> +TE’ | ε T -> i (任意の数列) ```
再帰的下向き構文解析 - バックトラック `A -> α | β` のような「または」という規則があるとき、どちらで解析すればよいか 判断できず、解析に失敗して後戻りが発生してしまうこと。
→解析効率が悪い
再帰的下向き構文解析 - バックトラック - 解決策 解析するトークンのk個先のトークンを先読みして、文法の曖昧さを除去してい く → LL (k)
文法の変換
LL (1) 文法 1個先のトークンを先読みして文法が一意に定まるようになる - First 集合 … 先頭に現れる終端記号の集合 -
Follow 集合 … ある非終端記号の直後に現れる終端記号の集合 - Director 集合 … ある非終端記号を特定の終端記号に展開してよいか判 断できる終端記号の集合 - First 集合と Follow 集合から求まる LL (1) かは全ての Director 集合の積集合が空集合であれば良い
中間語〜コード実行 構文解析済みの中間語を上から順番に実行するだけ 詳しくは書籍『RubyでつくるRuby ゼロから学びなおすプログラミング言語入門 』
製作日記
製作日記 期間: 9月24日〜10月19日
9月24日〜10月10日 様々な誘惑[^1] に負けつつも、書籍『RubyでつくるRuby ゼロから学びなおす プログラミング言語入門』のコードを写経し続ける mizukmb/train-make-ruby-by-ruby [^1]: Splatoon 2, beatmania
IIDX
10月11日 コンパイラを作り始める とりあえず数値リテラルを字句解析できるようにした mizukmb/my-compiler
10月12日 インデントやスペースを使いたかったので大丈夫なように実装 全角スペースも使える。便利ではないと思う mizukmb/my-compiler
10月14日 四則演算ができるように、 + - * / % 演算子を字句解析できるようにした ``` ”1
+ 2" => [[“lit", 1], ["operator_plus", "+"], ["lit", 2]] ``` mizukmb/my-compiler
10月15日 最低限の計算はできるようになったので、数値リテラルと四則演算の構文解析 を実装。四則演算のできる小さなプログラミング言語の完成 ``` ”1 + 2" (字句解析) => [[“lit",
1], ["operator_plus", "+"], ["lit", 2]] (構文解析) => ["+", ["lit", 1], ["lit", 2]] ``` mizukmb/my-compiler
10月16日 数値リテラルと演算子の間にスペースが無くても字句解析できるようにバグ修 正 ``` - 1 + 2 # =>
[["lit", 1], ["operator_plus", "+"], ["lit", 2]] - 1+2 # => [["lit", 1], ["operator_plus", "+"], ["lit", 2]] ``` mizukmb/my-compiler
10月17日 比較演算子 < <= == >= > != の実装 四則演算のときと実装はあまり変わらず。順序だけ気にしていればおk
発表までに FizzBuzz できそう…みたいな叶わぬ夢を見だす mizukmb/my-compiler
10月18日 複文を実装する。字句解析で改行(\n)もトークンとして扱うようにして複文を解 析できるようにした。 ``` “1 + 2\n3 - 4” (字句解析)
=> [[“lit", 1], ["operator_plus", "+"], ["lit", 2], ["newline", "\\n"], ["lit", 3], ["operator_minus", "-"], ["lit", 4]] (構文解析) => [“stmts", ["+", ["lit", 1], ["lit", 2]], ["-", ["lit", 3], ["lit", 4]]] ``` mizukmb/my-compiler
10月18日 - 続き 複文の実装を泥臭くやりすぎて、新しい文の追加や、リファクタリングがやりづ らくなった LL (1) ではない気がする… mizukmb/my-compiler
10月18日 - 続き if 文を実装する。が、前述の通り、複文が動かなくなったり、トークンの読み込 みがおかしくなってすごい悩んだ ``` if (10 >
9 ) { 5 * 100 } ``` mizukmb/my-compiler
10月19日 else を実装しようと試みるが、複文の(ry 実装を断念した。 文字列リテラルを忘れていたので実装 mizukmb/my-compiler
最終成果
最終成果 実装した - 数値、文字列リテラル - 四則演算、比較演算子 - if 文 -
複数式の評価
実演
感想 0からコンパイラ作るのは難しい。けど、オリジナルのプログラミング言語が 様々なプロセスを経て実行されると嬉しい。 一気に実装するのではなく、小さなパーツから少しづつ組み立てていくインクリ メンタルな開発は良かった。コンパイラが少しずつ言葉を覚えて育っていく様子 が見られるのは楽しい
感想(つらい) 理論を十分理解しないまま実装したので途中からコードの設計に無理が出てき た プログラミング言語として実用的ではない。せめて変数は欲しかった
None