web-dev-qa-db-ja.com

(コンパイラーではなく)インタープリターの業界定義は何ですか?

コンパイラーの設計コースでは、インタープリターとコンパイラーの明確な学術的定義について学び、それを使っています。

mからのプログラムを実行できるマシンで、言語Iと入力からプログラムiを取得し、与えられた入力と正しいセマンティクスでIを実行できる言語MからのプログラムPi

とコンパイラが

入力として言語Iから有効なプログラムiが与えられると、言語Oで意味的に同等のプログラムoを生成するプログラムPc

この定義は、JITコンパイルがいくら行われたとしても、JVMによる通常のJavaバイトコードの実行を解釈の領域に明確に置きます。 (もちろん、Javaも以前にJavaコードからJavaバイトコードにコンパイルされています。)このサイトでの議論で、明確かつ熱心に述べている意見に遭遇しました。逆、つまりJavaバイトコード実行のものはコンパイラです。私は学者から産業界へと飛躍しようとしているので、ここで少し混乱しています。

上記の通訳の定義は、一般の業界の人々の観点からは間違っていますか?それとも、Java人にとっては間違っているのでしょうか?完全にコンパイルされた言語としてのJavaのビューは代替ですが、少数派のビューですか?それともほんの数カナダドル?

(追記:これをcstheoryに移さないでください。私は学術界ではなく専門産業の見解を得たいので、この質問を意図的にここに置きました。)

7
thiton

この定義により、Javaバイトコードの通常の実行が解釈のドメインに置かれることになります。JITコンパイルがどれほど行われてもかまいません。このサイトでのディスカッションで、つまり、Javaバイトコード実行のものはコンパイラです。

そうですね、2つの定義は相互に排他的ではありません。インタープリターにはコンパイラーを含めることができます(実際、最新のインタープリターのほとんどには、少なくともバイトコード・コンパイラーが含まれています)。

しかし、私はここでほとんどの人が使用する直感的な定義は次のようなものだと思います:

  • コンパイラーは、CPUによって直接実行されるネイティブコードを作成します
  • インタプリタには、命令(ソースコードステートメント、またはプリコンパイルされたPコードやバイトコードなど)を読み取り、それに応じて命令を実行する、ある種の「インタプリタメインループ」があります。

この区別により、「インタプリタ」は通常、「コンパイルされた」プログラムよりも桁違いに遅くなります。したがって、パフォーマンスについて説明する場合、この定義は従来のCS定義よりも有用です。

7
nikie

上記の通訳の定義は、一般の業界の人々の観点からは間違っていますか?

番号

それともJava=人にとっては間違っていますか?

番号

完全にコンパイルされた言語としてのJavaのビューは代替ですが、少数派のビューですか?

番号

それともほんの数カナダドル?

番号

Java実行環境は、これらの理論的なCS定義で想定されているよりも複雑です。しかし、理論家と実際の開発者の両方がこれに満足しています。

このような理論的な定義は、特定の目的のために設計されています。つまり、プログラムがどのように「コンパイル」および「実行」されるかについての正式な推論。 Javaをそのようにモデル化し、モデリングにJITコンパイルを含める必要がある場合は、これを処理する方法があります。たとえば、「ネイティブコンパイル済みメソッドの呼び出し」を次のプリミティブ操作にすることができます。通訳。

現実には、Java実行プラットフォームは、直感的および理論的な意味でコンパイルと解釈の両方を使用します。したがって、Javaプラットフォームをモデル化する必要がある場合は、詳細レベルでは、これをモデリングに組み込む必要があります。

3
Stephen C

Michael Scottのプログラミング言語プラグマティクス、第3版 から。

コンパイルの概要は次のとおりです。

コンパイラーは、高レベルのソースプログラムを同等のターゲットプログラム(通常は機械語)に変換してから、削除します。後の任意の時点で、ユーザーはオペレーティングシステムにターゲットプログラムを実行するように指示します。コンパイラは、コンパイル中の統制の所在です。ターゲットプログラムは、それ自体の実行中の制御の軌跡です。

解釈の概要は次のとおりです。

コンパイラーとは異なり、インタープリターはアプリケーションの実行の周りにとどまります。実際、インタープリターはその実行中の統制の所在です。実際には、インタープリターは、「マシン言語」が高水準プログラミング言語である仮想マシンを実装します。インタープリターは、その言語のステートメントを一度に1つずつ読み取り、進行中に実行します。

ただし、一部の言語実装ではコンパイルと解釈が混在しているため、線が少しぼやけています。このような場合、ソースプログラムは、仮想マシンによって実行される中間プログラムに変換されます。ソースコードがコンパイルされ、コンパイルの出力が解釈されます。

コンパイルは、トランスレータが入力ソースファイルを徹底的に分析し、元のソースに似ていない出力を作成するときに発生します。つまり、スコットによれば、コンパイルには「分析と自明でない変換」が必要です。

3
Thomas Owens

私は通常、コードを解析してコンパイラーから下位レベルに変換するプログラムを検討します。したがって、私は間違いなくJavaコンパイラを検討します。C#、Python、PHPなどのコンパイラと同様に、ソースコードをバイトコードに減らしてから実行します。C++、Delphi、そして直接をコンパイルして、ネイティブに実行されるコードに私が呼び出す(そして私は多くの人が呼び出すと思います)「ネイティブコードコンパイラー」をコンパイルします。

インタプリタは、少なくとも私が学んだ方法いつ戻るかは、スクリプトの行を一度に1つずつ解析し、それらを直接実行するプログラムです。つまり、中間レベルまたは下位レベルのコードはありません。私は通訳者である「現代」の言語を知りません。

「コンパイラ」の定義に関しては、必ずしもJavaコードがコンパイルされていないことを意味するとは思いません。「言語O」をバイトコード命令セットとして解釈する必要があります。

1
GrandmasterB

実用的な観点から、この擬似コードを実行できるとすぐに何かが解釈されると考えることができます。

a = 6
b = 7
eval("c = a + b")
print c

セキュリティの問題、evalを使用する場合と使用しない場合のベストプラクティスなどについては説明しません。

JVMと.NETを使用すると、(標準ライブラリ関数、ラッパー、その他の問題を呼び出して)コードをその場でコンパイルできます。

a = 6
b = 7
Assembly = my_implementation_of_eval("function sum(x,y) { return x + y} ")
print Assembly.call("sum",a,b);

しかし、それはモジュールを動的にロードする機能を備えたコンパイラにすぎません。深い統合をローカル変数と比較し、インタープリターで新しい変数を作成します。

0
ZeusTheTrueGod

コンパイラは通常、言語Aから言語Bに何かを変換します。言語Bは(既存または仮想CPUの)マシンコードにすることができますが、ソースコードを別の言語で出力するコンパイラもあります。

インタプリタは通常、言語Xで記述されたプログラムを実行します。

0
oenone