95

ループ、関数内の関数宣言、再帰呼び出しなどをサポートする動的型付きプログラミング言語用のコンパイラをCで(Lex&Bisonを使用して)作成しました。また、コンパイラによって作成された中間コードを実行する仮想マシンも作成しました。

自分の中間コードではなく、Javaバイトコードにコンパイルすることを考えていました。

JVM言語の作成についての質問はすでに出されているのを見ましたが、その答えはあまり有益ではありません。

だからここに私の質問があります:

  1. JVM用の言語を作成するには、JVM仕様書を読む必要があると思いますが、他にどのような本を提案できますか(もちろんドラゴンブックを除く)。私は主に、一般的なコンパイラではなく、JVM言語を作成する方法に関する本やチュートリアルに関心があります。
  2. jclasslibbcelgnuバイトコード.classなどのファイルを読み書きおよび変更するための多くのJavaライブラリがあります。どれを提案しますか?また、同じ仕事をするCライブラリを知っていますか?
  3. Clojure、Jython、JRubyなどのJVMをターゲットとする別の言語を検討することを考えていました。しかし、これらの言語はすべて非常に高レベルで複雑です(それらのコンパイラーを作成するため)。私は、JVMを対象とし、オープンソースコンパイラを使用する、より単純な(不明であるか未使用であるかは関係ありません)プログラミング言語を探していました。何か案は?
4

8 に答える 8

64

ASMもお勧めしますが、Jasminを見てください。大学のプロジェクトで使用しました(または、使用する必要がありました)。非常にうまく機能しました。JavaとJasminを使用してプログラミング言語用のレクサー-パーサー-アナライザー-オプティマイザー-ジェネレーターの組み合わせを作成したので、JVMコードを生成していました。ここにコードをアップロードしました; 興味深い部分はソースコード自体です。フォルダbytecode/InsanelyFastByteCodeCreator.javaには、ASTツリーをJasminアセンブラの入力形式に変換するコードがあります。それは非常に簡単です。

ソース言語(lexer-parser-analyzerによってASTに変換された)は、MiniJavaと呼ばれるJavaのサブセットです。継承、コンストラクター、静的メソッド、プライベートフィールド、メソッドなどの「複雑な」機能が欠けています。これらの機能はどれも実装が難しいものではありませんが、x86バックエンドを作成する(マシンアセンブラーを生成するための)別のタスクがあり、これらの機能の一部を処理するJVMがない場合、これらの機能は困難になる傾向があります。

奇妙なクラス名について疑問に思われる場合:大学のプロジェクトのタスクは、ASTをSSAグラフ(入力コードを表す)に変換し、グラフを最適化してから、Javaバイトコードに変換することでした。これはプロジェクトの作業の約3/4であり、InsanlyFastByteCodeCreatorすべてをテストするためのショートカットにすぎませんでした。

JonMeyerとTroyDowningの「JavaVirtualMachine」の本をご覧ください。この本は、ジャスミンアセンブラーを大いに参照しています。JVMの内部を理解するのに非常に役立ちます。

于 2010-08-01T20:35:52.253 に答える
16

前学期は「コンパイラ構築」コースに参加しました。私たちのプロジェクトはまさにあなたがやりたいことでした。

私が自分の言語を書くために使用した言語はScalaでした。これはJVMで実行されますが、Javaではサポートされていない多くの高度な機能をサポートしています(純粋なJava JVMと完全に互換性があります)。

Javaバイトコードを出力するために、ScalaCAFEBABEライブラリを使用しました。十分に文書化されており、何をすべきかを理解するためにJavaクラスの奥深くに入る必要はありません。

この本のほかに、コース中に行ったラボをたどることで、多くの情報を見つけることができると思います。

于 2010-08-02T21:10:45.733 に答える
5

ASMは、バイトコードを生成するためのソリューションになります。まず、マニュアルから要素を生成するためのトピックを確認します。

于 2010-08-01T02:46:25.990 に答える
5

先週末、私は自分のおもちゃの言語をJVMに移植するために同じ質問をしていました。

私は情報を検索するのにほんの数時間しか費やさないので、この参照を一粒の塩で取ってください。

  • 言語実装パターン。私はantlrが嫌いですが、この本はとてもよさそうです。どちらもantlrが気に入らない場合は、「構文解析テクニック。実用ガイド」の構文解析について非常に優れています。

    構成ファイルリーダー、データリーダー、モデル駆動型コードジェネレーター、ソース間トランスレーター、ソースアナライザー、およびインタープリターの構築方法を学びます。コンピュータサイエンスのバックグラウンドは必要ありません。ANTLRの作成者であるTerenceParrは、言語の実装を最も一般的なデザインパターンに分解することでわかりやすく説明しています。パターンごとに、独自のコンピューター言語を実装するために必要な主要なスキルを学びます。

    第10章では、このトピックを30ページ(IMOを高速化するため)でカバーしています。しかし、おそらくあなたが興味を持つであろう他の章があります。

    • 10バイトコードインタープリターの構築
      • 10.1バイトコードインタプリタのプログラミング。。
      • 10.2アセンブリ言語構文の定義
      • 10.3バイトコードマシンアーキテクチャ。。。。。
      • 10.4ここからどこへ行くか。。。。。。。。。。
      • P.26。バイトコードアセンブラ。。。。。。。。。。。
      • P.27。スタックベースのバイトコードインタプリタ。。。
      • P.28。レジスタベースのバイトコードインタプリタ
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • Lua 5.0の実装これは、レジスタベースのバイトコードマシンに関する優れた論文です。それのためにも読んでください。

    • 小片のLisp。この本は、Cにコンパイルされる2つのschmeコンパイラの書き方を教えています。この本から多くの教訓を学ぶことができます。私はこの本のコピーを持っています、そしてそれはLispである興味深い人にとって本当に良いです、しかし多分あなたのお茶ではありません。

      これは、Lispファミリーの言語全体、つまりLisp、Scheme、および関連する方言のセマンティクスと実装の包括的な説明です。11個のインタプリタと2個のコンパイラについて説明しています...

    http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473

レジスタベースのVMであるDalvik7VMを確認します。DVMは、JavaコンパイラによってコンパイルされたJavaクラスファイルから変換されたバイトコードで動作します。

トピックjvm-languagesに関するメーリングリストがあります。

コードをどこかにアップロードする予定ですか?見てみたいと思います。

于 2010-08-03T18:13:48.143 に答える
4

Clojure、Jython、JRubyなどのJVMをターゲットとする別の言語を検討することを考えていました。しかし、これらの言語はすべて非常に高レベルで複雑です(それらのコンパイラーを作成するため)。

提案:Luaプログラミング言語を見ることができます。LuaJのようなJVM実装があります。

J2MEおよびJ2SE用に記述された軽量で高速なJava中心のLua インタープリター、基本、文字列、テーブル、パッケージ、数学、io、os、デバッグおよびコルーチンパッケージ用のライブラリ、コンパイラ、luajavaバインディング、およびJSR-233プラグ可能スクリプトエンジンバインディング。

(JNIアプローチでネイティブライブラリを使用するLuaJavaと混同しないでください。)

于 2010-08-01T20:53:22.853 に答える
2

まだ知らない場合は、最初にJVMアセンブリがどのように機能するかを学ぶことをお勧めします。

多くの命令の形式はです?name。ここで、?i、命令が整数型aで機能する場合と、参照型で機能する場合です。

基本的に、JVMはレジスタのないスタックマシンであるため、すべての命令はスタック上のデータを直接処理します。?push/?popを使用して、ローカル変数(オフセットによって参照されるスタック位置)とスタックの最上位の間でデータをプッシュ/ポップおよび移動できます?store/?loadinvoke???他のいくつかの重要な指示はとif_???です。

私の大学のコンパイラコースでは、 Jasminを使用してプログラムを組み立てました。これが最善の方法かどうかはわかりませんが、少なくとも開始するのは簡単な場所です。

これは、古いバージョンのJVMの命令リファレンスであり、新しいバージョンよりも少ない命令が含まれている可能性があります。

于 2010-08-03T17:36:26.547 に答える
1

もちろん、かつてはJavaを使用して新しい言語を書くことができました。Javaリフレクション-APIを使用すると、多くのことを達成できます。速度がそれほど重要でない場合は、ASMではなくJavaを優先します。Java (IMHO)では、プログラミングが簡単でエラーが発生しにくくなっています。RPN言語7を見てください。それは完全にJavaで書かれています。

于 2018-07-09T20:46:27.877 に答える
0

まず、元に戻して、Javaバイトコードの代わりに実際のJavaを出力するようにコンパイラを変更し(コンパイラよりも多くのトランスレータを作成することを意味します)、便利なJava環境でJava出力をコンパイルします(おそらくより良いオブジェクトコードを生成します)。私自身のコンパイラよりも)。

同じ手法(たとえば、C#にコンパイル)を使用してCLIバイトコードを生成したり、PascalにコンパイルしてPコードを生成したりすることもできます。

独自のVMを使用する代わりにJavaコードを検討している理由は明らかではありませんが、パフォーマンスのためであれば、もちろん実際のマシンコードへのコンパイルも検討する必要があります。

于 2010-08-04T20:28:04.893 に答える