JVMプログラミング言語を作成する


91

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

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

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

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

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

回答:


61

私はASMもお勧めしますが、Jasminを見て、大学のプロジェクトで使用しました(または使用する必要がありました)、それは非常にうまく機能し、lexer / parse / analyzer / optimizer / generatorの組み合わせをjavaとjasminを使用するプログラミング言語なので、JVMコードを生成します。私はここにコードをアップロードしました、興味深い部分はソースコード自体であるべきですです。「bytecode / InsanelyFastByteCodeCreator.java」フォルダには、ASTツリーをjasminアセンブラの入力形式に変換するコードが含まれています。かなり簡単です。

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

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

Jon MeyerおよびTroy Downingによる「Java Virtual Machine」の本をご覧ください。この本はJasmin-Assemblerを頻繁に参照しており、JVMの内部を理解するのに非常に役立ちます。


回答ありがとうございます。ジャスミンを見てみましょう。また、ソースをアップロードして見ていただければ幸いです。あなたが提案本書について、それが面白いようだが、それは、印刷とかなり古い:(のうちだ。

その本は非常に安い中古品です。私は数ドルでコピーを見つけました。
ナミン

上記の編集内容をご覧ください。ご不明な点がございましたら、お気軽にお問い合わせください。
theomega 2010

「ソースコード自体」へのリンクが壊れています。それは8年後に期待されると思いますが。
Llew Vallis

@LlewVallis、すべての情報を正しく解釈すると、コードはgithub.com/replimoc/compilerにあるようです。
U880D

14

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

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

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

この本の他にも、コース中に実施したラボを通して、多くの情報を見つけることができると思います。


これは素晴らしいコースのようです。メモやコードを共有していただけませんか?
ペドロ

1
問題ありません。バックアップの場所を確認し、ここにリンクを投稿して、できるだけ早くダウンロードできるようにします。

1
きちんと、私は、JVMを対象とした実践的なコンパイラーコースを探していました。このコースでは、すべての資料をオンラインで自己学習できます。
namin

5

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


4

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

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

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

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


ありがとうございました。見てみましょう

3

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

私は数時間しか情報を検索していませんので、この参考文献を一粒の塩でとってください。

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

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

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

    • 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であるDalvik7 VMを確認します。DVMは、JavaコンパイラーによってコンパイルされたJavaクラスファイルから変換されたバイトコードで動作します。

トピックについてのメーリングリストjvm-languagesがあります。

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


Are you planning to upload the code to anyplace?私は誇りに思ってそのコードのないよ:( ...私は多分全部を書き換えるだろうとにかく私がすれば、私はあなたが知っているだろう、あなたの提案をありがとうございました。。。

2

まだ分​​からない場合は、まずJVMアセンブリの仕組みを学ぶことをお勧めします。

多くの命令は、フォーム持っている?name?されているi命令が整数型とで動作するかどうかとa、それが参照タイプで動作するかどうかを。

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

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

ここに指示リファレンスがあります古いバージョンのJVMのです。新しいバージョンよりも命令の数が少ない場合があります。


0

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

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

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


JVM用にコンパイルすると、ネイティブコードにコンパイルする場合よりも、コードをより広く実行できます。さらに、バイトコードにコンパイルすると、Java言語自体では不可能ないくつかのことをコードが実行できるようになります。
スーパーキャット2013

0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.