トッププログラミング言語 > コンパイラの概要

コンパイラの概要

1.コンパイラとは

コンパイラは高水準言語(高級言語)によるプログラムを計算機に分かる機械語に翻訳する。

コンパイラはC言語やJavaなど高水準言語で開発できるが、 機械語コードを生成するためには、対象とするコンピュータの機械語命令についての知識が不可欠である。

また、Windowsパソコンの実行可能形式ファイル(または実行可能ファイル) を生成するには、Portable Executable(PE)形式についても知らねばならない。 しかし、既存のアセンブラーを使うのであれば、アセンブリ言語のコードを生成するまでが、 コンパイラの仕事となる。

インタプリタは、同時通訳のようにプログラムを一行ずつ即実行するもの。 インターネットでの代表例はJavaScript言語である。ただし、JavaScriptは、C言語、Javaと同様の 構造化プログラミング言語であるから、インタプリタではソースプログラムを直ちに一行ずつ 実行できるわけではない。まず、字句解析、構文解析を行い、意味解析・実行を行うこととなる。 インタプリタの開発では、機械語の知識は必要としない。 プログラムの実行速度は通常、コンパイラで生成した機械語プログラムより桁違いに遅い。

2.プログラムの処理過程

プログラムの処理過程(プログラムの開発手順)を次図に示す。

  1. ソースプログラムの作成はWindowsパソコンの場合、NotePadでもよいが、 TeraPad秀丸(ひでまる)エディタなどの方がプログラム開発に適している。
  2. コンパイラがソースプログラムからオブジェクトプログラムを生成する。 ELF(Executable and Linkable Format)形式が使われることが多い。 Windowsパソコンの場合、CygwinまたはMinGWに含まれる objdumpコマンドにより、 オブジェクトファイルの中身を調べることができる。
  3. 分割コンパイルではオブジェクトファイルは複数存在する。 また、一般に、プログラムはライブラリ関数(例えばprintf関数)を使う。 ライブラリ関数は現在は大抵の場合、DLL(Dynamic Link Library)が使われる。 リンカは、このような複数のオブジェクトファイルやライブラリを結合して、 一つの実行可能形式ファイルを生成する。
  4. DLLに関しては、リンカは DLL が使えるように準備をし、ローダが実際に結合する。 ローダはOSの一部に属するものであり、コンパイラ開発者の仕事は精々リンカの開発までである。

3.コンパイラの設計・開発

コンパイラの構造はしばしば、字句解析、構文解析、意味解析、コード生成の4フェーズで表現される。 しかし、実際に、コンパイラを設計・開発する場合、 まず、プログラミング言語の仕様を決め、表現しなければならない。 また、コード生成で終わりではない。規格に沿って、実行可能形式ファイルを生成しなければならない。 パソコンは長足の進歩を遂げており、諸規格も高度化しているので、 実行可能形式ファイルの生成はいとも簡単とは言えない。

●モデル化 ・・・ 
言語仕様(文法)をどう表現するか?
●字句解析 ・・・ 
字句(token)に分解する。
  X=A+B*C; ⇒ X, =, A, +, B, *, C, ;
●構文解析 ・・・ 
計算の優先順位を考慮して構文木(syntax tree)を生成する。 構造を表すのみで、どういう操作を行うかは規定しない。
 
●意味解析 ・・・ 
何を行うかを決める。 代入文(X=Y;)では、右辺の値(計算結果)を左辺の変数にセットする。
左辺は変数か、右辺と左辺のデータ型(数値、文字など)は一致するか、 などのチェックも行う。
●コード生成 ・・ 
必要に応じて、一時変数も用いて、オブジェクト・コードを生成する
   LOAD     B  ・・・・・・ B の内容をレジスタへ ( レジスタ ← B           )
   MULT     C  ・・・・・・ C の内容と乗じる     ( レジスタ ← レジスタ*C )
   ADD     A  ・・・・・・ A を加える           ( レジスタ ← レジスタ+A )
   STORE     X  ・・・・・・ 結果を X へ          (     X    ← レジスタ    )
          最終的には数字列(バイナリデータ)に変換される。
●リンク ・・・・ 
実行可能形式ファイルを生成する

4.コンパイラとインタプリタの違い

字句解析から始まり、構文解析、意味解析、中間語コード生成まで コンパイラとインタプリタに大きな違いはない。

両者の違いは、その後にある。 コンパイラの場合、中間語(もしくはアセンブリ言語)コードを機械語コードに変換し、 実行可能形式ファイルを生成する。 一方、インタプリタは中間語コードをそのまま一命令ずつ解釈・実行する。

実行可能形式ファイルは前に 簡単に紹介したように、複雑な構造(Portable Executable Format)をしている。 8ビット、16ビットパソコン時代には、COM形式と呼ばれる簡単な形式の実行可能ファイルも存在したが、 32ビットパソコンでは、拡張子が com であっても、内容はPE形式である。

このため、制作演習では、最初にインタプリタを取り上げ、理解が深まってから、 コンパイラ版の制作に進む。

一般に、インタプリタでの中間言語コードとコンパイラでの中間言語コードは全く同じとは限らない。 コンパイラの場合、いずれ、機械語コードに変換しなければならないので、 機械語命令を意識したものになるが、インタプリタでは、機械語を殆ど意識しなくてもよい。


参考文献

[1] Executable and Linkable Format