我正在使用解释器来使用我的域特定语言而不是编译器(尽管有性能)。我很难理解一些概念:
假设我有一个游戏的DSL(XML格式),以便开发人员可以轻松地构建对象:
<building>
<name> hotel </name>
<capacity> 10 </capacity>
</building>
解析DSL脚本,然后会发生什么?
它是否执行创建新建筑的现有方法?据我所知,它并不是简单地将DSL转换为较低级别的语言(因为这需要编译)。
有人可以描述解释器对生成的解析树的影响吗?
感谢您的帮助。
答案 0 :(得分:3)
很大程度上取决于您的具体应用细节。例如,是否需要name
和capacity
?我将给出一个相当通用的答案,这可能有点矫枉过正。
假设:
这引发了两个想法:将解释器结构化为递归下降解析器,并为对象使用某种构建器。在您的具体示例中,您有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)
)。
请注意,如果name
和capacity
是详尽的并且始终是必需的,您可以直接传递这两个参数来创建建筑物。您还可以构建构建并直接设置属性而不是使用构建器(当您有许多属性并且所述属性都是不可变的和可选的时,构建器模式很好。)
如果这是在非面向对象的上下文中,您将最终实现某种类型的buildBuilding函数,该函数获取当前上下文和构建元素的内部xml。实际上,您正在手动构建一个递归下降解析器,其中包含一个xml库,用于提供单个元素的实际解析。
但是,如果您实现它,您可能会欣赏DSL中的xml元素与解释器中的方法/对象之间的直接语义映射。