コンパイラ〜つく〜ろ〜♪1番全体の構成

オレオレ言語のコンパイラ作ることになったので、
せっかくなら勉強しながら学んでいくスタイル

これをKindleで買って、読み進めながらやっていきます。

今日のテーマはコンパイラの全体構成の話。
これから勉強を進めていく毎に、これらの詳細化が出来ればと思っています。

コンパイラの構成

コンパイラの全体構成図は次のようになっています。
f:id:pokotyamu:20150512003546p:plain:w300
それぞれについて少しだけ説明すると、

1.字句解析

ソースコードを最小の構成単位(トークン)に分割する。
字句の例としては
 キーワード:int for while
 識別子:変数名、関数名
 定数:100等
 文字列リテラル:”abcd"
 演算子:+ - / < =
 区切り子:[ ] { } ( )

2.構文解析

トークンの順序の正しさを判定するため構文木を作成する。

i = a + b * c;

というコードに対して構文木を書くと以下のようになる
f:id:pokotyamu:20150512003216p:plain:w300
これによって、ある程度の型のチェックすることで最適化を行う。

3.中間コード

構文木をソースプログラムの中間言語表現に変換する。
代表的な変換としては
上の式を

 T1 = b * c;
 i = a + T1;

とすることで、2項演算子のみにする等がある。
これについては理解が追いついていないので後日。

4.最適化

実行速度の面から改善するために、無駄な要素を見つけ出し、対処する。
・同じ変数値を何度も読み込んでいる
 →レジスタに1回読み込んで維持しておく
・ループ内で結果が一定である式が存在する
 →ループ外に出す処理をする
ここについても、もう少し進めていって勉強。

5.コード生成

中間コードは内部表現なので、中間コードが終わりではなく、
そこから目的のプログラムコードを作成する。
コードの生成結果は通常ファイルである。
目的のプログラムがアセンブラ言語ファイルである場合は、
それをさらに機械語に変換することで実行可能ファイルが生成される。

次回は、実際にトークンの作成のコードを作ってみようと思います。