2008-09-18 9 views
10

से नियंत्रण प्रवाह ग्राफ प्राप्त करें मेरे पास जावा के लिए एएनटीएलआर पार्सर जनरेटर से प्राप्त एएसटी है। मैं जो करना चाहता हूं वह किसी भी तरह स्रोत कोड का नियंत्रण प्रवाह ग्राफ बनाता है, जहां प्रत्येक कथन या अभिव्यक्ति एक अद्वितीय नोड है। मैं समझता हूं कि इस पहचान के लिए कुछ पुनरावर्तन होना चाहिए, मैं सोच रहा था कि आप सबसे अच्छे विकल्प के रूप में क्या सुझाव देंगे और यदि एएनटीएलआर में एक टूलसेट है तो मैं इस नौकरी के लिए उपयोग कर सकता हूं। चीयर्स, क्रिससार सिंटेक्स ट्री


संपादित करें - मेरी मुख्य चिंता एएसटी से एक नियंत्रण प्रवाह ग्राफ (CFG) प्राप्त करने के लिए है। इस तरह से मैं स्रोत का वृक्ष प्रतिनिधित्व प्राप्त कर सकता हूं। स्पष्टीकरण के लिए, दोनों स्रोत कोड और कार्यान्वयन भाषा जावा है।

+0

आपको प्रश्न में अपने प्रश्न की स्पष्टीकरण देना चाहिए, ताकि उत्तर आपके प्रश्न को प्रतिबिंबित कर सकें, और टिप्पणियों में न हो। – EfForEffort

+0

"सीएफजी .... स्रोत से पेड़ का प्रतिनिधित्व प्राप्त करें ..." ?? यदि आप स्रोत कोड को पार्स करते हैं, तो आपको पेड़ का प्रतिनिधित्व मिलता है। एक सीएफजी एक ग्राफ उत्पन्न करेगा जो एएसटी नोड्स को एक साथ जोड़ता है। –

उत्तर

7

आमतौर पर CFGs एक निचले स्तर पर प्रतिनिधित्व का परिकलन किया जाता है (जैसे JVM बाईटकोड)। किसी ने कुछ साल पहले ऐसी चीजों पर a thesis किया था। उस प्रतिनिधित्व में कैसे पहुंचे इसके लिए वहां एक उपयोगी तरीका हो सकता है।

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

पहले प्रत्येक जावा स्टेटमेंट को सीएफजी में एक नोड के साथ एक प्रविष्टि और निकास नोड के साथ संबद्ध करें।,

  1. यदि वर्तमान बयान एक विधि कॉल है यह पता लगाने की जहां प्रवेश नोड कि विधि कॉल की इसी शरीर के लिए है, और एक बढ़त वर्तमान बयान से इशारा करते हुए करते हैं: एक पहली सन्निकटन के रूप में, पेड़ और चलना उस प्रवेश नोड के लिए। यदि कथन एक विधि वापसी है, तो उन स्थानों को गिनें जो इसे कह सकते थे और उन लोगों के लिए बढ़त डाल सकते थे। प्रत्येक गैर-कूदने वाले कथन के लिए
  2. , इसके और अगले कथन के बीच एक किनारा बनाओ।

यह आपको सीएफजी के कुछ प्रकार देगा। प्रक्रिया चरण 2 में थोड़ा बालों वाली है क्योंकि बुलाया जाने वाला तरीका लाइब्रेरी में घोषित किया जा सकता है, और एएसटी में कहीं और नहीं - यदि ऐसा है, तो या तो उस किनारे का प्रतिनिधित्व करने वाले विशेष नोड को किनारे न बनाएं या किनारे न बनाएं पुस्तकालय विधि।

क्या यह समझ में आता है?

+0

आपके द्वारा लिंक की जाने वाली थीसिस सीएफजी को देखने के बारे में है: उन्हें उत्पन्न नहीं कर रही है। – Lii

+0

यह "x? Y: z" ऑपरेटर द्वारा प्रेरित नियंत्रण प्रवाह को संबोधित नहीं करता है, न ही यह अपवाद हैंडलिंग लिंक को संबोधित करता है। –

+0

न ही loops और न ही "ifs" –

-1

क्या आपने कभी ANTLR Studio का प्रयास किया था? यह छेद एएसटी ग्राफ उत्पन्न नहीं करता है, लेकिन समीक्षा के लिए, यह पहले से ही काफी उपयोगी है।

+1

एएनटीएलआर स्टूडियो मूल रूप से एएनटीएलआर के स्वचालित रूप से जेनरेट किए गए पार्सर्स के लिए एक भाषा संपादक है। मेरे पास पार्सर्स और लेक्सर्स हैं। मुझे एएसटी में हेरफेर करने का एक तरीका है। कोई विचार? – user5915

0

जब मैंने अतीत में ऐसा किया है, तो मैंने ग्राफ उत्पन्न करने के लिए graphviz, विशेष रूप से डॉट टूल का उपयोग किया था। मैंने संकलन समय पर नियंत्रण-प्रवाह ग्राफ को वास्तव में घुमाकर डॉट इनपुट फ़ाइल बनाई है।

ग्राफ लेआउट हार्ड समस्या है, और ग्राफविज़ एक उत्कृष्ट काम करता है। यह पीएस, पीडीएफ, और विभिन्न छवि प्रारूपों के लिए आउटपुट कर सकते हैं, और लेआउट आमतौर पर देखने के लिए बहुत सहज है। मैं इसकी पुरजोर सलाह देता हूँ।

+0

मुझे यह जानने में अधिक दिलचस्पी होगी कि आपने ग्राफ के वास्तविक विज़ुअलाइजेशन के निर्माण के बजाय संकलन समय पर नियंत्रण प्रवाह ग्राफ़ को कैसे पार किया है। चीयर्स – user5915

+0

आमतौर पर इस बिंदु पर आपने काफी कम-स्तर कोड उत्पन्न किया है जिसमें गैर-कूदने वाले निर्देश और कूदने वाले निर्देश शामिल हैं। पूर्व सीएफजी नोड्स के अनुरूप है, और बाद में अंतर्निहित किनारों (स्थानों पर कूदने के लिए) शामिल हैं। यह भी देखें: //en.wikipedia.org/wiki/Control_flow_graph। – EfForEffort

+0

आप "कोड जनरेशन" पर पढ़ना चाहेंगे: http://en.wikipedia.org/wiki/Code_generation_(compiler) - यह आपके एएसटी से कुछ निम्न-स्तरीय प्रतिनिधित्व में जाने की प्रक्रिया है, और यह आमतौर पर सीएफजी के निर्माण से पहले। – EfForEffort

1

कुछ टिप्पणियों के आधार पर, ऐसा लगता है कि ओपी वास्तव में code generation करना चाहता है - एएसटी को बुनियादी ब्लॉक और कूद बिंदुओं के आधार पर निर्देशों के निचले स्तर के अनुक्रम में परिवर्तित करने के लिए।

कोड जनरेशन बहुत भाषा-विशिष्ट है, और इस विषय में बहुत सारे काम किए गए हैं। कोड जनरेशन करने से पहले आपको अपनी लक्ष्य भाषा जानना होगा - चाहे वह असेंबलर हो या बस कुछ अन्य उच्च-स्तरीय भाषा हो। एक बार जब आप इसे पहचान लेंगे, तो आपको बस एएसटी चलने और एएसटी में कोड लागू करने वाले निर्देशों का अनुक्रम उत्पन्न करने की आवश्यकता है। (मैं कहता हूं कि यह आसान है, लेकिन यह सामान्य हो सकता है क्योंकि यहां पर विचार काफी भाषा-विशिष्ट हैं।)

कोड पीढ़ी के लिए आपके द्वारा चुने गए प्रतिनिधित्व में नियंत्रण-प्रवाह ग्राफ, अंतर्निहित या स्पष्ट रूप से। यदि आपकी लक्षित भाषा काफी कम-स्तर (असेंबलर के नजदीक) है, तो नियंत्रण-प्रवाह ग्राफ निकालने के लिए अपेक्षाकृत आसान होना चाहिए।

(यदि आप और स्पष्टीकरण चाहें कृपया टिप्पणी।)

+0

मैं मानता हूं कि लक्षित भाषा (जावा) का ज्ञान अनिवार्य है। मैं कुछ अंतर्दृष्टि की तलाश में हूं कि कैसे एएसटी चलने के लिए एक रूप में चलना है जो निश्चित रूप से नियंत्रण प्रवाह ग्राफ रखता है। कोई सुझाव? – user5915

+0

यदि आप जानते हैं कि जावा कैसे उत्पन्न करें, तो जावा से सीएफजी बनाने के लिए: प्रत्येक कथन के लिए नोड बनाएं जो आपके प्रोग्राम में विधि कॉल नहीं है। विधि कॉल के लिए, उस विधि के लिए शरीर के प्रवेश के लिए किनारे खींचें। – EfForEffort

+0

आम तौर पर यह एक कठिन काम है, भले ही मैं आपकी स्रोत भाषा जानता हूं, जो मैं नहीं करता हूं। आपको बस जावा में अपनी स्रोत भाषा संरचनाओं के मैपिंग के साथ आना होगा। – EfForEffort

3

एक पूर्ण नियंत्रण प्रवाह ग्राफ का निर्माण करना जो वास्तव में सभी भाषा समस्याओं को ध्यान में रखता है, यह दिखने से कठिन है। न केवल आपको यह पता होना चाहिए कि "मूलभूत ब्लॉक" प्रतीत होता है, लेकिन आपको फ़ंक्शन कॉल (आसान प्रकार की पहचान करना है, लेकिन लक्ष्य को पहचानना कठिन हो सकता है), जहां पीछे के दृश्य संचालन जैसे वर्ग प्रारंभकर्ता हो सकते हैं। और उन बिंदुओं के बारे में चिंता करने के लिए जहां अपवाद हो सकते हैं और जहां कोई अपवाद होता है तो नियंत्रण कहां जाता है।

आप सबसे अधिक भाषाओं को ध्यान से जांच करते हैं, तो वे भी भाव, में संगणना के मूल्यांकन के आदेश के बारे में स्पष्ट हो जाएगा और इस मायने रखती है अगर आप एक अभिव्यक्ति में दो दुष्प्रभाव; नियंत्रण प्रवाह ऑर्डर को प्रतिबिंबित करना चाहिए (या गैर-ऑर्डर, यदि यह परिभाषित नहीं किया गया है)।

शायद आप केवल मूल प्रवाह और सशर्त होने वाले नियंत्रण प्रवाह का एक अमूर्त चाहते हैं। यह स्पष्ट रूप से थोड़ा आसान है।

या तो मामले में (सरल CFG या पूर्ण CFG), आप संभव नियंत्रण प्रवाह लक्ष्य के लिए एक संदर्भ होने के प्रत्येक बिंदु पर एएसटी, चलने के लिए की जरूरत है (उदाहरण के लिए, इस तरह के बयानों अगर के रूप में ज्यादातर मामलों, के लिए, वहाँ दो हैं प्रवाह लक्ष्य: THEN और ELSE खंड)। प्रत्येक नोड पर, उस नोड को पर उचित नियंत्रण प्रवाह लक्ष्य से लिंक करें, संभवतः प्रवाह लक्ष्य (उदा।, जब आप आईएफ का सामना करते हैं) को प्रतिस्थापित करते हैं।

जावा (या सी) की पूर्ण भाषा अर्थशास्त्र के लिए ऐसा करने के लिए काफी बहुत काम है। आप बस उस टूल का उपयोग करना चाह सकते हैं जो ऑफ-द-शेल्फ की गणना करता है। http://www.semanticdesigns.com/Products/DMS/FlowAnalysis.html देखें जो हमारे उपकरणों से बाहर निकलने के लिए वास्तव में दिखता है।

संबंधित मुद्दे