我问了自己这个问题几次,并提出了一个解决方案,感觉很肮脏。也许你可以给我任何建议,因为我认为这是每个用Scala编写的DSL的基本问题。斯卡拉DSL没有额外的语法
我想拥有嵌套对象的层次结构,而无需添加任何额外的语法。规格是一个很好的例子:
MySpec extends Specification {
"system" should {
"example0" in { ... }
"example1" in { ... }
"example2" in { ... }
}
"system" can {
"example0" in { ... }
}
}
例如,我不必写"example0" in { ... } :: "example1" in { ... } :: "example2" in { ... } :: Nil
。
这和我想要的行为完全一样。我认为这是通过在规格的规范类像一个隐含的定义来实现(请不要如果你是规格作者和得罪我missunderstood东西:))现在
implicit def sus2spec(sus: Sus): Specification = {
suslist += sus
this
}
我主要的问题出现时,我想嵌套这些对象。想象一下,我有这样的语法:
root: statement*;
statement:
IDENT '{' statement* '}'
| declaration*
;
declaration: IDENT ':=' INT+;
我想转换为DSL,看起来像这样的:
MyRoot extends Root {
"statement0" is {
"nested_statement0" is {
"nested_nested_statement0" is {
"declaration0" := 0
}
"declaration1" := 1
"declaration2" := 2
}
"declaration3" := 3
}
"statement1" is {
"declaration4" := 4
}
}
即出现在这里对我来说是隐式的解决方案不起作用的问题。隐式定义将在根对象的范围内执行,这意味着我会将所有对象添加到根并且层次结构丢失。
然后我想我可以使用类似Stack [声明]的东西。每次致电is
时,我都可以推送一个对象,但感觉非常脏。
用一句话来说明问题:如何创建一个递归的DSL,并尊重其层次结构而不添加任何额外的语法,并且是否有解决方案仅对不可变对象执行此操作?
请注意,您可以很好地在规格中嵌套示例:http://code.google.com/p/specs/wiki/DeclareSpecifications#Sub_examples因此解决方案应该在那里。 – 2010-07-19 10:20:06
谢谢你指出。我想我已经找到了解决方案:“if(m.erasure == this.getClass)hasSomeSubExamples = true”。那么也许我应该坚持我的可变堆栈。 – 2010-07-19 12:56:34