2017-02-16 8 views
4

プログラミング言語を書いたとします。名前は、langとします。JVMの言語を書く

長い旅を書き始めるには、lang、私は自分自身でlangを書くことで始めることにしました。私は実際にを実行することはできませんそれは、実行するプログラムを実行するために何もないためです。

だから私はlangのJavaで別のコンパイラを書くことから始めます。今回は、私が終わったらバイトコードに変換してそれを残すことにしました。私は今、私のすべてlangコードをバイトコードに変換する作業コンパイラを持っています。

私は自分の言語用の自己コンパイラをプラグインすることにしました。私はちょうどJavaで作成したコンパイラにプラグインしました。次に、自己コンパイラをバイトコードに変換し、Javaコンパイラを実行します。私は今langコンパイラを持っています。純粋にそれ自身で書かれ、バイトコードに変換されています。

これは完全なプログラムを作成しますが、私はこれをすべて理解していますが、私の質問は、JVMのコンパイラ設計に比べてです。バイトコードを更新するにはどうすればいいですか?古いバージョンの言語の更新版を単に書き直すだけですか?

これは私がやりたがっているためです。存在しない言語をそれ自身で作成し、Javaで最初にコンパイラを作成してJVMにブートストラップします。

C++で行ったことと同じです。クラスを持つCが書かれ、次にC++が書かれ、最終的にClassesを持つCがブートストラップされたC++のために放棄されました。しかし、その後、彼らはどのようにして言語を更新するつもりでしたか?

+1

バイトコードのデバッグはかなり苦しいことがあります。私は 'lang'の翻訳者を' java'に書くことをお勧めします。これはあなたが何をしているのかを見て翻訳されたJavaをデバッグする方法です。後でより効率的なコンパイラをバイトコードに直接書くことができます。 –

+2

@Peter Lawrey:「バイトコードのデバッグ」はめったに必要ありません。生成されたクラスファイルにソースファイル名を指定し、行番号への命令のマッピングを指定するデバッグ属性がある場合は、実際に書き込まれた言語に関係なく、Javaソースコードと同様にデバッグできます。 – Holger

+1

言語をアップグレードすると、前の言語の機能のみを使用して新しい機能を実装する必要があります。その完了後にのみ、コンパイラ内で新しい機能の使用を開始できます。 – Holger

答えて

2

私はあなたの開発の2つの可能なシナリオからこれに答えます。任意のバイトコード言語を使用すると、仮想マシンまたは言語をいつでも更新できます。

まず、新しい構文を持つように、または現在のセマンティクスを変更するために、言語を更新したいとします。その後、現在コンパイルされているコンパイラをlang(コンパイラA)とし、新しい機能を正しくコンパイルできるようにソースを編集します。次にコンパイラを与える古いコンパイラを使用してコンパイラをコンパイルしますB。必要に応じて、新しい機能を使用するようにコンパイラを書き直し、コンパイラBを使用してコンパイラをコンパイルすると、コンパイラCが得られます。

JVMが変更されたらどうなりますか?その場合、古いバージョンのJVMをそのまま使用し、新しいバイトコードの変更に対処するようにコンパイラを調整してから、古いものとコンパイルしてください(これはコンパイラのBに似ています)。それはあなたに新しいバイトコードにコンパイルするが、古いVM上で実行されるコンパイラを取得します。次のステップでは、それをコンパイルして、新しいVM(コンパイラCに似ています)で動作する新しいコンパイラを作成します。

1

私はあなたのコンパイラがこれについて最善の方法ではないと思います。

私は自分の言語の文法から始めます。

次に、私の言語の式を抽象構文木(AST)に変換するために、lexer/parserが来ます。 ASTは式の正しい中間表現です。

ASTを横断するコードジェネレータを記述することにより、仮想マシンまたはプロセッサのバイトコードまたはアセンブリ言語命令を発行します。

更新はどこで行われますか?

言語の基本事項の場合は、文法とバイトコードの両方を変更する必要があります。

バイトコードを最適化したり、新しいプロセッサに移植する場合は、コードジェネレータを変更する必要があります。

+0

ありがとうございます!しかし、言語の基本を指定するとき、私はバイトコードのエミッションを修正するので、Javaでエミッターを書くべきですか、それとも以前のバージョンか、問題の言語のコミットですか? – finnrayment

+0

文法はまた、言語リファレンスのための良い基礎です。しかし、パーザがlangで書かれるまで、あなたはjavaパーサ実装言語に身を任せます。しかし、+1 –

+0

私はそれがJavaパーサでなければならないとは言いませんでした。パーサーが元の言語で書かれているのはなぜですか?あなたが望むなら、バイソンを使用してください。 – duffymo

-1

新しいバージョンのコンパイラは、以前のバージョンのみでコンパイルできます。たとえば、G ++ 4.6をコンパイルするには、G ++ 4.5ではなくG ++ 1.0を使用する必要があります。

ところでlangのコンパイラを書く必要はありません。言語が "成熟"していることを証明しようとしていますが、一部の言語ではこれを実証する必要はありません。

1

ラングコンパイラはラングサブセットに書き込むことができます。そして、サブセット(ブートストラップ)コンパイラ(またはインターレータ)だけが必要です。これはjavaで記述することができます。

より広範なコンパイラは、langに書き込むことができます。新しいバージョンでも可能です。


あなたも、javaのにLANGプログラムを変換翻訳を書き、LANGの最初の翻訳を作成するためにそれを使用して、バイトコードコンパイラにそれを回すことができます。

関連する問題