コンパイラのフェーズとは(全体像)
コンパイラは、プログラムの文(ソースコード)を、コンピュータが直接実行できる機械語に翻訳するソフトのこと。この翻訳は、いくつもの段階を順に通る流れ作業(パイプライン)になっている。
身近にたとえると、日本語を英語に翻訳する流れだ。まず文を単語に分け(字句解析)、文の構造(主語・述語など)をつかみ(構文解析)、意味を確かめ(意味解析)、いったん言葉によらない意味のメモにし(中間コード)、表現を整理し(最適化)、最後に英語の文章にする(コード生成)。
押さえるのは、コンパイルは1段階ではなく、6つの段階を順に通るということ。
詳しく:6フェーズの順番と前後の分離だけ覚えれば戦える
ここが記事の心臓部。まず6つのフェーズを順に見ましょう。
コンパイラの6フェーズ(この順)
| 順 | フェーズ | やること |
|---|---|---|
| 1 | 字句解析 | ソースを単語(トークン)に分ける |
| 2 | 構文解析 | 文法の構造を木(AST)にする |
| 3 | 意味解析 | 型のチェックなど意味を確かめる |
| 4 | 中間コード生成 | CPUによらない中間の表現(IR)にする |
| 5 | 最適化 | むだを省いて速く・小さくする |
| 6 | コード生成 | 機械語(CPUの命令)に変換する |
この6つは順番が大事です。字句解析→構文解析→意味解析→中間コード生成→最適化→コード生成と流れます。
次に、この6つは前半と後半に分けて設計されます。
フロントエンドとバックエンド
| 部分 | フェーズ | 何に依存するか |
|---|---|---|
| フロントエンド | 1〜3(字句・構文・意味解析) | 言語に依存(C・Rustなど) |
| バックエンド | 5〜6(最適化・コード生成) | CPUに依存(x86・ARMなど) |
間にある中間コード(IR)はCPUによらない共通の表現で、ここで前後を切り分けます。この分離のおかげで、新しい言語はフロントエンドだけ、新しいCPUはバックエンドだけを作れば、組み合わせて使えます。
最後に、コンパイラの基盤の代表がLLVMとGCC。ここで取り違えやすいのが「LLVM=GCC」という誤解です。
LLVMとGCC
| 基盤 | 特徴 |
|---|---|
| LLVM | 新しい基盤。共通の中間表現を活かす。Clang・Rust・Swiftなど |
| GCC | 伝統的なコンパイラ集。今もLinuxのビルドなどで現役 |
LLVMは比較的新しい基盤、GCCは伝統的な基盤で、設計思想が違います。どちらも現役で並んで使われています。
わかりやすく言い換えると
要するに、翻訳の流れで覚えるとラクです。
①6フェーズ … 単語に分ける→構造をつかむ→意味を確かめる→中間メモにする→整理する→英語にする
②前後の分離 … 前半(フロントエンド)は言語ごと、後半(バックエンド)はCPUごと。間が中間コード
③LLVMとGCC … LLVMは新しい基盤、GCCは伝統的な基盤(どちらも現役)
つまり、「6フェーズの順番」「前は言語・後はCPUで分ける」、この2点が試験の急所です。
試験のツボ
🔴 一番出る:6フェーズの順番
①字句解析→構文解析→意味解析
②中間コード生成→最適化→コード生成
🔴 次に出る:フロントエンドとバックエンドの分離
①フロントエンド(1〜3) = 言語に依存(C・Rustなど)
②バックエンド(5〜6) = CPUに依存(x86・ARMなど)。間が中間コード(IR)
🟡 押さえると安定:LLVMとGCC
①LLVM = 新しい基盤(Clang・Rust・Swiftなど)
②GCC = 伝統的な基盤(Linuxのビルドなどで現役)
よくある間違い
①「コンパイルは1段階で終わる」→ ✗ 6フェーズの流れ作業。前の段階の出力が次の段階の入力になる。
②「LLVMとGCCは同じもの」→ ✗ LLVMは新しい基盤、GCCは伝統的な基盤。設計思想が違い、どちらも現役。
③「フロントエンドはCPUに依存する」→ ✗ フロントエンド(1〜3)は言語に依存。CPUに依存するのはバックエンド(5〜6)。
試験での出題パターン
実際の問題でたしかめてみよう。
オリジナル問題1(6フェーズの順番)
コンパイラのフェーズに関する次の記述のうち、正しいものはどれか。
- コンパイルは字句解析・構文解析・意味解析などの6フェーズを順に通る流れ作業である
- コンパイルは1段階で終わり、字句解析や構文解析といった段階は存在しないものとされる
- コンパイルはコード生成から始めて字句解析で終わる、逆向きの流れとされているものだ
- コンパイルは紙に印刷する手順のことで、機械語への変換とは無関係なものとされている
解答は 1 ですよ。
コンパイルは字句解析・構文解析・意味解析などの6フェーズを順に通る流れ作業ですね。前の段階の出力が次の入力になります。
選択肢2の「1段階」、選択肢3の「逆向き」、選択肢4の「印刷する手順」はどれも誤りですよ。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✓ | 6フェーズを順に通る |
| 2 | ✗ | 段階がある |
| 3 | ✗ | 字句解析から始まる |
| 4 | ✗ | 印刷する手順ではない |
オリジナル問題2(フロントエンドとバックエンド)
コンパイラの前後の分離に関する次の記述のうち、正しいものはどれか。
- フロントエンドもバックエンドもCPUに依存し、言語による違いはないものとされているのだ
- フロントエンドは言語に依存し、バックエンドはCPUに依存する形で分離して設計されている
- フロントエンドはCPUに依存し、バックエンドは言語に依存する形に分かれているとされる
- フロントエンドもバックエンドも紙に印刷する手順で、コンパイラとは無関係なものとされる
解答は 2 ですよ。
フロントエンドは言語に依存し、バックエンドはCPUに依存する形で分離されますね。間にある中間コードが前後を切り分けます。
選択肢1の「どちらもCPU依存」、選択肢3のフロントとバックが逆、選択肢4の「印刷する手順」はどれも誤りですよ。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✗ | フロントは言語に依存する |
| 2 | ✓ | フロントは言語・バックはCPU |
| 3 | ✗ | フロントとバックが逆 |
| 4 | ✗ | 印刷する手順ではない |
オリジナル問題3(LLVMとGCC)
LLVMとGCCに関する次の記述のうち、正しいものはどれか。
- LLVMもGCCもまったく同じもので、設計思想や登場の新しさに違いはないものとされている
- LLVMは紙に印刷する装置のことで、GCCはその電源装置の一種にすぎないものとされている
- LLVMは比較的新しい基盤で、GCCは伝統的な基盤であり、どちらも現役で使われ続けている
- LLVMは伝統的な基盤で、GCCは新しい基盤として2003年に登場したものとされているのだ
解答は 3 ですよ。
LLVMは比較的新しい基盤、GCCは伝統的な基盤で、どちらも現役で使われていますね。設計思想が違います。
選択肢1の「同じもの」、選択肢2の「印刷する装置」、選択肢4のLLVMとGCCが逆はどれも誤りですよ。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✗ | 設計思想も登場時期も違う |
| 2 | ✗ | 印刷する装置ではない |
| 3 | ✓ | LLVMは新しい・GCCは伝統的 |
| 4 | ✗ | LLVMとGCCの説明が逆 |
まとめ
押さえどころ
- 🔴 6フェーズの順番 = 字句解析→構文解析→意味解析→中間コード生成→最適化→コード生成。
- 🔴 前後の分離 = フロントエンド(1〜3)は言語に依存、バックエンド(5〜6)はCPUに依存。間が中間コード(IR)。
- 🟡 LLVMとGCC = LLVMは新しい基盤(Clang・Rustなど)、GCCは伝統的な基盤。どちらも現役。
次に学ぶ
- 構文解析(LL・LR) ── 6フェーズの2番目、文法の構造を木にする構文解析のしくみ。
- 形式言語・文法 ── コンパイラが扱う「文法」の土台になる、形式言語の考え方。
執筆: SikakuQuest編集部