2012-11-17 16 views
8

मैं एक बार में एक रोसलिन वाक्य रचना पेड़ के लिए कई संशोधन करने के लिए इच्छुक रहा हूँ पर एक SyntaxTree करने के लिए कई संशोधन करने, केवल पहले संशोधन सफल होता है। ऐसा लगता है कि पहला परिवर्तन इसके आसपास के सभी नोड्स को बदलता है, इसलिए RemoveNodes विधि अब परिणामस्वरूप पेड़ में toRemove नहीं पाती है। मैं वास्तव में, वास्तव में, नए पेड़ में toRemove की पुन: गणना करने के लिए काम फिर से नहीं करना चाहता, और सभी काम करने के लिए एक सिंटेक्स रेवाइटर का उपयोग करना (DefaultVisit विधि को ओवरराइड करना) हास्यास्पद रूप से धीमा है।सभी तथापि कोड</p> <pre><code>tree = tree.ReplaceNodes(oldNode, newNode).RemoveNode(toRemove); </code></pre> <p>के एक ही क्षेत्र के आसपास, एक बार

मैं जो कर सकता हूं वह मैं कैसे कर सकता हूं?

उत्तर

5

इससे पहले कि मैं कुछ विकल्प प्रदान करता हूं, आपकी टिप्पणी है कि एक सिंटेक्स रेवाइटर "हास्यास्पद रूप से धीमा" थोड़ा आश्चर्यजनक है। जब आप कहते हैं "धीमा" क्या आपका मतलब है "यह लिखने के लिए बहुत सारे कोड हैं" या "यह बहुत प्रदर्शन कर रहा है"? यह एकाधिक प्रतिस्थापन करने का सबसे तेज़ (निष्पादन समयवार) तरीका है, और दोनों ReplaceNodes और RemoveNode आंतरिक रूप से एक पुनःलेखक का उपयोग करते हैं। यदि आपको प्रदर्शन समस्याएं आ रही हैं, तो सुनिश्चित करें कि जब आप अपनी डिफ़ॉल्ट विज़िट को कार्यान्वित करते हैं, तो आप केवल बच्चे के प्रकारों पर जाते हैं यदि आप जिन नोड्स में रूचि रखते हैं, वे नोड के नीचे हैं। सरल चाल स्पैन की तुलना करना और सुनिश्चित करना है कि नोड का विस्तार नोड्स के साथ छेड़छाड़ करता है जो आप प्रसंस्करण कर रहे हैं।

फिर भी, SyntaxAnnotations किसी संशोधन के बाद पेड़ में नोड्स पता लगाने के लिए एक उपयोगी तरीका प्रदान करते हैं। आप बस प्रकार का एक उदाहरण बना सकते हैं, और इसे WithAdditionalAnnotations एक्सटेंशन विधि के साथ नोड में संलग्न कर सकते हैं। आप GetAnnotatedNodesOrTokens विधि के साथ फिर से नोड का पता लगा सकते हैं।

तो एक तरह से अपनी समस्या के दृष्टिकोण अपने toRemove टिप्पणी करने के लिए है, और फिर जब तुम ReplaceNodes एक ही कॉल में दो प्रतिस्थापन कर कहते हैं - एक oldNode करने के लिए -> newNode प्रतिस्थापन और फिर एक toRemove करने के लिए -> toRemoveWithAnotation प्रतिस्थापन। फिर परिणामी पेड़ में एनोटेटेड नोड पाएं और RemoveNode पर कॉल करें।

यदि आप जानते हैं कि पुराना नोड और टूमोव एक दूसरे के पूर्वजों नहीं हैं (यानी वे पेड़ के असंबंधित हिस्सों में हैं), तो दूसरा विकल्प आदेश को उलट देना होगा। माता-पिता नोड को पकड़ें (इसे पुराना नोडपेरेंट कहते हैं) को हटाने और निकालें नोड को कॉल करें, जिसका अर्थ है कि आपको एक अपडेटेड पैरेंट नोड मिलता है (इसे पुराना नोडपेरेंट रिवाइट किया जाता है)। फिर, दो प्रतिस्थापन करने वाले ReplaceNodes को कॉल करें: oldNode -> newNode और oldNodeParent -> oldNodeParentRewritten। कोई टिप्पणी की जरूरत नहीं है।