2011-11-09 6 views
4

私はちょうど6ヶ月間続くはずの私の卒業プロジェクトの冒頭にあります。 プロジェクトの目的は、1つのスクリプト言語用の.Netコンパイラを実装することです。私はカリキュラムの主題としてコンパイラ構築をしていましたが、一般的にコンパイラを実装する基本的な手順を認識していましたが、BisonとGCCを使用した単純なコンパイラをバックエンドとして使用していました。 .Netプラットフォームで。C#でコンパイラを実装する最も興味深く有望なアプローチは何ですか?

はこのトピックに関するいくつかの研究を行ってきたが、私は(私はパーサのように、コンパイラの他の要部の話ではないのです - それはここで範囲外である)コード生成のための次の代替の解決策を見つけた:

  1. Reflection.Emitを使用したダイレクトコード生成。
  2. Common Compiler Interfaceリフレクションの抽象化を使用して、コード生成の自動化を行います。
  3. 実行時にC#およびVBコンパイルにCodeDOMを使用します。
  4. Roslynと呼ばれる新しく登場するC#の "サービスとしてのコンパイラ"がCTPとして利用可能になりました。
  5. DLRはモノも同様に、コード生成のためのいくつかの機能を持っているようだMono.Cecilライブラリが同梱されて
  6. などを動的なコード生成のためのサポートを提供し、式ツリーを経由して実行時のコード生成のためのいくつかのインタフェースを持っています。

私のプロジェクトの主な目的は、.Netの要点を深く掘り下げ、コンパイラの構築を学び、自分の仕事のグレードを向上させることです。 2番目の目標は、後で許可されたオープンソースライセンスの下でコミュニティに開かれるコンパイラの実装を考え出すことです。

ここで、最も興味深く、教育的で面白く有望なアプローチは何でしょうか?私はもう少し時間があれば絶対に試してみましたが、正のグレードを得るために6ヶ月で私の仕事を提出する必要があります...

ありがとうございます、 アレクサンダー。

+0

Roslynは、あなたの '1'、' 2'、 '3'のまわりの太いラッパーであることに注意してください。 – SLaks

+0

@SLaks、私はRoslynがCodeDOM(#3)を実際に使用していないと思う。 – svick

+0

私はそのことについてはわかりませんでした。私はあなたが正しいと思う。 – SLaks

答えて

5

言語を合理的にC#に変換できるようにするには、C#コード(または同様のもの)を生成してコンパイルすることをお勧めします。おそらくRoslynはそれで最高だろう。明らかに、CCIもCCI Codeを使用してそれを行うことができますが、私はそれを使ったことはありません。 it doesn't support features like static classes or extension methodsのようにCodeDOMはおすすめしません。

さらに制御したい場合や、低レベルにしたい場合は、Reflection.Emitを使用して直接CILを生成できます。しかし、特にCILに精通していない人にとっては、はるかに多くの作業が必要になります。セシルは同じ方法で使うことができると思いますが、それは他のものを意図したものです。私はそれがリフレクションよりも利点はないと思います。

DLRは、動的言語では、そのフルネームが示すとおり、意味します。コード生成には、それが使用するExpressionを使用できますが、実行時に比較的簡単なメソッドを生成するのに最適です。もちろん、あなたの言語が動的であれば、DLR自体は非常に便利です。

2

Booは、CLIをターゲットとする言語/コンパイラです。それはオープンソースのように見えますので、あなたはどのようにそれを達成するかを学ぶことができます。

+0

非常に興味深い提案!私は書籍 "DSL with Boo"を読んで、私の作業プロジェクトの一つでBoo(スクリプティングエンジン)を使っていましたが、私はコンパイラ構築の面からは扱っていませんでした。ありがとうございました! –

2

私がコンパイラを書いていたとき、アセンブリ言語(つまりアセンブリ言語のソースコード)に書き込んで、システムのアセンブラを実行しました。そうすれば、私は自分が作り出しているものを簡単に見ることができました。 mov ax, bx(x86アセンブリ)は、HEXオペコードをデコードするよりもずっと簡単です。

最終製品でアセンブラを使用できない場合は、アセンブリ出力を使用してコンパイラを開発した後、すべての作業が完了したらバイナリ出力パスを作成しました。私が変えなければならなかったのは、実際のバイト出力(テキストではなくオペコードとバイナリ値)でした。

あなたのプロジェクトに似たようなことをお勧めします。まず、ILASMでアセンブルできるMSILを出力するように開発します。このようにして、生成されたコードを読むことで、コードジェネレータの出力を簡単に検証できます。コードジェネレータが動作していることを確認したら、Reflection.EmitまたはCommon Compiler Infrastructureを使用する出力オプションを追加します。

+0

面白い提案、ありがとうございます! MSIL出力は、デバッグの目的やコンパイラの最適化に適しています。とにかく、私は最初にC#に翻訳者を書いてから自分のコンパイラを実装することを考えていますが、コンパイラの最適化は簡単ではなく、簡単です。 –