我可以在哪裏學習如何構建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