2011-11-09 29 views
4

我剛剛開始我的畢業計劃,應該持續6個月。 該項目的目標是爲一種腳本語言實現.Net編譯器。我將編譯器構造作爲課程中的一個主題,並且知道如何實現一般編譯器的基本步驟,但是我們使用Bison和簡單的GCC編譯器作爲後端,因此我不太瞭解如何實現編譯器在.Net平臺上。在C#中實現編譯器最有趣和最有前途的方法是什麼?

已經進行了一些研究,這個話題我發現代碼生成以下的替代解決方案(我不是在談論編譯器的其它關鍵部分,像一個解析器 - 它是超出範圍在這裏):

  1. 使用Reflection.Emit直接生成代碼。
  2. 對Reflection.Emit使用Common Compiler Interface抽象來自動生成一些代碼。
  3. 在運行時使用CodeDOM進行C#和VB編譯。
  4. 有一種新興的C#「編譯器作爲服務」,名爲Roslyn,現在可作爲CTP使用。
  5. DLR提供了動態代碼生成支持,並通過表達式樹等
  6. 單附帶Mono.Cecil庫似乎有代碼生成一些功能,以及對運行時代碼生成一些接口。

我的項目的主要目標是深入研究.Net的內容,學習編譯器構建以及爲我的工作取得好成績。次要目標是提出一個編譯器實現,稍後可以在寬鬆的開放源代碼許可下向社區開放。

那麼,這裏最有趣,最具教育性,最有趣和最有希望的方法是什麼?如果我有更多的時間,我肯定會嘗試所有這些,但我需要在6個月內提交我的工作以獲得正面評分...

在此先感謝您, Alexander。

+0

請注意,Roslyn只是圍繞你的'1','2'和'3'的厚包裝。 – SLaks

+0

@SLaks,我認爲Roslyn實際上並沒有使用CodeDOM(#3)。 – svick

+0

我不確定那個。我懷疑你是對的。 – SLaks

回答

5

如果您希望更簡單的方法和您的語言可以合理地轉換爲C#,我會建議您生成C#代碼(或類似)並編譯它。羅斯林可能是最好的。顯然,CCI也可以使用CCI Code這樣做,但我從來沒有使用過。我不會推薦CodeDOM,因爲it doesn't support features like static classes or extension methods

如果你想要更多的控制,或者如果你想要低級別,你可以直接使用Reflection.Emit生成CIL。但是,這將會(多)更多的工作,特別是如果你不熟悉CIL。我認爲塞西爾可以以同樣的方式使用,但它是用於其他事情的,我認爲它不會比Reflection.Emit有任何優勢。

DLR的意思是,正如其全名所暗示的那樣,動態語言。它使用的Expression可用於代碼生成,但我認爲它們最適合在運行時生成相對簡單的方法。當然,如果你的語言是動態的,DLR本身可能非常有用。

2

Boo是一種面向CLI的語言/編譯器。它似乎是開源的,所以你可以研究他們如何完成它。

+0

非常有趣的建議!我讀了一本書「DSL with Boo」,甚至在我的一個工作項目中使用了Boo(作爲腳本引擎) - 但我從來沒有從編譯器構建的角度處理它。謝謝! –

2

當我編寫編譯器時,我會寫入彙編語言(即彙編語言源代碼),然後再通過系統的彙編器進行編譯。這樣我可以很容易地看到我產生的東西。讀取mov ax, bx(x86彙編)比讀取HEX操作碼更容易。

如果我不被允許在最終產品中使用匯編程序,我使用程序集輸出開發了編譯程序,然後一旦我完成所有工作,我就完成了一個二進制輸出路徑。美是,所有我必須改變的是實際的字節輸出(操作碼和二進制值而不是文本)。

我會建議爲您的項目做類似的事情。最初開發它以輸出可以用ILASM組裝的MSIL。這樣,您可以通過讀取生成的代碼輕鬆驗證代碼生成器的輸出。一旦確信代碼生成器正在工作,請添加一個輸出選項,該選項將使用Reflection.Emit或通用編譯器基礎結構。

+0

有趣的建議,謝謝! MSIL輸出很適合調試和編譯器優化。無論如何,我首先想到的是編寫一個翻譯器到C#,然後實現我自己的編譯器,因爲編譯器優化並不容易,也不透明。 –

相關問題