c++ Antlr के लाभ(बनाम कहते हैं, लेक्स/yacc/बाइसन)




bison (4)

मैंने विभिन्न परियोजनाओं के लिए अतीत में लेक्स और वाईएसी (आमतौर पर बाइसन) का उपयोग किया है, आमतौर पर अनुवादक (जैसे ईडीआईएफ का सबसेट ईडीए ऐप में स्ट्रीम किया जाता है)। इसके अतिरिक्त, मुझे पिछले दशकों से संबंधित लेक्स / yacc व्याकरण के आधार पर कोड का समर्थन करना पड़ा है। इसलिए मैं उपकरण के चारों ओर अपना रास्ता जानता हूं, हालांकि मैं कोई विशेषज्ञ नहीं हूं।

मैंने अतीत में विभिन्न मंचों में एंटर के बारे में सकारात्मक टिप्पणियां देखी हैं, और मैं उत्सुक हूं कि मैं क्या खो सकता हूं। तो यदि आपने दोनों का उपयोग किया है, तो कृपया मुझे बताएं कि एंटर में बेहतर या अधिक उन्नत क्या है। मेरी वर्तमान बाधाएं हैं कि मैं एक सी ++ दुकान में काम करता हूं, और हमारे द्वारा उत्पादित किसी भी उत्पाद में जावा शामिल नहीं होगा, इसलिए परिणामस्वरूप पार्सर्स को उस नियम का पालन करना होगा।


एएनटीआरएल का एक अन्य लाभ यह है कि आप एंटरलॉर्क्स का उपयोग कर सकते हैं, हालांकि मैं यह नहीं कह सकता कि यह एक सख्त लाभ है, क्योंकि अन्य जनरेटर के लिए भी समान उपकरण हो सकते हैं।


एएनटीएलआर के लिए कुछ फायदे:

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

मेरा .02 $


एक बड़ा अंतर यह है कि एएनटीएलआर एक एलएल (*) पार्सर उत्पन्न करता है, जबकि वाईएसीसी और बाइसन दोनों एलएआरआर पार्सर्स उत्पन्न करते हैं। यह कई अनुप्रयोगों के लिए एक महत्वपूर्ण भेद है, सबसे स्पष्ट ऑपरेटरों:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

एएनटीएलआर इस व्याकरण को संभालने में पूरी तरह असमर्थ है। एएनटीएलआर (या कोई अन्य एलएल पार्सर जनरेटर) का उपयोग करने के लिए, आपको इस व्याकरण को उस चीज़ पर परिवर्तित करने की आवश्यकता होगी जो बाएं-रिकर्सिव नहीं है। हालांकि, इस फार्म के व्याकरण के साथ बाइसन में कोई समस्या नहीं है। आपको '+' और '-' को बाएं-सहयोगी ऑपरेटरों के रूप में घोषित करने की आवश्यकता होगी, लेकिन बाएं रिकर्सन के लिए इसकी कड़ाई से आवश्यकता नहीं है। एक बेहतर उदाहरण प्रेषण हो सकता है:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

ध्यान दें कि दोनों expr और actuals नियम बाएं-रिकर्सिव हैं। यह कोड पीढ़ी के लिए समय आने पर एक और अधिक कुशल एएसटी पैदा करता है क्योंकि यह एकाधिक रजिस्टरों और अनावश्यक स्पिलिंग की आवश्यकता से बचाता है (एक बाएं झुकाव वाला पेड़ ध्वस्त हो सकता है जबकि दाएं झुकाव वाला पेड़ नहीं हो सकता है)।

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


  • बाइसन और फ्लेक्स का परिणाम एक छोटी मेमोरी पदचिह्न में है, लेकिन आपके पास कोई ग्राफिकल आईडीई नहीं है।
  • एंटरलर अधिक मेमोरी का उपयोग करता है, लेकिन आपके पास एंटरलाइक्सेस, एक ग्राफिकल आईडीई है।

बाइसन / फ्लेक्स मेमोरी उपयोग आम तौर पर एक एमबीटी या तो होता है। कंट्रास्ट कि एंटरलर के साथ - यह मानते हुए कि यह उस फ़ाइल में प्रत्येक टोकन के लिए 512 बाइट्स मेमोरी का उपयोग करता है जिसे आप पार्स करना चाहते हैं। 4 मिलियन टोकन और आप 32-बिट सिस्टम पर वर्चुअल मेमोरी से बाहर हैं।

यदि आप जिस फ़ाइल को पार्स करना चाहते हैं वह बड़ा है, तो एंटरलर स्मृति से बाहर हो सकता है, इसलिए यदि आप केवल कॉन्फ़िगरेशन फ़ाइल को पार्स करना चाहते हैं, तो यह एक व्यवहार्य समाधान होगा। अन्यथा, यदि आप बहुत सारे डेटा वाले फ़ाइल को पार्स करना चाहते हैं, तो बाइसन आज़माएं।





bison