この記事は、コンパイラの進化 からの続編です。
この記事は、絵でわかる プログラムとは何か(3)~リンクで進化した言語処理~ の一記事です。
この記事のポイント
- プログラミング言語をマシンコードに変換するプログラムを言語処理系と言う。(アセンブラやコンパイラなど)
- 言語処理系には、以下のような種類がある。
- アセンブラ
- アセンブリ言語をマシンコードに変換。
- コンパイラ
- ソースコードを最適化し変換。
- AOTコンパイラ
- 実行前にソースコードを変換。
- JITコンパイラ
- 実行直前にソースコードを変換。
- インタプリタ
- 実行時にソースコードを一行ずつ変換。
- どの言語処理系も、パースという、対象プログラミング言語の解析処理を、まず最初に行う。
- 変換後のマシンコードは、実行するプラットフォームに合っていなければならない。
- 時間のかかる最適化処理は、実行時ではほとんどできない。
言語処理(translate)
プログラミング言語処理系
これまで見たようなソースコードから実行ファイルまでの変換をするプログラムをプログラミング言語処理系(programming language processor)と言います。略して「言語処理系」、さらに略して単に「処理系」と表現されることもあります。
コンパイラは単体でも言語処理系になり得ますが、リンカまで含めての1セットでも一つの言語処理系として扱われます。
パース(parse)
どんな言語処理系であっても、共通しているのが、前半にあるパースという言語処理です。
パースでは、以下の2段階の処理が行われます。
- 字句解析(lexical analysis) →トークン(token)分解
- 構文解析(syntax analysis) →抽象構文木(AST)生成
高級プログラミング言語は、どれも英語の文化が基本になっているので、単語と単語の間を 空白/改行/記号 のどれかで区切ってあります。この 空白/改行/記号 で区切られていて一つの意味を持つ字句のことをトークン(token)と言います。
lexical は、lexicon=語彙、辞書 の形容詞で、ソースコードから言語処理系にとっての字句(token)を抽出することを指しています。

パーサ(parser)というパースをするプログラムは、このトークンを抽出し、トークン間の関係を抽象構文木(Abstract Syntax Tree)という樹形図にマッピングします。

樹形図へのマッピングは、
- 文の先頭から、各トークンをメモリに配置。
- そのトークンの定義に従って、その枝葉となる別トークンを特定する。
- 枝葉トークンのメモリアドレスを元トークンに対応づける。
を繰り返して完成します。
種々の言語処理系とその違い
通常のコンパイラの他にも、言語処理系にはインタプリタ(interpreter)や、JITコンパイラというものがあります。
前段のパースを、プログラム実行の前(AOT)にやるか/実行中(JIT)にやるか、後段で最適化を、するか/しないか等の違いによって、メリット/デメリットが異なります。
インタプリタ
インタプリタはプログラム実行フェーズ(run time)で、パースからマシンコード実行まで突貫で処理する言語処理系です。
処理の流れ
- プログラム実行(run)
- インタプリタ処理(interpretation)
- パース(parse)
- 意味解釈(semantics analysis)【ほとんど最適化できない】
- マシンコード生成(code generation)【実行環境に合わせられる】
- マシンコード実行(execution)
- インタプリタ処理(interpretation)
メリット
- 実行環境を限定せずにプログラムを配布できる。
- プログラムの一部分だけでも突貫処理できるため、部分修正の繰り返し時に便利。
デメリット
- 実行時にする事が多いため、動作が遅く感じる。
JITコンパイラ
JITコンパイラは、プログラム実行中(run time)にコンパイルを行います。そしてコンパイル後、即マシンコードを実行します。JITは、Just-In-Time の略で、「ギリギリで」という意味です。
処理の流れ
- プログラム実行(run)
- JITコンパイル(JIT compilation)
- パース(parse)
- 中間コード生成(intermediate representation)
- 最適化(code optimization)【短時間での中度最適化】
- マシンコード生成(code generation)【実行環境に合わせられる】
- マシンコード実行(execution)
- JITコンパイル(JIT compilation)
メリット
短時間で効果が高い最小限の最適化だけを行うことで、インタプリタより動作を速められる。
事前コンパイルと違い、プログラム実行環境が限定されない。
デメリット
最適化の効果が出せない場合、インタプリタより動作が遅くなる。
AOTコンパイル
JITコンパイルに対して、通常のコンパイラが行う事前コンパイルをAOT(Ahead-Of-Time)コンパイルとも言います。
処理の流れ
- 事前コンパイル(AOT compilation)
- パース(parse)
- 中間コード生成(intermediate representation)
- 最適化(code optimization)【長時間での高度最適化】
- マシンコード生成(code generation)【実行環境が限定される】
- プログラム実行(run)
- マシンコード実行(execution)
メリット
プログラム実行中ではないので、高度な最適化にも十分時間をかけられ、プログラム実行時の動作を最速にできる。
デメリット
プログラム実行前にマシンコード生成をするので、その時点で実行環境を限定せざるを得ない。
この記事のまとめ
プログラミング言語をマシンコードに変換するプログラムを言語処理系と言います。
言語処理系には、アセンブラやコンパイラ、実行時にソースコードを一行ずつ変換するインタプリタがあります。
コンパイラにはさらに、実行前にコンパイルしておくAOTコンパイラと、実行直前にコンパイルするJITコンパイラがあります。
言語処理系は、パースという、対象プログラミング言語の解析処理を、まず最初に行います。
それから、実際にプログラムを実行するプラットフォームに合わせた変換処理を行います。
この時、プラットフォームに合わせて最適化ができる場合もありますが、それには時間がかかります。
事前に最適化をしておくためには、プラットフォームを決めねばならず、実行できるプラットフォームが制約されます。
以上で、絵でわかる プログラムとは何か(3)~リンクで進化した言語処理~ は終わりです。
次は、絵でわかる プログラムとは何か(4)~マルチタスクとメモリ~ へ進みましょう。
コンピューターのしくみ全体を理解したい場合は、以下の2コースがお勧めです。
日本全国 オンラインレッスン にも対応しています。
知りたいことだけ単発で聞きたい場合は、 オンラインサポート をご利用ください。