プログラミング言語の分類と翻訳処理
私たちが普段記述しているソースコードは、人間が理解しやすい「高水準言語」で書かれています。しかし、CPUが直接実行できるのは、第3章で学んだ「機械語」のみです。このギャップを埋めるために不可欠な、プログラミング言語の分類と、それを翻訳して実行する仕組み(翻訳方式)について解説します。
1. 高水準言語と低水準言語の階層
プログラミング言語は、ハードウェア(CPU)からの抽象化の度合いによって、大きく「低水準言語」と「高水準言語」に分類されます。
- 低水準言語(Low-Level Language):
機械語(バイナリコード)やアセンブリ言語がこれに該当します。ハードウェアのレジスタやメモリのアドレスを直接指定して操作するため、実行速度やメモリ効率は極めて高いですが、人間にとって読み書きが難しく、CPUのアーキテクチャごとにコードを書き直す必要があります。 - 高水準言語(High-Level Language):
C、C++、Java、Python、JavaScript、TypeScriptなど、現代の多くの言語がこれに該当します。英語に近い表現や数式を用いて、ハードウェアの詳細(メモリ管理やレジスタの割り当てなど)を意識せずにプログラムを記述できます。また、一度書いたコードは異なるプラットフォームでも再利用可能です。
2. 翻訳処理の3つの方式
高水準言語で記述されたプログラムを実行するために、ソースコードを機械語へと変換(または解釈実行)するアプローチには、主に「コンパイル方式」「インタプリタ方式」、そして両者を組み合わせた「JITコンパイル方式」の3つが存在します。
① コンパイル方式(Ahead-Of-Time: AOT)
実行前にソースコード全体を一括して機械語に翻訳し、実行可能ファイル(バイナリ)を生成する方式です。C、C++、Rust、Goなどが採用しています。
メリット: 実行時にはすでに翻訳が完了しているため、実行速度が極めて高速です。また、配布時にソースコードを隠蔽できます。
デメリット: コンパイルにかかる待ち時間が発生するほか、コンパイル後のバイナリは特定のOSやCPUアーキテクチャに依存するため、移植性が制限されます。
② インタプリタ方式
プログラムの実行時に、ソースコードを1行(または1ステップ)ずつ逐次読み込み、解釈しながら実行する方式です。PythonやRuby、初期のJavaScriptなどがこれに該当します。
メリット: 事前のコンパイルが不要なため、コード修正後に即座に動作確認が可能です。また、プラットフォームに対応したインタプリタさえあれば、同じソースコードをそのまま実行できる高い移植性を持ちます。
デメリット: 実行と並行して「翻訳処理」を常に行うため、コンパイル方式に比べて実行速度が大幅に低下します。
③ JIT(Just-In-Time)コンパイル方式
コンパイル方式とインタプリタ方式のハイブリッドです。Java(JVM)や、V8エンジンを搭載した現代のJavaScriptなどで広く採用されています。
まず、ソースコードを一括して「中間コード(バイトコード)」と呼ばれるプラットフォーム非依存の軽量コードに事前コンパイルします。実行時は中間コードを仮想マシンが逐次解釈しますが、何度も実行されるループ処理や頻繁に呼び出される関数(ホットスポット)を検知すると、その部分だけを実行中にネイティブ機械語へ動的コンパイルします。
これにより、インタプリタの持つ「移植性と起動の速さ」と、コンパイラの持つ「実行速度の高さ」を両立させることができます。
3. 実行モデル:ネイティブと仮想マシンの対比
翻訳方式は、その最終ターゲットが物理的なハードウェアなのか、それともソフトウェアで構築された仮想的な計算機なのかによって、実行モデルが分類されます。
- ネイティブ実行モデル:
CやRustなどで生成されたバイナリが該当します。特定のCPU命令セット(x86_64、ARM64など)に直結した機械語として実行されます。物理メモリやレジスタを直接駆動するため無駄がありませんが、他のプラットフォームへの互換性はありません。 - 仮想マシン(Virtual Machine)実行モデル:
JavaのJava Virtual Machine(JVM)や、Node.js/ブラウザのV8エンジンが該当します。プログラムは論理的なレジスタや論理スタックを備えた「ソフトウェア的なCPU」を想定してコンパイルされ、仮想マシンのインタプリタやJITが実CPUの命令へと動的にマッピングします。これにより、「一度書けばどこでも動く(Write Once, Run Anywhere)」という汎用性が保障されます。
次節からは、コンパイラ(AOTコンパイラやJITコンパイラのフロントエンド)が、プレーンなソースコード文字列をどのように解析し、構造化されたデータに変換していくのか、その第一段階である「字句解析」について詳しく学びます。