我正在开发一个类似于Baysick的InternalDSL项目,用于构建编译器。我理解代码here的某些部分。在文件Baysick.scala
中,有隐式函数,它们是获取行号,赋值,符号等,并将它们馈送到相应的案例类中。Baysick InternalDSL
有人可以在这里解释我如何解析这个('dist := 100)
表达式吗?这里使用了哪些隐式函数,以及它对应的case类是什么。里面发生了什么?
而且,appendr()
在这里做什么?
我正在开发一个类似于Baysick的InternalDSL项目,用于构建编译器。我理解代码here的某些部分。在文件Baysick.scala
中,有隐式函数,它们是获取行号,赋值,符号等,并将它们馈送到相应的案例类中。Baysick InternalDSL
有人可以在这里解释我如何解析这个('dist := 100)
表达式吗?这里使用了哪些隐式函数,以及它对应的case类是什么。里面发生了什么?
而且,appendr()
在这里做什么?
具有单个初始刻度的文字被称为Symbol
。
搜索代码,我发现
case class Assignment(sym:Symbol)
其中也有:=
方法。
根据其scaladoc文本,它是由隐式方法symbol2Assignment
创建的。
请注意,您现在可以使用implicit class
,同时执行类和隐式转换。这也是建议。
首先,'dist
是一个符号文字,所以它会被转换成类似Symbol("dist")
的东西。
然后,:=
被解析为中缀运算符并称为方法。如果它是Symbol
的方法,那么结果将是Symbol("dist").:=(100)
。但是,没有这样的方法。
现在,隐式方法的解析发挥了作用。它会发现范围内有一个独特的隐式函数,如symbol2Assignment
,它将“适合类型槽”;也就是说,它必须有一个类型等
Symbol => { def :=(i: Int): Unit }
(模子类型),其表示“转换到Symbol
东西,有一个合适的方法:=
”。然后,这个功能被应用,我们得到
symbol2Assignment(Symbol("dist")).:=(100)
这是有效的,因为Assignment <: { def :=(i: Int): Unit }
。然后这个方法关闭它修改的一些字典。
正如我上面所说,我很清楚隐式函数和相应的案例类给他们每个人。但是如何将这个('dist:= 100)转换为scala或者可能解析为scala。 – Jordon
我可能会理解错误,但没有真正的解析,并且所有值都已经是Scala值。这是关于内部DSL的一点。他们不是独立的语言,只是古怪的说话方式。 在'('dist:= 100)'的情况下,这会将一个键值对'('dist,100)'添加到'绑定',它的类型是'绑定[字符串,整数]'。 Binding类型的对象基本上被定义为一个映射,它可以采用两种不同的值,在这种情况下是字符串和整数。 –