我可以在哪里学习如何构建Scala的宏生成的AST?我可以从哪里学习如何为Scala宏构建AST?
Scaladoc没有我想要的那么有用。例如:
abstract def Apply(sym: Universe.Symbol, args: Universe.Tree*): Universe.Tree
A factory method for Apply nodes.
但是,如何找出Apply节点是什么?我在哪里可以找到AST的节点类型列表,以及它们如何组合在一起?
我可以在哪里学习如何构建Scala的宏生成的AST?我可以从哪里学习如何为Scala宏构建AST?
Scaladoc没有我想要的那么有用。例如:
abstract def Apply(sym: Universe.Symbol, args: Universe.Tree*): Universe.Tree
A factory method for Apply nodes.
但是,如何找出Apply节点是什么?我在哪里可以找到AST的节点类型列表,以及它们如何组合在一起?
可用编译器的内部没有太多的文档,但可用的东西应该足以开始。
Mirko Stocker,写了他的Master Thesis about Scala Refactoring。在附录D(第95页)中,他描述了AST的架构。它还包括一个图形概览:
另一种方式来查找有关AST信息直视的reflect.internal.Trees来源,其中包含了AST。
如果我们要找出一个特定的源代码片段是如何表示内部有reify
:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> showRaw(reify{val i = 0}.tree)
res8: String = Block(List(ValDef(Modifiers(), newTermName("i"), TypeTree(),
Literal(Constant(0)))), Literal(Constant(())))
你可以看看在scaladoc(http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html#trees)或幻灯片(http://scalamacros.org/talks/2012-04-28-MetaprogrammingInScala210.pdf,在“学习学习“部分)。
这是我通常做的。我写了一个名为parse
的简单脚本,它将Scala代码作为参数,然后用-Xprint:parser -Ystop-after:parser -Yshow-trees-stringified -Yshow-trees-compact
(parse
使用另一个帮助程序脚本:adhoc-scalac
.click here也可以查看它的源代码)进行编译。
此方法优于showRaw
的优点是它不需要代码进行类型检查。您可以编写一小段代码,它指向不存在的变量或类,它仍然会成功运行并向您显示AST。下面是输出的一个例子:
09:26 ~$ parse 'class C { def x = 2 }'
[[syntax trees at end of parser]]// Scala source: tmp36sVGp
package <empty> {
class C extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def x = 2
}
}
PackageDef(Ident(TermName("<empty>")), List(ClassDef(Modifiers(), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))), DefDef(Modifiers(), TermName("x"), List(), List(), TypeTree(), Literal(Constant(2))))))))
还有一个叫typecheck
脚本,它不相同,但typer
后停止。这对于理解typechecker如何转换解析器树有时很有用。但是,工具箱和宏都使用解析器树,所以我很少使用typecheck
来构建树。
谢谢,尤金! scalac调用非常有帮助。 – Bill 2013-02-12 03:15:36
谢谢!那篇论文是一个很好的资源。 – Bill 2013-02-09 21:57:22
谢谢:-)我希望它不是太过时了.. – 2013-02-10 08:50:01
我们如何绘制这样的图? – Freewind 2015-02-28 15:02:42