私は最近、Dragon Book を全部読みました (ただの楽しみで、実際のコンパイラを実際に実装するつもりはありません) が、この大きな疑問が頭の中にぶら下がっていました。
コンパイラーとインタープリターの実装の違いは何ですか?
私にとって、コンパイラは次のもので構成されています。
- レクサー
- パーサー (構文ツリーを構築する)
- 中間コードの生成 (3 アドレス コードなど)
- 必要に応じて、これらすべてのクレイジーなことを最適化してください:-)
- 3つのアドレスコードから「アセンブリ」または「ネイティブコード」を生成します。
さて、明らかに、インタープリターにもコンパイラーと同じレクサーとパーサーがあります。
しかし、それはその後何をしますか?
構文ツリーを「読み取り」、直接実行しますか? (ツリー内の現在のノードを指し示す命令ポインタを持つようなもので、実行は 1 つの大きなツリー トラバーサルとコール スタックのメモリ管理です) (もしそうなら、どのようにそれを行うのですか?実行は、ノードのタイプをチェックする巨大な switch ステートメントよりも優れています)
3 つのアドレス コードを生成し、それを解釈しますか? (もしそうなら、それはどのように行うのですか? 繰り返しますが、1 マイルの長い switch ステートメントよりもエレガントなものを探しています)
- 実際のネイティブ コードを生成し、メモリにロードして実行しますか? (その時点で、それはもはやインタープリターではなく、JITコンパイラーに似ていると思います)
また、「仮想マシン」の概念はどの時点で割り込まれますか? 言語で仮想マシンを何に使用しますか? (私の無知のレベルについて明確にするために、私にとって仮想マシンはVMWareです。VMの概念がプログラミング言語/プログラムの実行にどのように適用されるかわかりません)。
ご覧のとおり、私の質問は非常に広範囲です。私は主に、どの方法が使用されているかだけでなく、最初に大きな概念を理解し、次にそれがどのように機能するかを詳細に理解するために探しています. 私は醜い生の詳細が欲しい. 明らかに、これは、ここでこれらすべての詳細に回答することを期待するのではなく、読むべきものへの参照の探求です.
ありがとう!
ダニエル
編集:これまでにご回答いただきありがとうございます。しかし、私のタイトルが誤解を招くことに気づきました。コンパイラとインタープリタの「機能的な」違いを理解しています。
私が探しているのは、インタープリターとコンパイラーの実装方法の違いです。
コンパイラがどのように実装されているかを理解しました。問題は、インタプリタがそれとどのように異なるかです。
例: VB6 は明らかにコンパイラとインタプリタの両方です。コンパイラの部分がわかりました。しかし、IDE 内で実行しているときに、任意の時点でプログラムを停止し、コードを変更して、新しいコードで実行を再開する方法を理解できません。これはほんの一例であり、私が探している答えではありません。以下で説明するように、私が理解しようとしているのは、解析ツリーを作成した後に何が起こるかです。コンパイラは、「ターゲット」言語でそれから新しいコードを生成します。通訳者は何をしますか?
ご協力ありがとうございました!