한국   대만   중국   일본 
インタプリタ - Wikipedia コンテンツにスキップ

インタプリタ

出典: フリ?百科事典『ウィキペディア(Wikipedia)』

インタプリタ : interpreter )とは、 プログラミング言語 で書かれた ソ?スコ?ド ないし 中間表現 を逐次 解? しながら ?行 する プログラム のこと [1] 。「インタ?プリタ」「インタ?プリタ?」などと表記することもある。

インタプリタは、およそ次のいずれかの動作をするプログラムである。

  1. ソ?スコ?ド を直接解??行する。
  2. ソ?スコ?ドを何らかの?率的な中間的なコ?ド( 中間表現 )に、最初に全て?換して、あるいは、逐次?換しながら、解??行する。
  3. 何らかの コンパイラ が生成し出力した、何らかの?率的な(マシンに依存しない、あるいは、マシン依存の)中間表現を解??行する [注 1]

このように程度の差はあるが、ソフトウェアがソフトウェアを?行するという形になる。

いずれにしても、「インタプリタ言語」などという分類は本?は存在しない。?にそれぞれの言語の代表的な?理系の??がインタプリタであったというだけで、理論上はどの言語であってもインタプリタとコンパイラのどちらでも作ることができる。しかしながら、インタプリタかしか存在しない言語があるが故に、「インタプリタ言語」や「コンパイラ言語」と?別されているのが現?である。インタプリタは?行中何度もプログラムを再解?するため、 ダイナミックディスパッチ 英語版 ダイナミックバインディング リフレクション 動的型付け のような機能を?現することが容易である。一方、コンパイラは事前にCPUで?行できるように?換するだけで?行には??しないため、?行中に振る舞いを?更したいときはそのためのプログラムを別途用意しなければならないケ?スがほとんどである。さらに、自前の言語から?存の何らかの表現に?換するには、その表現と??付けるための知識と技術が必要であり、言語機能が大規模化や複?化するほど、?存の表現との互換性をできるだけ確保しながら、自前の言語での振る舞いを?現することは難しくなる。中間表現も自前であれば、?換する手間はずっと?になる。

仕組み [ 編集 ]

インタプリタは各?想命令に紐づく命令ボディとディスパッチ機構をもち、ホストマシン上で?行可能になっている(例: x86マシンコ?ドbinファイル)。?想命令群からなるコ?ドを引?としてインタプリタが?行されると、?想命令に基づいて制御が移行され??する命令ボディが?行される。これを繰り返すことでインタプリタはコ?ドを?行する。

命令ボディ [ 編集 ]

命令ボディ : instruction body 、命令本?とも)は?想命令をホスト言語で エミュレ?ト するコ?ドである [2] 。命令ボディがホストマシンで?行されることで?想命令が事?上?行される。すなわち命令ボディは?想命令の??である。例えば二項和?想命令 ADD2 に??してC言語で書かれた push(pop() + pop()) は命令ボディである。

ディスパッチ [ 編集 ]

ディスパッチ : dispatch )は?想命令に基づいた命令ボディから命令ボディへの 制御 移行メカニズムである [2] [3] 。ディスパッチの最もシンプルな例は Switch文 Jump命令 )である。ある?想命令の?行後、次の?想命令に??する命令ボディへ制御を移す(Jumpする)ことでその?想命令??が?行される。

誤解 [ 編集 ]

プログラミング言語?理系の??には、インタプリタと コンパイラ の2つがある、とされてきた。インタプリタは ?行 を行う が、コンパイラは ?行 を行わない、という差がある。

インタプリタは、インタプリタが提供する言語のプログラム文を1文ずつ、インタプリタを??した言語の機能を呼び出していく(?純な)方式が一般的であった。コマンドラインインタプリタではこれに加えて、別のプログラムに?理を委ねて一つの機能を?現する。

この時代のインタプリタの長所と欠点については、およそ次のような解?がされることが一般的であった。

  • (長所)プログラムを作成している途中でも、とりあえず書かれた箇所まで?行させることができ、プログラマの期待通りの動作をしている場合も、期待通りの動作をしていない場合も、早期にそれを確認??見し、そして修正後すばやく?行、再確認できる。
  • (短所)?行速度が?い。( ル?プ (=繰り返し)の箇所などでは)1度構文解?した文でも、?回(あらためて、最初から) 解? と?行を行うので、コンパイラ方式に比べて?行速度が?くなる。(ル?プを全く含まないような、全ての命令が一回だけ解?され、一回だけ?行されるような(ある意味、特殊な)プログラムであれば、解?+?行のト?タルの時間は、インタプリタでもコンパイラでもさほど差は生じない。だが、?用的なプログラムは一般的に、多?のル?プを含んでおり、そうしたプログラムではインタプリタのほうが?行を完了するまでの時間が多くかかり、特に、ル?プ回?が多ければ多いほど(古典的な、?純な)インタプリタの相?的な?さは?著になってくる。→ #長所と短所

その後、そうした欠点を解消すべく、(1990年代ころになって)?回?回、(高級言語から)機械語に?換するのではなく、中間言語に?換することで高速化をはかるインタプリタなどが作りだされた。

改良の結果、古典的な意味での「インタプリタ」と「コンパイラ」の?方の性質を備えたようなインタプリタが登場し、複?化してきている。

(近年の)インタプリタがおこなう、(??の)コンパイラが行っているような?換のひとつとしては、高速化などを目的とした、 ?行時コンパイラ による 動的コンパイル を?げることができる。

[注 2]

?史 [ 編集 ]

インタプリタという手法、すなわち、「そのハ?ドウェアが直接解?するのではないプログラム」を受け取り、「プログラムで??された抽象的な、あるいは?想上のコンピュ?タで解??行する」というプログラムの?行法は、コンピュ?タが登場した時から、ないしそれ以前からある。

万能チュ?リングマシン は、「どんなチュ?リングマシンについても、それを模擬できるチュ?リングマシン」というもので、ある種の エミュレ?タ ないしインタプリタであり、考察されたのは電子式のコンピュ?タの誕生する以前である。

EDSAC (?用的な機能を持った プログラム??方式 の世界初の電子計算機とされている)において?に、ある種のインタプリタが??されていたことが記?に?っている。同機におけるプログラミングの技法が書かれた The Preparation of Programs for an Electronic Digital Computer の chapter 2 の § 2-22 Interpretive subroutines で?明されているが、複素?演算などのサブル?チンを明示的にサブル?チンとして呼ぶのではなく、通常の加減算などと同?の形式のプログラムをインタプリタで解?してそれらのサブル?チンを利用する、というものである。また日本においても、 パンチカ?ド を入力として パッチパネル の配線によるプログラミングで?理するような機械で、配線によってある種のインタプリタのようなものを??し、パンチカ?ドの?容をデ?タとしてではなくプログラムのように扱う、というような例があると言われている [4]

最初の Lisp インタプリタは スティ?ブ?ラッセル IBM 704 上に??した。これにはエピソ?ドがあり、 ジョン?マッカ?シ? が「Lisp の論文」 [5] で「??的」に示したものだったのであるが、マッカ?シ?自身は??できるものだとは考えていなかった。それを、論文を?んだ、院生であったラッセルが、??可能だと言って??的な記述から?換して機械語で??してみせたという。 [6] [7]

1960年代には(現在のJavaなどと同?な)、プログラミング言語から中間表現にコンパイルし、それをインタプリタで?行する、というような手法も一般的になった( pコ?ドマシン を?照)。

長所と短所 [ 編集 ]

開?時に修正作業が容易 [ 編集 ]

プログラム開?中、プログラマは頻繁にソ?スコ?ドに手を加える。コンパイラの場合、ソ?スコ?ドを?更するたびにコンパイルし、 リンク して ?行ファイル を完成させないと、そのプログラムを?行できない。プログラムが大きくなると、 ビルド の完了を待っている時間が長くなる。一方、インタプリタではソ?スコ?ドをそのまま?行するか中間表現に?換するだけなので、ほとんど待つ必要がなく、修正がうまくいったかどうかのテストをより素早く確認できる。

この特性を利用したプログラムとして REPL がある。入力を受け取る(Read)、入力の評?(Eval)、評?結果を提示する(Print)を繰り返す(Loop)、テスト環境の一つである。評?はインタプリタに限らずコンパイラで行なわれるかもしれないが、ユ?ザからの入力は常にソ?スコ?ドの?片であり、それを逐次?行するという点で一種のインタプリタということもできる。?際、その?動はソ?スコ?ドを指定せずに起動したBASICなどのそれとよく似ている。しかし、テスト環境も兼ねているため、エラ?が起きた場合のメッセ?ジが詳細であることが多い。 ??型言語 論理型言語 では、通常は 機械語 にコンパイルする ?理系 であっても用意される。

可搬性 [ 編集 ]

AOTコンパイラ 方式では事前に生成された 機械語 ?行ファイル がユ?ザ?に配布される。 機械語 はプロセッサア?キテクチャに依存するため、このバイナリは特定のプロセッサでしか動作しない( 可搬性 が低い)。

一方インタプリタ形式ではソ?スコ?ドとインタプリタが配布される。インタプリタは機械語?行ファイルであるため環境に依存するが、ソ?スコ?ドには環境に依存しない言語を採用できる。その場合環境に合わせたインタプリタを事前配布しておけば、ア?キテクチャに依存しないプログラムの配布が可能である( 可搬性 が高い)。またインタプリタの代わりに JITコンパイラ を用いても同?の利点が得られる。同一動作の保?はインタプリタ??に依存しており(JITであればコンパイラ)、互換性バグの例として表計算マクロやWebペ?ジ(HTML)が?げられる。

複?性 [ 編集 ]

AOTコンパイラ 方式では1つのバイナリを?行するだけでプログラムが機能する。一方インタプリタ方式では、まずインタプリタを インスト?ル しその上でソ?スコ?ドを動かす必要がある。その結果全?のプログラムサイズが大きくなり、ユ?ザ?の手間が?える場合がある(複?性が高い)。また JITコンパイル 方式でも同?の複?性が生まれる。

可?性 [ 編集 ]

インタプリタ用コ?ド(高級言語コ?ドあるいは バイトコ?ド )は 機械語 バイナリより容易に解?できる( 可?性 が高い)。ゆえに配布後のデバッグや修正が容易な一方、 知的財産 保護上の問題を起こしうる。そのための 暗? 化? 難?化 を考慮した言語?システムが存在する。また JITコンパイル 方式でも同?の可?性に?する特性が現れる。

速度 [ 編集 ]

インタプリタ方式の?行速度はコンパイラ方式の?行速度よりも?い傾向がある。

コンパイラではプログラム?の の解析を?行前に1回だけ行うが、?純な??のインタプリタではそれを文ごとに?行時に?回行うため、?行性能が低くなる。?純な??のインタプリタでは??にアクセスする際も識別子とメモリ上の位置のマッピングを確認しなければならず、しかもそれを?行中に何度も行わなければならないので、?くなる。

また ディスパッチ はインタプリタが本質的に抱えるコストである。コンパイル方式では事前(コンパイル時)にディスパッチ相?の命令ボディ整列がおこなわれるため、?行時にディスパッチコストが?生しない。ゆえにインタプリタ方式ではディスパッチコスト×命令?分の追加コストが本質的に掛かる。

ディスパッチ 分岐予測 を難しくする。ゆえに パイプライン 方式を採用する CPU において速度へ影響を?える [8] 。影響の大きさは分岐予測器の性能に左右され、2000年代以前のCPUではインタプリタの低速度がこのペナルティによって引き起こされるとされていた。予測器の性能が上昇した2010年代以降のCPU(例: x86 Haswell )ではその影響は小さい [9]

インタプリタによる開?の速さとコンパイラによる?行の速さの間で、??な妥協案が考案されてきた。一部の LISP ?理系などでは、インタプリタのコ?ドとコンパイルされたコ?ドが相互に呼び出しあうことができ、??も共有できる。そのため、あるル?チンをインタプリタで評?しデバッグした後、先行してコンパイルして?行性能を高めつつ、他のル?チンを開?し?けることができる。多くのインタプリタはソ?スコ?ドをそのまま?行するわけではなく、よりコンパクトな?部形式に?換している。多くの BASIC インタプリタは 予約語 を1 バイト ト?クン に置換し、それを ジャンプテ?ブル のインデックスとして使用する。 PBASIC など一部のインタプリタでは、バイト?位ではなくビット?位でプログラムの短縮を行っており、例えばコマンドを5ビットで表し、一般に16ビットで表される定?をその?値の大きさに??して可?長(3、6、10、18ビットなど)で表し、アドレスオペランドとして「ビットオフセット」を用意している。多くの BASIC インタプリタは?自にト?クン化された?部表現を保存し、?み?むことができる。

インタプリタがコンパイラと同?の 字句解析 構文解析 を行い、その結果生成された 抽象構文木 を解?することもある。

プログラムの?行時間はコンパイラよりもインタプリタの方が長いが、コンパイル時間と?行時間を合計すればインタプリタでの?行時間よりも長くなることがある。 プロトタイピング テスト においては、この差が重要となる。

その他の技法に 制御フロ?解析 ?的?一代入 がある。

バリエ?ション [ 編集 ]

スレッデッドコ?ド [ 編集 ]

それ自?はインタプリタの手法とも言えるしコンパイラの手法とも言える。そのどちらと言うよりも、中間表現の1種類というべきかもしれない。 ?想??テ?ブル テ?ブルジャンプ によるフロ?制御に似ていなくもない。

スレッデッドコ?ドは、呼び出されるべきサブル?チンのアドレスのみが順番に羅列されたものである。「直接スレッディング」の場合は、そのアドレスが指す先は機械語のサブル?チンである。他にもいくつかのバリエ?ションがある。「サブル?チン?スレッディング」は最も違うタイプのバリエ?ションで、アドレスのみではなく、機械語のCALL命令として羅列するので、ハ?ドウェアのプロセッサで直接?行できる。これは?行のオ?バ?ヘッドは極小だが、メモリ?率は?い [注 3] 。サブル?チン?スレッディング以外のスレッデッドコ?ドは、きわめて?純なインタプリタで?行できる。 Forth では「?部インタプリタ」と呼んでいる(これは、Forth言語自?を??しているインタプリタである「外部インタプリタ」と?になっている)。

バイトコ?ド [ 編集 ]

ソ?スコ?ドを?行可能な形にするには、まず、ソ?スコ?ドを構文木に?換する必要がある。構文木のまま、インタプリタ型の?理系で?行する?理系もあるが、構文木をさらに、中間コ?ド( バイトコ?ド など)などの 中間表現 に?換してから?行する物もある。中間コ?ドをバイトコ?ドと呼んでいる?理系ではそのインタプリタをバイトコ?ドインタプリタと呼ぶ。 Java .NET Framework のように、中間コ?ドの仕?を公開しファイルに書き出すものもあるし、仕?は公開せず?理系?部だけで使用するものもある。 動的コンパイル を使っているインタプリタは、?部で?機の 機械語 に?換し?行する。

インタプリタとコンパイラの間には??な中間的??が存在し、それぞれにプログラム?行前に行われる解析の度合いが異なる。例えば Emacs Lisp バイトコ?ド にコンパイルされ、 LISP のソ?スを高度に?縮し最適化した表現にしているが、それは機械語コ?ドではない(したがって特定のプラットフォ?ムに依存しない)。この「コンパイル」されたコ?ドを解?するのがバイトコ?ドインタプリタである(それ自?は C で書かれている)。この場合のコンパイルされたコ?ドは ?想機械 の機械語コ?ドであり、?想機械はハ?ドウェアで??されておらず、バイトコ?ドインタプリタとして??されている。同?の手法は Open Firmware システムで使われている Forth コ?ドでも使われている。ソ?ス言語は「Fコ?ド」(バイトコ?ドの一種)にコンパイルされ、それを ?想機械 が解??行する。他に Pコ?ドマシン などがある。

コントロ?ル?テ?ブル 英語版 はコンパイラを通さなくとも生成でき、バイトコ?ドインタプリタと同?の方法でカスタマイズされたインタプリタでの適切なアルゴリズム的 制御構造 を記述できる。

抽象構文木 [ 編集 ]

インタプリタとコンパイラの中間的手法の1つとして、ソ?スコ?ドを最適化された 抽象構文木 (AST) に?換し、その木構造にしたがってプログラムを?行するか、 ?行時コンパイラ での機械語コ?ド生成に使用する方法がある [10] 。この方式では各文を1回だけ構文解析する必要がある。バイトコ?ドに比べると、ASTではプログラムの全?的構造や文と文の?係を保持でき(それらはバイトコ?ドでは失われる)、?縮するとさらにコンパクトな表現になる [11] 。そのため、?行時コンパイラにとってはバイトコ?ドよりもASTの方が優れた中間表現だとして提案されてきた。また、?行時の解析もより優れたものにできる。

しかし、ASTはバイトコ?ドよりも冗長であるため、インタプリタとしてはオ?バ?ヘッドが大きくなるという問題がある [12] CRuby の場合は、1.8までは構文木インタプリタであったが、1.9では(開?中には YARV と呼ばれていた)バイトコ?ドインタプリタに入れ替えられ、性能が向上した。

?行時コンパイル [ 編集 ]

インタプリタとコンパイラの境界をさらにぼやけさせる方式として、中間表現を ?行時コンパイラ (JIT) でコンパイルし、?行時にネイティブの 機械語 にコンパイルする技法がある。これはネイティブなコ?ドの?行?率を?現する代わり、ASTやバイトコ?ドを最初にコンパイルする際に起動時間やメモリ使用量が?大するという欠点がある。これを補う技法として 適?的最適化 英語版 があり、インタプリタが?行中のプログラムを 性能解析 して最も頻繁に?行される部分をネイティブのコ?ドにコンパイルする。これらの技法は1980年代の Smalltalk などの言語で使われ始めた [13]

?行時コンパイルは近年多くの言語?理系で採用されており、 Java .NET Framework 、最近の JavaScript の??でも JIT が採用されている。

トランスレ?タ方式 [ 編集 ]

他のインタプリタ言語に?換して、タ?ゲット言語のインタプリタ上で?行する方式。例えば CoffeeScript JavaScript に?換されて、 JavaScript インタプリタ上で?行される。

?用 [ 編集 ]

デバッグ、?育用 [ 編集 ]

通常 C言語 はコンパイラで?理されるが、デバッグ目的および?育目的のインタプリタ型のC言語の?理系もある。MS-DOS時代に、いくつかの製品が提供されていた。C-Terpなどがその?な製品の例である。C/C++のインタプリタはほかに CINT Ch がある。

パンチカ?ド [ 編集 ]

パンチカ?ドシステム において、 パンチカ?ド を?み?んで、その?容を人間が?める形式(文字)でパンチカ?ド上に印字する機械をインタプリタと呼ぶ。例えば、 IBM 550 英語版 Numeric Interpreter (1930年) や IBM 557 英語版 Alphabetic Interpreter (1954年) がある。

プログラミング言語 [ 編集 ]

インタプリタとコンパイラ方式が?用のもの [ 編集 ]

「共通言語ランタイム」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

Erlang VM 」( BEAM )のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

Java ?想機械」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

JavaScript に?換されるもの [ 編集 ]

Lua VM」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

「Pコ?ドマシン」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

Parrot 」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

Smalltalk VM 」のバイナリ??コ?ドにコンパイルされるもの [ 編集 ]

VBAのPコ?ドにコンパイルされるもの [ 編集 ]

脚注 [ 編集 ]

注? [ 編集 ]

  1. ^ この意味では、 CPU は機械語インタプリタであると見ることができる。
  2. ^ 現在では、「インタプリタ / コンパイラ」という?分に?しては?況が?わっており、 [ 誰? ] に言わせると『だが、それらは必ずしも相互排他的に2つに分類できるわけではない。なぜなら多くのインタプリタ方式の?理系は、コンパイラが行っているような?換も?部で行っているからだ。 [ 要出典 ] 」とも言われ、『「インタプリタ言語」あるいは「コンパイラ言語」といった呼?も見掛けることがあるが、これらは?にその言語の規範的??がインタプリタかコンパイラかを示しているに過ぎない(?際、詳しく調べれば、??的な程度の??まで含めれば?方ともあるということも多い)。』という見解も出てくることになる。 高水準言語 は基本的に抽象であり、(理想的には)特定の??からは?立している。しかし、 動的プログラミング言語 のようにインタプリタでの??が向いている方向性の言語、あるいはその逆もあるということは確かである。
  3. ^ つまり、近年では高速化にはキャッシュのほうが重要なので、高速化に有利か否かはわからない。

出典 [ 編集 ]

  1. ^ bit 編集部『bit ?語帳』 共立出版 、1990年8月15日、19頁。 ISBN   4-320-02526-1  
  2. ^ a b "An interpreter dispatches a virtual instruction body to emulate each virtual instruction in turn." Zaleski (2007). YETI: a GraduallY Extensible Trace Interpreter . University of Toronto.
  3. ^ "we defined dispatch as the mechanism used by a high level language virtual machine to transfer control from the code to emulate one virtual instruction to the next." Zaleski (2007). YETI: a GraduallY Extensible Trace Interpreter . University of Toronto.
  4. ^ 日本のソフトウェアの草創期:座談?:日本のソフトウェアの草創期
  5. ^ Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I のこと
  6. ^ History of Lisp の、§3 の最後のほうに、次のようにある「S.R. Russell noticed that eval could serve as an interpreter for LISP, promptly hand coded it, and we now had a programming language with an interpreter. (段落) The unexpected appearance of an interpreter ...(後略)」
  7. ^ ポ?ル?グレアム の『ハッカ?と?家』(原著「 Hackers & Painters 、185ペ?ジ)によれば、マッカ?シ?は「ラッセルは『ねえ、この eval をプログラムしようか』と言った。…私は『ほう、ほう。君は理論と?際を混同している。この eval は?み物として書いたもので、?際に動かすために書いたものじゃない』と答えた。しかし彼はそれをやってのけた。つまり彼は私の論文にある eval IBM 704 の機械語にコンパイルして、 バグ を修正し、それを LISP インタプリタだと宣?したし、?際それはそのとおりだった。だからその時点で LISP は今日のような形態を本質的に備えていた」と述べたという。
  8. ^ "Conventional wisdom states that this indirect jump incurs a major performance degradation on deeply pipelined architectures because it is hardly predictable" Rohou, et al. (2015). Branch Prediction and the Performance of Interpreters - Don’t Trust Folklore . International Symposium on Code Generation and Optimization, Feb 2015, Burlingame, United States.
  9. ^ "we show that the accuracy of indirect branch prediction is no longer critical for interpreters." Rohou, et al. (2015). Branch Prediction and the Performance of Interpreters - Don’t Trust Folklore . International Symposium on Code Generation and Optimization, Feb 2015, Burlingame, United States.
  10. ^ AST intermediate representations Lambda the Ultimate forum
  11. ^ A Tree-Based Alternative to Java Byte-Codes — ト?マス?キスラ?、マイケル?フランズ
  12. ^ Annoucing SquirelFish
  13. ^ L. ドイチュ、A. シフマン、 Efficient implementation of the Smalltalk-80 system Proceedings of 11th POPL symposium 、1984年

?連項目 [ 編集 ]

外部リンク [ 編集 ]

この記事は2008年11月1日以前に Free On-line Dictionary of Computing から取得した項目の資料を元に、 GFDL バ?ジョン1.3以降の「RELICENSING」(再ライセンス) ?件に基づいて組み?まれている。