口译员如何使用DSL?

时间:2011-07-05 17:02:40

标签: parsing compiler-construction programming-languages interpreter dsl

我正在使用解释器来使用我的域特定语言而不是编译器(尽管有性能)。我很难理解一些概念:

假设我有一个游戏的DSL(XML格式),以便开发人员可以轻松地构建对象:

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

解析DSL脚本,然后会发生什么?

它是否执行创建新建筑的现有方法?据我所知,它并不是简单地将DSL转换为较低级别的语言(因为这需要编译)。

有人可以描述解释器对生成的解析树的影响吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

很大程度上取决于您的具体应用细节。例如,是否需要namecapacity?我将给出一个相当通用的答案,这可能有点矫枉过正。

假设:

  1. 所有嵌套属性都是可选的
  2. 有许多嵌套属性,可能有不同的深度
  3. 这引发了两个想法:将解释器结构化为递归下降解析器,并为对象使用某种构建器。在您的具体示例中,您有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函数,该函数获取当前上下文和构建元素的内部xml。实际上,您正在手动构建一个递归下降解析器,其中包含一个xml库,用于提供单个元素的实际解析。

    但是,如果您实现它,您可能会欣赏DSL中的xml元素与解释器中的方法/对象之间的直接语义映射。