2012-07-09 20 views
5

मैक्रोज़ के साथ काम करते समय, मैं बिंदु तक पहुंच गया हूं (मैं इसे टालने के लिए कड़ी मेहनत कर रहा हूं) जहां मुझे एएसटी में उन नोड्स को अपडेट करने की आवश्यकता है, जो कुछ शर्त रखते हैं। मूल्य के साथएक अपरिवर्तनीय एएसटी अपडेट करने का सबसे आसान तरीका क्या है?

Literal(Constant(1)) 

: उदाहरण के लिए, मान लीजिए कि मैं प्रत्येक नोड अद्यतन करना चाहते हैं

Literal(Constant(2)) 

उन एएसटी नोड्स अभिव्यक्ति ट्री में कहीं हो सकता है, तो मैं एक तदर्थ उपयोग नहीं कर सकते पैटर्न matcher। जाहिर है, आखिरी चीज जो मैं करना चाहता हूं वह एक पूर्ण पैटर्न मैचर को कोड करना है जो सभी कंपाइलर प्राइमेटिव को कवर करने में सक्षम है। मैं API में खोज रहा हूं लेकिन मेरे पास यह प्रभाव है कि और ट्रैवर्सबल परिवार मेरी आवश्यकताओं को पूरा करने के लिए पर्याप्त नहीं हैं, क्योंकि वे पेड़ को एक रैखिक चीज़ के रूप में देखते हैं, और मैं पूरी तरह अद्यतन करना चाहता हूं नतीजतन पेड़। तो, क्या एक स्मार्ट तरीके से एक अपरिवर्तनीय अभिव्यक्ति वृक्ष को अद्यतन करना संभव है? मानक एपीआई में ऐसे 'अपडेट' ऑपरेशन क्यों मौजूद नहीं है?

+0

प्लगइन्स के लिए एक TreeTransformer है। मुझे लगता है कि मैक्रोज़ के लिए एक समान होना चाहिए, शायद वही भी। – pedrofurla

+0

शायद आप [zippers] (http://anti-xml.org/zippers.html) –

+0

@ निकितावोल्कोव को देखना चाहेंगे, मैं कहूंगा कि अगर वह मैक्रोज़ के संदर्भ में नहीं पूछ रहा था। – pedrofurla

उत्तर

3

यहाँ एक स्काला मैक्रो में एक एएसटी ट्रांसफार्मर का उपयोग करने का एक उदाहरण है कर रहे हैं:

https://github.com/retronym/macrocosm/blob/171be7e/src/main/scala/com/github/retronym/macrocosm/Macrocosm.scala#L129

+0

मुझे वास्तव में ट्रांसफॉर्मर के लिए स्रोत कोड देखना होगा। यह एक्सएमएल ट्रांसफॉर्म लाइब्रेरी की तरह दिखता है, और उस लाइब्रेरी में पेड़ की गहराई पर घातीय प्रदर्शन है। –

+0

इस मुद्दे पर एक जंगली शॉट: क्या यह ऊपर-नीचे बनाम नीचे-ऊपर ट्रैवर्सल से संबंधित है? एक शीर्ष-नीचे ट्रैवर्सल में, एक पत्ता बदलने से तात्पर्य पेड़ का पुनर्निर्माण होता है। उपरोक्त लिंक में 'traceImpl' के कार्यान्वयन से पता चलता है कि नए पेड़ नीचे-नीचे (कम से कम वहां) बनाए जाते हैं। लेकिन, सामान्य रूप से, यह इस बात पर निर्भर करता है कि आप 'super.transform' कैसे कहते हैं। – Blaisorblade

2

डेटा संरचनाओं में पॉली-टाइप किए गए नोड्स को संशोधित करना सामान्य रूप से डाटाटाइप जेनेरिक (प्रकार कन्स्ट्रक्टर के माध्यम से कोड का पैरामीटर) का क्लासिक केस है।

"Scrap Your Boilerplate" दृष्टिकोण जैसे कई परिचालन मौजूद हैं, जो डाटाटाइप जेनेरिक ट्रैवर्सल फ़ंक्शंस को परिभाषित करते हैं।

हास्केल में, नोड अद्यतन समारोह दो आयामों में पैरामिट्रीकृत है: डेटाप्रकार द्वारा और कोड द्वारा - तो आप एक संरचना में कहीं भी, विभिन्न प्रकार के अलग अलग अद्यतन कार्यों आवेदन कर सकते हैं:

-- | Apply a transformation everywhere in bottom-up manner 
everywhere :: (forall a. Data a => a -> a) 
      -> (forall a. Data a => a -> a) 

तो में कर हास्केल प्रकार के वर्गों पर भारी निर्भर करता है। स्काला में, वहाँ कई ported examples