2013-02-09 53 views
38

जहां मैं एएसटी के निर्माण को सीख सकता हूं कि स्कैला के मैक्रोज़ उत्पन्न होते हैं?स्कैला मैक्रोज़ के लिए एएसटी बनाने के बारे में मैं कहां से सीख सकता हूं?

स्केलैडोक उतना सहायक नहीं है जितना मैं चाहूंगा। उदाहरण के लिए:

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

लेकिन मैं कैसे पता लगा सकता हूं कि नोड लागू करना क्या है? मुझे एएसटी में नोड प्रकारों की सूची कहां मिल सकती है, और वे एक साथ कैसे फिट हो सकते हैं?

उत्तर

39

कंपाइलर के आंतरिक के लिए बहुत सारे दस्तावेज उपलब्ध नहीं हैं, लेकिन उपलब्ध चीजें शुरू करने के लिए पर्याप्त होनी चाहिए।

Mirko Stocker, ने अपना Master Thesis about Scala Refactoring लिखा है। परिशिष्ट डी (पृष्ठ 95) में वह एएसटी की वास्तुकला का वर्णन करता है। यह भी एक चित्रमय सिंहावलोकन में शामिल हैं:

Scala AST

एएसटी बारे में जानकारी प्राप्त करने के लिए एक और तरीका है reflect.internal.Trees के स्रोतों, जो एएसटी शामिल में सीधे देखने के लिए है।

एक कैसे किसी विशिष्ट स्रोत कोड स्निपेट का प्रतिनिधित्व करती है पता लगाने के लिए की जरूरत है आंतरिक रूप से वहाँ 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

आप scaladoc (http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html#trees) पर एक नज़र डालें या स्लाइड पर सकता है (http://scalamacros.org/talks/2012-04-28-MetaprogrammingInScala210.pdf, " "भाग) सीखना सीखें।

यहां मैं आमतौर पर ऐसा करता हूं। मैंने parse नामक एक साधारण स्क्रिप्ट लिखी, जो स्कैला कोड को तर्क के रूप में लेती है और फिर इसे -Xprint:parser -Ystop-after:parser -Yshow-trees-stringified -Yshow-trees-compact (parse के साथ संकलित करती है, एक और सहायक स्क्रिप्ट का उपयोग करती है: adhoc-scalacclick here इसके स्रोतों को देखने के लिए भी)।

इस दृष्टिकोण का लाभ showRaw है कि यह टाइप करने के लिए कोड की आवश्यकता नहीं है। आप कोड का एक छोटा सा स्निपेट लिख सकते हैं, जो अस्तित्वहीन चर या वर्गों को संदर्भित करता है, और यह अभी भी सफलतापूर्वक चलाएगा और आपको एएसटी दिखाएगा। यहाँ उत्पादन का एक उदाहरण है:

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