लेकर्स बनाम पार्सर


308

क्या लेक्सर्स और पर्सर्स वास्तव में सिद्धांत में भिन्न हैं?

नियमित अभिव्यक्तियों से घृणा करना फैशनेबल लगता है: हॉरर कोडिंग , एक और ब्लॉग पोस्ट

हालांकि, लोकप्रिय lexing आधारित उपकरण: pygments , Geshi , या सुंदर बनाना , सभी उपयोग नियमित अभिव्यक्ति। वे कुछ भी करने के लिए लग रहे हो ...

कब पर्याप्त है, आपको ईबीएनएफ की आवश्यकता कब होती है?

क्या किसी ने बाइसन या एंटलर पार्सर जनरेटर के साथ इन लेक्सर्स द्वारा उत्पादित टोकन का उपयोग किया है?


2
हाँ। मैं ऑटोहोटेक को पार्स करने की कोशिश कर रहा हूं। मैं वास्तव में तेजी से pyolution का उपयोग कर एक वाक्यविन्यास हाइलाइटर बनाने में सक्षम था। लेकिन antlr में अधिक समय लग रहा है ... मैंने दो उपकरणों के बीच बहुत अधिक पार परागण नहीं देखा है।
नवीन

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

2
मैं antlr के साथ कुछ गति लेने के लिए शुरू कर रहा हूं, शुक्र है। बहुत सी लेक्सिंग संदर्भ-मुक्त है और कभी-कभी संदर्भ भी निर्भर करता है।
नवीन

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

यह ध्यान देने योग्य है कि lexers और पारसर्स नहीं है है अलग होने की, जैसे LLLPG और ANTLR के पिछले संस्करणों में एक ही डालूँगा (के) दोनों lexers और पारसर्स के लिए पार्स करने प्रणाली का उपयोग करें। मुख्य अंतर यह है कि रेक्सक्स आमतौर पर लेकर्स के लिए पर्याप्त होते हैं लेकिन पार्सर्स नहीं।
क्वर्टी

जवाबों:


475

पार्सर्स और लेकर्स आम में क्या हैं:

  1. वे अपने इनपुट से कुछ वर्णमाला के प्रतीकों को पढ़ते हैं ।

    • संकेत: वर्णमाला में अक्षरों का होना जरूरी नहीं है। लेकिन यह उन प्रतीकों का होना है जो भाषा के लिए परमाणु हैं जो पार्सर / लेक्सर द्वारा समझे गए हैं।
    • लेक्सर के प्रतीक: ASCII वर्ण।
    • पार्सर के लिए प्रतीक: विशेष टोकन, जो उनके व्याकरण के टर्मिनल प्रतीक हैं।
  2. वे इन प्रतीकों का विश्लेषण करते हैं और उन्हें उस भाषा के व्याकरण के साथ मिलान करने का प्रयास करते हैं जिसे उन्होंने समझा था।

    • यहां वह जगह है जहां असली अंतर आमतौर पर निहित है। अधिक के लिए नीचे देखें।
    • व्याकरण को लेकर्स द्वारा समझा गया: नियमित व्याकरण (चॉम्स्की का स्तर 3)।
    • व्याकरण को पार्सर्स द्वारा समझा गया: संदर्भ-मुक्त व्याकरण (चॉम्स्की का स्तर 2)।
  3. वे शब्दार्थक अर्थ (अर्थ) को उन भाषा के टुकड़ों से जोड़ते हैं जो वे पाते हैं।

    • Lexers वर्गीकृत करके अर्थ देते हैं शब्दिम विशेष रूप (इनपुट से प्रतीकों के तार) टोकन । इन जैसे सभी शब्दिम: *, ==, <=, ^"ऑपरेटर" C / C ++ lexer द्वारा निशानी के रूप में वर्गीकृत किया जाएगा।
    • पारसर्स इनपुट (वाक्य) विशेष रूप से टोकन के तार को वर्गीकृत करके अर्थ देते हैं nonterminals और निर्माण पार्स पेड़ । उदाहरण के लिए इन सभी टोकन तार: [number][operator][number], [id][operator][id], [id][operator][number][operator][number]के रूप में "अभिव्यक्ति" C / C ++ पार्सर द्वारा nonterminal वर्गीकृत किया जाएगा।
  4. वे मान्यता प्राप्त तत्वों के लिए कुछ अतिरिक्त अर्थ (डेटा) संलग्न कर सकते हैं।

    • जब एक लेक्सर एक उचित संख्या को बनाने वाले वर्ण अनुक्रम को पहचानता है, तो वह इसे अपने बाइनरी मान में बदल सकता है और "नंबर" टोकन के साथ स्टोर कर सकता है।
    • इसी तरह, जब एक पार्सर एक अभिव्यक्ति को पहचानता है, तो वह अपने मूल्य की गणना कर सकता है और वाक्यविन्यास पेड़ के "अभिव्यक्ति" नोड के साथ संग्रहीत कर सकता है।
  5. वे सभी अपने आउटपुट पर उस भाषा के उचित वाक्यों का उत्पादन करते हैं जो वे पहचानते हैं।

    • लेक्सर्स टोकन का उत्पादन करते हैं , जो नियमित भाषा के वाक्य हैं जिन्हें वे पहचानते हैं। प्रत्येक टोकन में एक आंतरिक वाक्यविन्यास हो सकता है (हालांकि स्तर 3, स्तर 2 नहीं), लेकिन यह आउटपुट डेटा और जो उन्हें पढ़ता है उसके लिए कोई फर्क नहीं पड़ता।
    • पार्सर्स सिंटैक्स पेड़ों का उत्पादन करते हैं, जो उन संदर्भ-मुक्त भाषा के वाक्यों का प्रतिनिधित्व करते हैं जो वे पहचानते हैं। आमतौर पर यह पूरे दस्तावेज़ / स्रोत फ़ाइल के लिए केवल एक बड़ा पेड़ है, क्योंकि संपूर्ण दस्तावेज़ / स्रोत फ़ाइल उनके लिए एक उचित वाक्य है। लेकिन ऐसा कोई कारण नहीं है कि क्यों पार्सर अपने आउटपुट पर सिंटैक्स पेड़ों की एक श्रृंखला का उत्पादन नहीं कर सका। उदाहरण के लिए, यह एक ऐसा पार्सर हो सकता है जो SGML टैग को सादे-पाठ में चिपका हुआ पहचानता है। तो यह टोकन की एक श्रृंखला में एसजीएमएल दस्तावेज़ को टोकन देगा :।[TXT][TAG][TAG][TXT][TAG][TXT]...

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

तो इन "चॉम्स्की के व्याकरण स्तरों" के बारे में क्या है? खैर, नोअम चोमस्की ने अपनी जटिलता के आधार पर व्याकरण को चार स्तरों में वर्गीकृत किया:

  • स्तर 3: नियमित व्याकरण

    वे रेगुलर एक्सप्रेशन का उपयोग यह है कि, वे केवल वर्णमाला के प्रतीकों में से हो सकते हैं ( a, b), उनके concatenations ( ab, aba, bbbETD।), या विकल्पों (जैसे a|b)।
    उन्हें एनएफए (नॉनडेर्मिनिस्टिक फ़िनिट ऑटोमैटन) या बेहतर डीएफए (निर्धारक फ़िनिट ऑटोमेटन) की तरह परिमित राज्य ऑटोमेटा (एफएसए) के रूप में लागू किया जा सकता है।
    नियमित रूप से व्याकरण वाले नेस्टेड सिंटैक्स के साथ संभाल नहीं सकते हैं , जैसे कि ठीक से नेस्टेड / मिलान किए गए कोष्ठक (()()(()())), नेस्टेड HTML / BBcode टैग, नेस्टेड ब्लॉक आदि। यह इसलिए है क्योंकि इससे निपटने के लिए राज्य ऑटोमेटा को असीम रूप से कई घोंसले के स्तर को संभालने के लिए असीम रूप से कई राज्यों का होना चाहिए।
  • स्तर 2: संदर्भ-मुक्त व्याकरण

    उनके पास सिंटैक्स पेड़ों में नेस्टेड, पुनरावर्ती, स्व-समान शाखाएं हो सकती हैं, इसलिए वे नेस्टेड संरचनाओं के साथ अच्छी तरह से संभाल सकते हैं।
    उन्हें स्टैक के साथ राज्य ऑटोमेटन के रूप में लागू किया जा सकता है। इस स्टैक का उपयोग वाक्य रचना के घोंसले के स्तर का प्रतिनिधित्व करने के लिए किया जाता है। व्यवहार में, वे आमतौर पर शीर्ष-नीचे, पुनरावर्ती-वंशीय पार्सर के रूप में कार्यान्वित किए जाते हैं जो नेस्टिंग स्तर को ट्रैक करने के लिए मशीन की प्रक्रिया कॉल स्टैक का उपयोग करता है, और अपने सिंटैक्स में प्रत्येक गैर-टर्मिनल प्रतीक के लिए पुनरावर्ती रूप से कॉल की गई प्रक्रियाओं / फ़ंक्शन का उपयोग करता है।
    लेकिन वे एक संदर्भ-संवेदनशील वाक्य रचना के साथ नहीं संभाल सकते । उदाहरण के लिए, जब आपके पास एक अभिव्यक्ति है x+3और एक संदर्भ में यह xएक चर का नाम हो सकता है, और दूसरे संदर्भ में यह एक फ़ंक्शन का नाम हो सकता है आदि।
  • स्तर 1: संदर्भ के प्रति संवेदनशील व्याकरण

  • स्तर 0: अप्रतिबंधित व्याकरण
    को पुनरावर्ती असंख्य व्याकरण भी कहा जाता है।


70
अरे हां? तो वे "शब्द या टोकन" क्या हैं? वे नियमित भाषा में केवल वाक्य हैं, जिसमें वर्णमाला के अक्षर शामिल हैं। और उन "निर्माण" या पार्सर में "पेड़" क्या हैं? वे वाक्य भी हैं , लेकिन एक अलग, उच्च-स्तरीय भाषा में, जिसके लिए विशेष टोकन वर्णमाला के प्रतीक हैं। अंतर यह नहीं है कि आपने क्या कहा है, लेकिन उपयोग किए गए परिसर की स्थिरता में । पार्सिंग सिद्धांत के बारे में किसी भी पुस्तिका के साथ अपने -1 का सामना करें।
SasQ

3
@ एसक्यूक्यू क्या यह कहना उचित होगा कि दोनों लेकर्स और पर्सर्स इनपुट के रूप में कुछ व्याकरण और टोकन की एक श्रृंखला लेते हैं?
पराग

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

6
उदाहरण के लिए, आप STMT_ENDनिर्देशों के अंत को दर्शाने के लिए अपने सिंटैक्स (पार्सर के लिए) में एक टर्मिनल चिन्ह का उपयोग कर सकते हैं । अब आपके पास उसी नाम से जुड़ा एक टोकन हो सकता है, जो लेक्सर द्वारा जनरेट किया गया है। लेकिन आप वास्तविक लेक्सेम को बदल सकते हैं जो इसके लिए खड़ा है। उदाहरण के लिए। आप सी / सी ++ के STMT_ENDरूप में परिभाषित कर सकते हैं ;- जैसे स्रोत कोड। या आप endइसे किसी भी तरह पास्कल-शैली के समान परिभाषित कर सकते हैं । या आप इसे केवल '\n'पंक्ति के अंत के साथ निर्देश को समाप्त करने के लिए परिभाषित कर सकते हैं , जैसे पायथन में। लेकिन निर्देश का सिंटैक्स (और पार्सर) अपरिवर्तित रहता है :-) केवल लेक्सर को बदलने की आवश्यकता है।
SasQ

24
विकिपीडिया और Google पर घंटों मदद नहीं की, लेकिन आपने 3 मिनट में चॉम्स्की के व्याकरण की व्याख्या की। धन्यवाद।
enrey

107

हां, वे सिद्धांत रूप में, और कार्यान्वयन में बहुत भिन्न हैं।

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

पार्सर्स का उपयोग भाषा वाक्यांशों की "संरचना" को पहचानने के लिए किया जाता है। इस तरह की संरचना आम तौर पर "नियमित अभिव्यक्तियों" से परे हो सकती है, इसलिए ऐसी संरचना को निकालने के लिए "संदर्भ संवेदनशील" पार्सर की आवश्यकता होती है। संदर्भ के प्रति संवेदनशील पार्सर का निर्माण कठिन होता है, इसलिए इंजीनियरिंग-समझौता "संदर्भ-मुक्त" व्याकरणों का उपयोग करना है और संदर्भ-संवेदनशील भाग को संभालने के लिए पार्सर ("प्रतीक ताल", आदि) में हैक्स जोड़ना है।

न तो लेक्सिंग और न ही पार्सिंग तकनीक के जल्द ही दूर जाने की संभावना है।

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


40
अच्छा स्पष्टीकरण, इरा। अपने सादृश्य को जोड़ना: जबकि लेक्सर्स शब्द सही होने के बारे में हैं, पार्सर वाक्यों को सही करने के बारे में हैं। "देखें स्पॉट रन" और "स्पॉट रन सी देखें" दोनों ही मान्य हैं जहां तक ​​एक लेक्सर का संबंध है। यह निर्धारित करने के लिए एक पार्सर लगता है कि वाक्यांश संरचना गलत है (अंग्रेजी व्याकरण में)।
एलन

मुझे लगता है कि एक पार्सर एक लेसर के लिए है जैसे एक पेड़ वॉकर एक पार्सर के लिए है। मुझे विश्वास नहीं है कि सिद्धांत यह है कि अलग है: antlr.org/wiki/display/~admin/ANTLR+v4+lexers लेकिन मैं उन दोनों के बीच सम्मेलन में मतभेदों को समझना शुरू कर रहा हूं ...
नवीन ने

4
सिद्धांत बहुत अलग है। अधिकांश पार्सर प्रौद्योगिकियां संदर्भ-मुक्त भाषाओं को कुछ हद तक संभालने की कोशिश कर रही हैं (कुछ केवल भाग, जैसे, एलएएलआर, कुछ यह सब करते हैं, उदाहरण के लिए, जीएलआर)। अधिकांश लेक्सर तकनीकें केवल नियमित अभिव्यक्ति करने की कोशिश करती हैं।
इरा बैक्सटर

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

1
मेरी ऑफ़िसमेट श्रेणी सिद्धांत में थी। उन्होंने दिखाया कि सभी प्रकार के पैटर्न से मेल खाते शीशों की श्रेणीबद्ध सिद्धांत धारणा किस प्रकार है, और एक सामान्य श्रेणीबद्ध विनिर्देश से एलआर पार्सिंग प्राप्त करने में सक्षम है। तो वास्तव में, यदि आप पर्याप्त रूप से अमूर्त जाते हैं, तो आप ऐसी समानताएं पा सकते हैं। श्रेणी सिद्धांत की बात यह है कि आप अक्सर "सभी तरह से" सार कर सकते हैं; मुझे यकीन है कि आप एक श्रेणी सिद्धांत पार्सर का निर्माण कर सकते हैं जो मतभेदों को मिटा देता है। लेकिन इसके किसी भी व्यावहारिक उपयोग को विशिष्ट समस्या डोमेन के लिए तत्काल करना पड़ता है, और फिर अंतर वास्तविक रूप में दिखाई देते हैं।
इरा बैक्सटर

32

कब पर्याप्त है, आपको ईबीएनएफ की आवश्यकता कब होती है?

EBNF वास्तव में व्याकरण की शक्ति में बहुत कुछ नहीं जोड़ता है । यह मानक चॉम्स्की के नॉर्मल फॉर्म (CNF) व्याकरण नियमों के ऊपर सिर्फ एक सुविधा / शॉर्टकट नोटेशन / "सिंटैक्टिक शुगर" है। उदाहरण के लिए, EBNF विकल्प:

S --> A | B

आप प्रत्येक वैकल्पिक उत्पादन को अलग से सूचीबद्ध करके CNF में प्राप्त कर सकते हैं:

S --> A      // `S` can be `A`,
S --> B      // or it can be `B`.

EBNF से वैकल्पिक तत्व:

S --> X?

आप एक अशक्त उत्पादन का उपयोग करके CNF में प्राप्त कर सकते हैं , वह है, जिसे एक खाली स्ट्रिंग द्वारा प्रतिस्थापित किया जा सकता है (यहां सिर्फ खाली उत्पादन द्वारा चिह्नित किया जाता है; अन्य एप्सिलॉन या लैम्ब्डा या क्रॉस सर्कल का उपयोग करते हैं):

S --> B       // `S` can be `B`,
B --> X       // and `B` can be just `X`,
B -->         // or it can be empty.

पिछले एक के Bऊपर के रूप में एक उत्पादन को "इरेज़र" कहा जाता है, क्योंकि यह अन्य प्रस्तुतियों में जो कुछ भी खड़ा है उसे मिटा सकता है (उत्पाद कुछ और के बजाय एक खाली स्ट्रिंग)।

EBNF से शून्य या अधिक दोहराव:

S --> A*

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

S --> S A    // `S` is just itself ended with `A` (which can be done many times),
S -->        // or it can begin with empty-string, which stops the recursion.

यह जानते हुए कि यह सिर्फ एक खाली स्ट्रिंग (अंत में) शून्य या अधिक के बाद उत्पन्न करता Aहै, एक ही स्ट्रिंग ( नहीं बल्कि एक ही भाषा! ) का उपयोग कर व्यक्त किया जा सकता सही-प्रत्यावर्तन :

S --> A S    // `S` can be `A` followed by itself (which can be done many times),
S -->        // or it can be just empty-string end, which stops the recursion.

और जब +EBNF से एक या अधिक पुनरावृत्ति की बात आती है:

S --> A+

यह पहले से फैक्टरिंग Aकरके *और पहले की तरह उपयोग करके किया जा सकता है :

S --> A A*

जिसे आप CNF में व्यक्त कर सकते हैं, (मैं यहाँ सही पुनरावर्तन का उपयोग करता हूँ; दूसरे को व्यायाम के रूप में जानने की कोशिश करें):

S --> A S   // `S` can be one `A` followed by `S` (which stands for more `A`s),
S --> A     // or it could be just one single `A`.

यह जानते हुए कि, आप अब एक व्याकरण को एक नियमित अभिव्यक्ति (यानी, नियमित व्याकरण ) के रूप में पहचान सकते हैं, जिसे केवल एकल प्रतीकों में से एक ईबीएनएफ उत्पादन में व्यक्त किया जा सकता है। आम तौर पर, आप नियमित व्याकरण को पहचान सकते हैं जब आप इन के समान प्रस्तुतियों को देखते हैं:

A -->        // Empty (nullable) production (AKA erasure).
B --> x      // Single terminal symbol.
C --> y D    // Simple state change from `C` to `D` when seeing input `y`.
E --> F z    // Simple state change from `E` to `F` when seeing input `z`.
G --> G u    // Left recursion.
H --> v H    // Right recursion.

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

लेकिन जब आपका सिंटैक्स गैर-तुच्छ तरीके से पुनरावृत्ति का उपयोग करता है, तो पेड़-जैसी, स्व-समान, नेस्टेड संरचनाओं का निर्माण करने के लिए, निम्न की तरह:

S --> a S b    // `S` can be itself "parenthesized" by `a` and `b` on both sides.
S -->          // or it could be (ultimately) empty, which ends recursion.

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

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

A R B --> A S B

आप नियम लागू करने के लिए बाईं ओर इन अतिरिक्त प्रतीकों को "संदर्भ" के रूप में सोच सकते हैं। वहाँ कुछ पूर्व शर्त हो सकती है, postconditions आदि उदाहरण के लिए, उपर्युक्त नियम विकल्प होगा Rमें Sहै, लेकिन केवल जब यह के बीच में है Aऔर Bउन छोड़ रहा है, Aऔर Bखुद को अपरिवर्तित। इस तरह के वाक्यविन्यास को पार्स करना वास्तव में कठिन है, क्योंकि इसमें एक पूर्ण विकसित ट्यूरिंग मशीन की आवश्यकता होती है। यह एक पूरी कहानी है, इसलिए मैं यहां समाप्त करूंगा।


1
आप कहते हैं कि EBNF मानक चॉम्स्की के नॉर्मल फॉर्म (CNF) व्याकरण नियमों के ऊपर "बस एक सुविधा / शॉर्टकट नोटेशन /" सिंटैक्टिक शुगर "है। लेकिन CNF के पास हाथ में विषय के साथ शायद ही कुछ है। EBNF को आसानी से मानक BNF में बदला जा सकता है। अवधि। यह मानक बीएनएफ के लिए सिंटैक्टिक चीनी है।
बाबू

11

पूछे गए प्रश्न का उत्तर देने के लिए (बिना दोहराए जो अन्य उत्तरों में प्रकट होता है)

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

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

इसीलिए "नियमित भावों से घृणा करना फैशनेबल लगता है"। हालांकि वे बहुत कुछ कर सकते हैं, उन्हें कभी-कभी इसे प्राप्त करने के लिए बहुत ही अपठनीय कोडिंग की आवश्यकता होती है, इस तथ्य का उल्लेख नहीं करने के लिए कि कार्यान्वयन में विभिन्न एक्सटेंशन और प्रतिबंध कुछ हद तक उनकी सैद्धांतिक सादगी को कम करते हैं। लेक्सर्स आमतौर पर ऐसा नहीं करते हैं, और आमतौर पर टोकन को पार्स करने के लिए एक सरल, कुशल और उपयुक्त तकनीक है। टोकन के लिए CF पार्सर का उपयोग करना अधिक भारी होगा, हालांकि यह संभव है।

लेक्सर्स के लिए सीएफ औपचारिकता का उपयोग नहीं करने का एक और कारण यह है कि यह पूरी सीएफ शक्ति का उपयोग करने के लिए आकर्षक हो सकता है। लेकिन इससे कार्यक्रमों के पठन के बारे में समस्याएँ खड़ी हो सकती हैं।

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

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

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

(ध्यान दें कि नियमित ट्रांसड्यूसर के अन्य उपयोग हो सकते हैं, जैसे कि कुछ सिंटैक्स त्रुटि हैंडलिंग तकनीकों का औपचारिककरण।)

बीएनएफ सीएफ व्याकरण प्रस्तुत करने के लिए सिर्फ एक विशिष्ट वाक्यविन्यास है।

ईबीएनएफ बीएनएफ के लिए एक सिंथेटिक्स शुगर है , जो बीएनएफ व्याकरण के टेरर संस्करण देने के लिए नियमित रूप से अंकन की सुविधाओं का उपयोग करता है। इसे हमेशा एक समान शुद्ध बीएनएफ में तब्दील किया जा सकता है।

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

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

मेरा सुझाव है कि एएचआर के जवाब को भी देखें

लेकिन यह एक सवाल छोड़ता है: पेड़ क्यों?

वाक्यविन्यास को निर्दिष्ट करने के लिए पेड़ एक अच्छा आधार हैं क्योंकि

  • वे पाठ को एक सरल संरचना देते हैं

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

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

इस तथ्य के बारे में वक्तव्य कि प्रोग्रामिंग भाषा सीएफ के बजाय संदर्भ-संवेदनशील (सीएस) हैं, मनमाना और विवादित है।

समस्या यह है कि सिंटैक्स और शब्दार्थ का अलगाव मनमाना है। घोषणाओं या प्रकार के समझौते को जाँचना सिंटैक्स के भाग, या शब्दार्थ के भाग के रूप में देखा जा सकता है। प्राकृतिक भाषाओं में लिंग और संख्या के समझौते के बारे में भी यही सच होगा। लेकिन प्राकृतिक भाषाएं हैं जहां बहुवचन समझौता शब्दों के वास्तविक अर्थ अर्थ पर निर्भर करता है, ताकि यह वाक्य रचना के साथ अच्छी तरह से फिट न हो।

अलंकारिक भाषा में प्रोग्रामिंग भाषाओं की कई परिभाषाएं, शब्दार्थ में घोषणाएं और प्रकार की जाँच करती हैं। इरा बैक्सटर द्वारा किया गया यह बताते हुए कि सिंटैक्स द्वारा आवश्यक संवेदी संवेदनशीलता प्राप्त करने के लिए सीएफ पार्सरों को हैक किया जा रहा है, जो स्थिति का सबसे अच्छा दृष्टिकोण है। इसे कुछ कंपाइलरों में हैक के रूप में व्यवस्थित किया जा सकता है, लेकिन यह होना आवश्यक नहीं है।

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


हां, पार्स ट्री और एएसटी अलग हैं, लेकिन वास्तव में उपयोगी तरीके से बहुत ज्यादा नहीं हैं। मेरी इस चर्चा को देखें: stackoverflow.com/a/1916687/120163
इरा बैक्सटर

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

"व्यावहारिक" दृश्य वह कारण है जो मैं दावा करता हूं कि वे एक उपयोगी तरीके से बहुत अलग नहीं हैं। और मैं बस विश्वास नहीं करता कि (एड हॉक एएसटी) का उपयोग करने से आपको "सही रूप से सही रूपांतर" मिलते हैं; आपके तदर्थ एएसटी के पास संसाधित किए जा रहे लैंग्वेज के वास्तविक व्याकरण का कोई स्पष्ट संबंध नहीं है (और यहां, हां, मेरी प्रणाली इस बात में दोषपूर्ण है कि हमारा "एएसटी" बीएनएफ के बराबर एक इस्मोर्फिक है)। तदर्थ ASTs न आप "कई ठोस अभ्यावेदन के लिए unparse के लिए किसी भी अतिरिक्त क्षमता) दे आप GLR (नहीं सबसे कुशल) को आपत्ति सुंदर व्यर्थ लगता है न ही वे गैर नियतात्मक कर रहे
ईरा बैक्सटर

इसलिए वास्तव में मुझे आपकी टिप्पणी पर कोई आपत्ति नहीं है। आपको यह लिखना होगा कि "स्वच्छ उत्तर"।
इरा बैक्सटर

@IraBaxter टिप्पणियाँ एक उचित उत्तर (सुझाव?) के लिए बहुत विवश हैं। एएसटी I अधिवक्ता के लिए "एड हॉक" एक उचित क्वालिफायर नहीं है, जो कि संदर्भ सिंटैक्स होना चाहिए (कभी-कभी)। यह ऐतिहासिक रूप से सच है, दोनों कंप्यूटर विज्ञान में एएसटी की अवधारणा के इतिहास को देख रहे हैं, और एक तरह से बीजगणित में शब्दों (पेड़ों) के रूप में औपचारिक प्रणालियों के इतिहास में, एक साथ व्याख्या के साथ। एएसटी संदर्भ रूप है, व्युत्पन्न नहीं है। आधुनिक प्रूफ सिस्टम और स्वचालित प्रोग्राम जनरेशन भी देखें। आप इस तथ्य से पक्षपाती हो सकते हैं कि आपको दूसरों द्वारा डिजाइन किए गए एक ठोस वाक्यविन्यास से काम करना होगा।
बबौ

7

कई कारण हैं कि एक कंपाइलर के विश्लेषण भाग को सामान्य रूप से लेक्सिकल विश्लेषण और पार्सिंग (सिंटैक्स विश्लेषण) चरणों में अलग किया जाता है।

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

संसाधन ___ कंपाइलर्स (2 डी संस्करण) द्वारा लिखित- अल्फ्रेड वी। अबो कोलंबिया यूनिवर्सिटी मोनिका एस। लाम स्टैनफोर्ड यूनिवर्सिटी रवि सेठी अवेया जेफरी डी। उलमान स्टैनफोर्ड यूनिवर्सिटी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.