2013-02-09 11 views
38

ここで、Scalaのマクロが生成するASTの構築方法を学ぶことができますか?Scalaマクロ用のASTの構築については、どこで知ることができますか?

スカラドックは私が望むほど役に立たない。例:

abstract def Apply(sym: Universe.Symbol, args: Universe.Tree*): Universe.Tree 
A factory method for Apply nodes. 

しかし、どのようにアプライ・ノードがあるのでしょうか? ASTのノードタイプのリストはどこにありますか?

答えて

39

利用可能なコンパイラの内部については、多くの文書はありませんが、使用できるもので十分です。

Mirko Stockerは、彼のMaster Thesis about Scala Refactoringを書いています。付録D(95ページ)では、ASTのアーキテクチャについて説明します。また、グラフィカルな概要が含まれています

Scala AST

ASTについての情報を検索する別の方法は、ASTが含まれているreflect.internal.Treesの源、を直接見ることです。

1は、特定のソースコードスニペットがどのように表現されるか、内部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(()))) 
+0

ありがとうございます!その論文はすばらしい資源です。 – Bill

+5

ありがとうございます:-)それほど古くはありませんね。 –

+0

どうすればこのようなグラフを描くことができますか? – Freewind

22

あなたはhttp://scalamacros.org/talks/2012-04-28-MetaprogrammingInScala210.pdf(scaladoc(http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html#trees)で、またはスライドを見てみることができ、 "学習することを学ぶ ")。

ここは私が通常行っていることです。私はparseという簡単なスクリプトを書いています。スカラコードを引数にとり、-Xprint:parser -Ystop-after:parser -Yshow-trees-stringified -Yshow-trees-compactparseは別のヘルパースクリプト:adhoc-scalacclick 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後に停止します。これは、型チェッカーがパーサーツリーをどれだけ正確に変換するかを理解するために役立つことがあります。しかし、ツールボックスとマクロは両方ともパーサーツリーで動作するので、私は非常にまれにしかツリー構築目的でtypecheckを使用しません。

+0

ありがとう、ユージーン!スカラコールはとても役に立ちます。 – Bill

関連する問題