クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

コンパイラの基礎

レッスン全文をここで読めます。無料アカウントを作成すると、実際のラボで実践できます。

仮想マシンラボ読了目安 12分コマンド10個

1つのコマンド、4つの段階

コマンドを1つ打つだけで、C のプログラムがマシンで動くものに変わります。そのコマンドの中には、4つの段階が隠れています。ビルドに失敗したとき、エラーはそのどれかから出ています。どの段階のエラーかが分かれば、どこを見ればよいかが分かります。

このレッスンが終わると

メモ

コンパイラがプログラムを通す段階の名前を言うことができる。

キーワード

  • コンパイラ:ソースコードをプロセッサの命令に変えるプログラム。
  • プリプロセッサ:最初の段階。ファイルを貼り込み、名前を置き換える。
  • アセンブリ:プロセッサの命令を、言葉で書いたもの。
  • リンカ:最後の段階。機械語の部品をつないで1つのプログラムにする。
  • トークン:プログラムの1語。数や記号など。
  • 構文解析器(パーサ):トークンが文法に合っているかを調べる部分。

ウォームアップ:すでに知っていること

メモ

頭の中で答えてみましょう。1. cd は何をしますか。2. cat は何を表示しますか。3. 名前が .c で終わるファイルには何が入っていますか。3つめの答えは、すぐに使います。

はじめる前に

メモ

このレッスンの上にあるバーのラボを起動を押してください。このラボは、あなた専用の Ubuntu のマシンまるごとです。コンテナよりも、立ち上がるまで少し時間がかかります。実行ボタンを押すと、コマンドが順番にマシンのターミナルへ入力されます。「マシンはまだ起動中です」と出たら、数秒待ってからもう一度押してください。自分で入力と書かれたところでは、プログラムがあなたの入力を待ちます。バーのターミナルを開くを押して、自分で打ち込みます。

プリプロセッサは貼り込み、置き換える

gcc -E は最初の段階で止まり、できたものを表示します。#include <stdio.h> の1行が何百行にもなるので、tail -n 8 で最後だけを見ます。main を見てください。GREETING という名前は消え、そこにマクロの文字列が入っています。コメントも消えています。

コマンド
cd ~/compiler

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
gcc -E hello.c | tail -n 8

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

チェック

ヒント

GREETING はどうなりましたか。答え: コンパイラ本体がプログラムを見る前に、プリプロセッサが文字列に置き換えました。

コンパイル、アセンブル、リンク

gcc -S はコンパイルの後で止まり、hello.s を書きます。このマシンのプロセッサ用のアセンブリです。中で square と main を探し、square を呼ぶ call か bl を見つけてください。gcc -c はもう1段階進み、機械語の hello.o を書きます。最後の gcc は、printf のある C ライブラリとリンクして、プログラムにします。

コマンド
gcc -S hello.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
cat hello.s

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
gcc -c hello.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
gcc hello.o -o hello

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
./hello

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

コンパイラは C を一度にプログラムへ変えるので、エラーはすべてコードの誤りだ、と考える人がよくいます。実際には4つの段階があります。undefined reference to のあとに名前が続くエラーはリンカから出ています。コードのコンパイルは済んでいて、最後の段階に必要な部品が渡されていないのです。

チェック

ヒント

アセンブリで止まるコマンドはどれで、オブジェクトファイルを書くコマンドはどれですか。答え: gcc -S が hello.s を、gcc -c が hello.o を書きます。

コンパイラは意味も調べる

C の文法をすべて守っていても、意味の通らないプログラムはあります。scope.c では、step はループの中で作られ、ループの後、もう存在しない場所で使われています。-Wall は、gcc にふつうの警告をすべて出させます。答えを読みましょう。ビルドを止めるエラー(step が宣言されていない)と、止めない警告(unused が一度も使われていない)です。

コマンド
gcc -Wall -c scope.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

自分で作れる字句解析器と構文解析器

calc.l は flex に、トークンの形を教えます。数、記号、かっこです。calc.y は bison に文法を教え、* と / が + と - より先だと伝えます。make は Makefile を読み、bison、flex、gcc を正しい順に動かします。できた電卓は、この式に 20 ではなく 14 と答えます。

コマンド
make

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
echo "2 + 3 * 4" | ./calc

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

最後のチェック

ヒント

前を見ないで答えましょう。1. 4つの段階を順に言いましょう。2. マクロを置き換えるのはどの段階ですか。3. 文字をトークンに変えるのはどの部分ですか。4. 使われない変数は、エラーですか、警告ですか。答え: プリプロセス、コンパイル、アセンブル、リンク。プリプロセッサ。字句解析器(ここでは flex が作ったもの)。警告。

先生へ

ヒント

このレッスンは VM ラボで行います。学生はそれぞれ自分の Ubuntu マシンを持ち、実行ボタンはそのターミナルに入力して、表示された結果を見せます。学習のポイント:1. ビルドには、プリプロセス、コンパイル、アセンブル、リンクの4段階がある。2. gcc -E、-S、-c は各段階の後で止まるので、途中の結果を読める。3. 字句解析器がトークンを作り、構文解析器がそれを文法と照らし合わせる。よくある間違い:リンカのエラーを、コードの誤りだと読んでしまう。準備するもの:ラボとブラウザ。ヒント:hello.c と hello.s を並べ、C の各行がアセンブリのどこになったかを探させてください。このラボには検査がなく、採点もしません。成績が必要なら、独自の提出物を出してください。

このラボのほかのレッスン

このラボとソースについて: コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

授業で教えていますか?これらのレッスンを生徒に割り当て、採点と生徒ごとのラボを使えます。