2009-10-04 81 views
5

我想知道部署必須至少以兩種語言(Java,C#)運行並且可能更多(Python,可能還有Javascript)的領域特定語言的好策略。編寫便攜式域特定語言

一些背景。我們已經開發並部署了一個當前用C#編寫的領域特定語言。它通過一系列方法調用進行部署,其參數是公共語言基元(字符串,double等),集合(IEnumerable,HashSet,...)或特定於領域的庫(CMLMolecule,Point3,RealSquareMatrix)中的對象。這個庫已經過很好的測試,對象必須遵守一個穩定的部署XML模式,所以變化將會演化和管理(至少這是希望)。

我們希望這個語言能夠被廣泛和部分計算機使用的社區使用,用於在沒有中央控制的情況下攻擊他們自己的解決方案。理想情況下,DSL將創建一定程度的封裝併產生他們所需的基本功能。圖書館將管理多種多樣而詳細的算法。 DSL的要求在Domain-specific languages vs. library of functions中有很多共同之處。

我很欣賞最好的體系結構(很明顯,一旦部署,我們不能輕易回溯)。選項至少包括:

  • 創建IDL(例如通過CORBA)。 W3C爲XML DOM做了這樣的工作 - 我討厭它 - 並且它似乎是過度殺傷
  • 手動爲每個平臺創建類似的簽名並盡力保持它們的同步。
  • 創建可解析語言(例如CSS)。
  • XML聲明式編程(c.f. XSLT)。這是我的首選解決方案,因爲它可以被搜索,操縱等。

性能並不重要。明確的目的是。

編輯有關應用程序調用是否構成DSL的討論。我發現了Martin Fowler對DSL的介紹(http://martinfowler.com/dslwip/Intro.html),他認爲簡單的方法調用(或者鏈接調用)可以稱爲DSL。等等一系列這樣的:

point0 = line0.intersectWith(plane); 
point1 = line1.intersectWith(plane); 
midpoint = point0.midpoint(point1); 

可以被認爲是DSL

+1

了很大的負面在XML表達的任何語言。你打算讓開發人員直接使用XML或者是存儲/運行時格式?發明ANT的人說XML是錯誤的選擇,如果他能改變事情,他會選擇不同的方式。 – SteveD 2009-10-08 14:10:55

+0

@stevendick。謝謝,我聽到你說的話。我個人是一個XML上癮者,但我儘量保持開放的態度。 – 2009-10-08 20:25:48

+0

看看ANT的原作者有什麼話:http://web.archive.org/web/20040602210721/x180.net/Articles/Java/AntAndXML.html 不要盲目地遵循XML-金錘範例。如果您打算創建一個由實際人員閱讀和寫入的DSL,請考慮使用許多優秀的詞法分析器/分析器工具中的一種,而不是XML。這些日子裏有很多很好的工具(比如ANTLR)使得這個工具很實用。現在寫lexers/parser並不像現在lex/yacc是最先進的那樣痛苦。 – 2009-10-15 01:50:00

回答

6

語言和圖書館之間的問題似乎有些不明確之處。術語「內部DSL」和「外部DSL」是有用的,我認爲是由於Martin Fowler

「外部」DSL可能是一個獨立的命令行工具。它傳遞了一串資源,它以某種方式解析它,然後用它做一些事情。對語法和語義如何工作沒有真正的限制。它也可以作爲一個庫,主要由類似eval的方法提供;一個常見的例子是將SQL查詢作爲字符串構建並在RDBMS庫中調用execute方法;不是一個非常愉快或方便的使用模式,而且如果大規模地散佈在一個程序中,那就太糟糕了。

「內部」DSL是一種庫,其編寫方式是利用主機(通用)語言的怪癖來創建新語言可嵌入現有語言的印象。在語法豐富的語言(C++,C#)中,這意味着使用操作符重載的方式嚴重拉伸(或忽略)操作符的通常意義。 C++中有很多例子。在C#中也有一些 - Irony parser toolkit以相當有限的方式模擬BNF,效果很好。

最後,還有一個普通的舊圖書館:類,方法,屬性,以及精心挑選的名字。

外部DSL將允許您完全忽略跨語言集成問題,因爲唯一類似庫的部分將是eval方法。但是發明自己的工具鏈並不重要。人們總是忘記調試,智能感知,語法突出等重要性。

如果您想在C#和Java上做好,內部DSL可能是毫無意義的努力。問題是,如果你利用一種宿主語言的怪癖,你不一定能夠重複另一種語言的技巧。例如Java沒有運算符重載。

這留下一個普通的舊圖書館。如果你想跨越C#和Java(至少),那麼你在選擇實現語言方面存在一些困難。你真的想兩次寫圖書館嗎?一種可能性是使用Java編寫庫,然後使用IKVM將其交叉編譯爲.NET程序集。這將保證你在這兩個平臺上都有相同的界面。

不利的一面是,API將用最小公因分位特徵來表示 - 也就是說,Java特性:)。沒有屬性,只需getX/setX方法。避開泛型,因爲這兩個系統在這方面有很大不同。即使這兩種命名方法的標準方式也不同(camelCasePascalCase),所以一組用戶會聞到一隻老鼠。

+0

@Earwicker +1非常有用的概述。 Java和C#的參與是一個給定的(不幸的)。我一定會嘗試IKVM。我不介意丟失屬性,泛型很簡單。命名約定可以是自動的,我希望。 我知道發明我自己的工具鏈的問題,這是一個有用的總結。 – 2009-10-04 10:15:06

+0

是的,毫無疑問,你可以編寫一個修復命名約定的工具。你甚至可以爲屬性做類似的事情 - 尋找getX/setX方法對(雖然也許一個屬性標記是必須的,因爲並非所有的getX方法都適用於屬性語法,例如有時它們具有可見的副作用)。 – 2009-10-04 10:26:09

+1

@Earwicker。這是我目前的想法。減少對儘可能多的語言的通用子集的調用(例如,不要使用屬性,當然不是運算符重載)。 – 2009-10-04 10:32:16

1

能夠逃脫在你需要做的事情,只是不被你的DSL支持,或性能方面的原因的情況下實現語言(儘管我意識到這不是優先事項)。

我正在研究在C#中的規則引擎中實現規則的DSL,其中一些規則非常複雜,並且可能在未來發生重大變化,因此能夠轉義出C#是非常有用的。當然,這會打破跨平臺兼容性,但它實際上只是一種繞過邊緣案例而不必更改DSL的方式。

+1

@戴爾。是!會出現邊緣案例,沒有理由不以這種方式加以處理,然後可能會被抽象化和泛化。我希望主要的圖書館功能無論如何都會被公開,所以我們不會有一個單一的網關。 – 2009-10-04 08:56:33

0

你最好關閉寫在C庫(或類似rpython將生成C代碼的一些語言),然後使用痛飲或類似的生成C#語言的特定綁定的Java的Python等

請注意,如果您在瀏覽器中使用Javascript,此方法將無濟於事 - 您必須單獨編寫JavaScript庫。如果您通過Rhino使用JavaScript,那麼您將只能使用Java綁定。

0

可以直接使用腳本引擎從Java程序內部解釋JavaScript,顯然也可以從C#解釋。 Python可以在JVM和.NET引擎上運行。

我建議您調查這些選項,然後將您的庫寫入可用於您選擇的語言的執行路徑的通用子集中。我不會考慮用需要翻譯和轉換的語言編寫它,因爲您引入了一個步驟,在發生問題時可能非常非常難以調試。

2

雖然我不想過多宣傳我自己的項目,但我想提一下PIL, a Platform Independent Language,這是一種我一直致力於支持多種軟件平臺(如Java,Python等)的中間語言。 ,專門用於外部DSL。總的想法是,您可以在PIL(Java的一個子集)中生成代碼,然後PIL編譯器可以轉換爲其他語言之一,目前只是Java或Python,但將來會增加更多。

大約兩天前,我在軟件和語言工程會議上介紹了關於此問題的一篇論文,如果您有興趣,可以找到PIL網站(pil-lang.org)的出版物鏈接。

+0

幾年前我嘗試過這樣的事情,看到人們做得更好很有用。 – 2009-10-08 20:27:35

3

如果您願意使用ANTLR重新描述您的語言,則可以使用多種語言生成您的DSL解釋器,而無需手動維護它們,包括所提及的所有語言以及更多。

的Antlr是一個語法/詞法分析器生成器和有大量目標語言。這允許您一次描述您的語言,而無需保留多個副本。

見目標語言here的整個列表。

+0

我個人喜歡這個想法。當然,這是一個巨大的飛躍,難以從 – 2009-10-08 20:26:22

+0

撤退。確實,有一個Antlr和StringTemplate的學習曲線。但是,我個人喜歡它。我發現越來越多的問題可以用簡單描述的語法來解決。最終,當你在轉換過程中鬆動的時候,你將不僅能夠彌補節省的維護費用。 – 2009-10-09 18:32:32

0

我想展開Darien的答案。我認爲ANTLR帶來了一些其他詞法分析器工具提供的東西(至少據我所知)。如果你想創建一個最終生成Java和C#代碼的DSL,ANTLR真的很閃耀。

ANTLR提供了四個基本要素:

  • 詞法語法(分解輸入流爲標記)
  • 分析器語法(組織標記成抽象語法樹)
  • 樹語法(走抽象語法樹並將元數據導入模板引擎)
  • StringTemplate(基於函數式編程原則的模板引擎)

您的詞法分析器,分析器和樹語法可以保持獨立於最終生成的語言。實際上,StringTemplate引擎支持模板定義的邏輯組。它甚至提供了模板組的接口繼承。這意味着,當您最初提供的所有內容都是java和C#輸出時,您可以讓第三方使用您的ANTLR解析器創建說python,assembly,c或ruby。隨着時間需求的變化,DSL的輸出語言可以很容易地擴展。

要充分利用ANTLR的你將要閱讀以下內容:

The Definitive ANTLR Reference: Building Domain-Specific Languages

Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages