2

我爲我的域特定語言而不是編譯器使用解釋器(儘管表現)。我努力理解一些概念,但:口譯員如何使用DSL?

假設我有一個遊戲DSL(在XML風格),使開發人員可以使建築對象容易:

<building> 
    <name> hotel </name> 
    <capacity> 10 </capacity> 
</building> 

的DSL腳本解析,那麼會發生什麼?

它是否執行創建新建築的現有方法?據我所知,它不會簡單地將DSL轉換爲低級語言(因爲這需要編譯)。

有人可以請描述解釋器將如何處理所產生的解析樹嗎?

謝謝你的幫助。

+0

(+1)有時可以很好地使用解釋器,有時也可以將解釋器作爲製作編譯器的中間步驟 – umlcat

+0

解析某些數據後該做什麼?那麼,它不僅僅是一個遊戲化的答案,而不是編譯器/解釋器的答案。你想如何使用遊戲中已有的數據? – umlcat

回答

3

很大程度上取決於您的具體應用細節。例如,是否需要namecapacity?我會給出一個相當普通的答案,這可能有點矯枉過正。

假設:

  1. 所有嵌套的屬性都是可選的
  2. 有許多嵌套屬性,可能的變化的深度

此邀請2個想法:組織你的解釋作爲一個遞歸下降解析器和使用某種形式的建設者爲你的對象。在您的具體的例子,你有一個BuildingBuilder,看起來像(在Java中):

public class BuildingBuilder { 
    public BuildingBuilder() { ... } 
    public BuildingBuilder setName(String name) { ... return this; } 
    public BuildingBuilder setCapacity(int capacity) { ... return this; } 
    ... 
    public Building build() { ... } 
} 

現在,當你的解析器遇到building元素,使用BuildingBuilder建大樓。然後將該對象添加到DSL適用的任何上下文中(city.addBuilding(building))。

請注意,如果namecapacity是詳盡且始終需要的,則可以通過直接傳遞兩個參數來創建建築物。您也可以構建該構建,並直接按照遇到的屬性設置屬性,而不是使用構建器(如果有很多屬性並且所述屬性都是不可變的和可選的,則構建器模式很好)。

如果這是在一個非面向對象的上下文中,您將最終實現某種類型的buildBuilding函數,該函數採用當前上下文和building元素的內部xml。實際上,您正在用一個xml庫構建一個遞歸下降解析器,提供各個元素的實際解析。

然而,如果你實現它,你可能會喜歡在你的DSL中的xml元素和解釋器中的方法/對象之間有一個直接的語義映射。

+0

非常感謝您的詳細和有用的答案:) – FBryant87

+0

這就是爲什麼。我應該警告你:如果你允許引用以前的腳本對象(稍後可以通過名稱引用building「hotel」),爲便於查找創建一個散列表接口,但記住要注意範圍(如果你有範圍) 。你可以做一個堆棧,並讓每個級別的作用域在棧上推新的散列表。如果查找失敗,請進入下一級並重試。 – ccoakley