शाब्दिक विश्लेषण व सिंटैक्स विश्लेषण
लेक्सर क्या कर सकता है और क्या नहीं
शाब्दिक विश्लेषण अक्षरों की धारा को टोकनों की धारा में बदलता है। तीन शब्दों को पृथक् रखना उपयोगी है क्योंकि प्रश्न उन्हें ठीक-ठीक बरतते हैं: पैटर्न नियम है (एक नियमित व्यंजक), लेक्सीम स्रोत में मिला अक्षरों का वास्तविक क्रम है, और टोकन वह है जो लेक्सर पार्सर को देता है — पैटर्न का नाम तथा प्रायः एक गुण। count = 10 में लेक्सीम count, = व 10 हैं, और टोकन आइडेंटिफ़ायर, असाइन व नंबर, जिनमें आइडेंटिफ़ायर प्रतीक-सारणी प्रविष्टि तथा नंबर अपना मान धारण करता है। सम्पूर्ण चरण एक परिमित स्वचालित्र से बना है, जो तय कर देता है कि वह क्या पहचान सकता है: ठीक नियमित भाषाएँ, और कुछ नहीं।
x<=y तीन टोकन हैं, चार नहीं, क्योंकि <= < को हरा देता है। और int x = a+++b; आठ टोकन हैं — int, x, =, a, ++, +, b, ; — क्योंकि पहले + पर दीर्घतम मेल ++ है, जो एक + पीछे छोड़ता है; तब पार्सर के पास उसे (a++) + b पढ़ने के अतिरिक्त कोई विकल्प नहीं। बराबरी-भंजन कुंजी-शब्दों हेतु महत्व रखता है: if कुंजी-शब्द पैटर्न व आइडेंटिफ़ायर पैटर्न दोनों से समान लंबाई पर मेल खाता है, अतः कुंजी-शब्द नियम पहले सूचीबद्ध होता है, और कुंजी-शब्द आइडेंटिफ़ायर न होने का सम्पूर्ण कारण वही है।( व ) को टोकन के रूप में सहर्ष बताएगा और यह नहीं बता सकता कि वे संतुलित हैं या नहीं, और कारण अभिकल्प का चयन नहीं अपितु एक कठोर सीमा है। संतुलित कोष्ठकों को असीमित गणना चाहिए, अतः संतुलित मालाओं की भाषा नियमित नहीं है, और परिमित स्वचालित्र के पास नियत संख्या में अवस्थाएँ हैं, गणना रखने का कोई स्थान नहीं। वही सीमा खंड 6 खींचता है, यहाँ अभियांत्रिकी तथ्य बनकर आती है: कोष्ठक मिलाना संदर्भ-मुक्त समस्या है, वह पार्सर की है, और ठीक इसीलिए पार्सर को स्टैक दिया जाता है जहाँ लेक्सर को नहीं। श्रम-विभाजन को भाषा-वर्गों से पढ़ लें और यह चरण संकेतों की सूची होना बंद कर देता है।FIRST व FOLLOW, अनुमान के बजाय गणना
वाम-पुनरावर्तन हटाकर मानक व्यंजक व्याकरण लें: E → T X, X → + T X | ε, T → F Y, Y → * F Y | ε, F → ( E ) | id। नीचे के दोनों समुच्चय नियत-बिंदु कलनविधियाँ चलाकर बने, और इस व्याकरण में कोई LL(1) संघर्ष ही नहीं निकलता — वह LL(1) है, और वाम-पुनरावर्तन हटाने का सम्पूर्ण कारण वही है।
| अ-टर्मिनल | FIRST | FOLLOW |
|---|---|---|
| E | { (, id } | { $, ) } |
| X | { +, ε } | { $, ) } |
| T | { (, id } | { $, ), + } |
| Y | { *, ε } | { $, ), + } |
| F | { (, id } | { $, ), *, + } |
व्याकरण कहाँ विफल होते हैं, और वह कौन-सी विफलता है
| व्याकरण का गुण | वह क्या बाहर करता है | क्यों |
|---|---|---|
| वाम-पुनरावर्तन, A → A α | कभी LL(1) नहीं | ऊपर-से-नीचे निवेश खपाए बिना पुनरावर्तित होता |
| सामान्य उपसर्ग, A → α β | α γ | वाम-गुणनखंडन तक LL(1) नहीं | एक लुकअहेड टोकन दोनों को पृथक् नहीं कर सकता |
| अस्पष्टता | किसी भी प्रकार का LR कभी नहीं | एक माला हेतु दो वृक्ष — चुनने का आधार नहीं |
S → if S else S | if S | a लें। FIRST(S) = { if, a } तथा FOLLOW(S) = { $, else }। LL(1) सारणी भरने पर कोष्ठ (S, if) में दोनों if-उत्पादन आ जाते हैं, क्योंकि दोनों उसी टोकन से आरंभ होते हैं — एक संघर्षित कोष्ठ, और व्याकरण LL(1) नहीं। गहन समस्या यह है कि वह अस्पष्ट है: if a else a के दो पार्स वृक्ष हैं, और कितना भी लुकअहेड अस्पष्टता ठीक नहीं करता, अतः व्याकरण LR(1) भी नहीं। वास्तविक संकलक व्याकरण ठीक नहीं करते; वे उसके बाहर एक नियम जोड़ते हैं — else निकटतम अ-मिलान if से बँधता है — जो व्याकरणिक मरम्मत के बजाय अस्पष्टता-निवारण नीति है। वह भेद रखने योग्य है: पार्सर जनरेटर डैंगलिंग else कैसे सँभालता है यह पूछता प्रश्न नीति के विषय में है, और व्याकरण LL(1) है क्या यह पूछता प्रश्न सारणी के विषय में।| वर्ग | वह क्या प्रयोग करता है | सारणी आकार |
|---|---|---|
| LR(0) | कोई लुकअहेड नहीं | सबसे छोटा |
| SLR(1) | LR(0) अवस्थाएँ + FOLLOW समुच्चय | LR(0) जितनी ही अवस्थाएँ |
| LALR(1) | कोर से विलीन LR(1) अवस्थाएँ | LR(0) जितनी ही अवस्थाएँ — यही yacc बनाता है |
| LR(1) | प्रति आइटम पूर्ण लुकअहेड | सबसे बड़ा — प्रायः अव्यावहारिक |
LR(0) आइटम समुच्चय गिनना
व्याकरण S′ → S, S → C C, C → c C | d हेतु प्रामाणिक संग्रह बनाने पर — संवरण, फिर प्रत्येक प्रतीक पर goto जब तक कुछ नया न आए — 7 आइटम समुच्चय मिलते हैं, और वह गणना उसे बनाकर नहीं, रचना चलाकर बनी। वह इस व्याकरण हेतु SLR(1) व LALR(1) सारणियों की अवस्थाओं की संख्या भी है, क्योंकि दोनों LR(0) अवस्था-समुच्चय अपरिवर्तित प्रयोग करते हैं और केवल इसमें भिन्न हैं कि वे क्रिया-प्रविष्टियाँ कैसे भरते हैं।
मुख्य बिंदु
- लेक्सिंग नियमित समस्या है व पार्सिंग संदर्भ-मुक्त — लेक्सर अंतःस्थापित कोष्ठक नहीं मिला सकता।
- FOLLOW, LL(1) सारणी में केवल ε व्युत्पन्न कर सकते उत्पादनों हेतु आता है — पहले उन्हें जाँचें।
- वाम-पुनरावर्ती व्याकरण कभी LL(1) नहीं; सामान्य उपसर्ग को पहले वाम-गुणनखंडन चाहिए।
- अस्पष्ट व्याकरण किसी भी प्रकार का LR कभी नहीं — कोई लुकअहेड अस्पष्टता की मरम्मत नहीं करता।
- डैंगलिंग-else व्याकरण में ठीक एक संघर्षित LL(1) कोष्ठ है, (S, if) पर।
- वास्तविक संकलक डैंगलिंग else को व्याकरण के बाहर के नियम से सुलझाते हैं, उसे ठीक करके नहीं।
- LL(1) ⊂ SLR(1) ⊂ LALR(1) ⊂ LR(1), और प्रत्येक अंतर्वेशन कठोर है।
- LR(0), SLR व LALR एक ही अवस्था-गणना साझा करते हैं; केवल प्रामाणिक LR(1) के पास अधिक। yacc, LALR(1) बनाता है।
अभ्यास प्रश्न (8)
उत्तर खोलने से पहले प्रत्येक प्रश्न हल करें। हर व्याख्या सही विकल्प के साथ लुभावना गलत विकल्प भी बताती है, क्योंकि अंक वहीं जाते हैं।
व्याकरण E → T X, X → + T X | ε, T → F Y, Y → * F Y | ε, F → ( E ) | id हेतु समुच्चय FOLLOW(T) है:
उत्तर देखें
उत्तर: B — { $, ), + }
{ $, ), + }।E → T Xमें T के पश्चात् X आता है, अतः FIRST(X) − {ε} = { + } भीतर जाता है; और चूँकि X, ε व्युत्पन्न कर सकता है, FOLLOW(E) = { $, ) } में सब कुछ भी T के पश्चात् आता है। विकल्प A, FOLLOW(E) व FOLLOW(X) है, जो वस्तुतः भिन्न समुच्चय है — यह देखना कि E व X एक FOLLOW साझा करते हैं जबकि T व Y बड़ा वाला, सम्पूर्ण गणना पर अच्छी जाँच है। विकल्प C, FOLLOW(F) है, जो अतिरिक्त रूप से*उठाता है क्योंकि F के पश्चात् Y आता है। यहाँ काम करता यांत्रिक नियम यह है कि जब पश्चवर्ती अ-टर्मिनल लुप्त हो सके, तो वाम पक्ष का FOLLOW बहकर आ जाता है।किसी व्याकरण में उत्पादन A → A α है। इससे निकलता है कि वह व्याकरण:
उत्तर देखें
उत्तर: A — LL(1) नहीं है
LL(1) नहीं। ऊपर-से-नीचे पार्सर स्टैक पर A देखकर A → A α चुनने पर कोई निवेश खपाए बिना पुनः A पुश करेगा, और अनंत काल ऐसा कर सकता है — अतः वाम-पुनरावर्तन किसी भी k हेतु LL(k) पर पूर्ण रोक है। परंतु वह LR हेतु कोई अवरोध ही नहीं, जो नीचे-से-ऊपर है और वाम-पुनरावर्तन स्वाभाविक रूप से सँभालता है, वस्तुतः उसे पसंद करता है क्योंकि वह स्टैक उथला रखता है। विकल्प C नामित करने योग्य त्रुटि है: वाम-पुनरावर्तन व अस्पष्टता असंबद्ध हैं, और मानक वाम-पुनरावर्ती व्यंजक व्याकरण पूर्णतः अनस्पष्ट है। व्यावहारिक परिणाम यह है कि वाम-पुनरावर्तन हटाना केवल ऊपर-से-नीचे पार्सर हेतु उठाया कदम है, और वही व्यंजक व्याकरण को ऊपर प्रयुक्त LL(1) रूप में बदलता है।व्याकरण S′ → S, S → C C, C → c C | d हेतु प्रामाणिक LR(0) संग्रह में कितने आइटम समुच्चय हैं?
संख्यात्मक उत्तर — मान टाइप करें।
उत्तर देखें
उत्तर: 7
सात।S′ → · Sका संवरण लें, फिर S, C, c व d पर बारंबार goto लगाएँ जब तक कोई नया समुच्चय न आए; रचना सात आइटम समुच्चयों पर समाप्त होती है। आँकड़ा दो बार महत्व रखता है, क्योंकि वह इस व्याकरण हेतु SLR(1) व LALR(1) सारणियों की अवस्थाओं की संख्या भी है — उनमें कोई स्वचालित्र नहीं बदलता, वे केवल यह बदलते हैं कि न्यूनन-प्रविष्टियाँ कैसे भरी जाएँ। केवल प्रामाणिक LR(1) के पास अधिक होतीं। अतः "SLR पार्सर में अवस्थाओं की संख्या" पूछता प्रश्न यही 7 चाहता है, और इसके बजाय LR(1) संग्रह निकालना गलत उत्तर हेतु अधिक काम है।व्याकरण S → if S else S | if S | a, LL(1) नहीं है। उसकी LL(1) सारणी के कितने कोष्ठों में संघर्ष है?
उत्तर देखें
उत्तर: A — एक
एक। FIRST(S) = { if, a }, और दोनों if-उत्पादनifसे आरंभ होते हैं, अतः दोनों एकमात्र कोष्ठ (S, if) में आ जाते हैं। तीसरा उत्पादन, S → a, अकेला (S, a) में जाता है। एक संघर्षित कोष्ठ, और व्याकरण को अयोग्य ठहराने हेतु वह पर्याप्त है। उस गणना से पृथक् करने योग्य गहन दोष है: व्याकरण अस्पष्ट है —if a else aके दो पार्स वृक्ष हैं — और अस्पष्टता LR(1) को भी बाहर करती है, अतः कितना भी लुकअहेड सहायता नहीं करता। अतः संकलक उसे व्याकरण के बाहर के नियम से सुलझाते हैं, प्रत्येकelseको निकटतम अ-मिलानifसे बाँधकर।LR कुल के विषय में निम्नलिखित में कौन सत्य हैं? (एक से अधिक सही हो सकते हैं।)
उत्तर देखें
उत्तर: A — LALR(1) व SLR(1) पार्सरों की अवस्थाओं की संख्या समान होती है; B — प्रत्येक LL(1) व्याकरण LR(1) है; D — प्रामाणिक LR(1) को LALR(1) से अधिक अवस्थाएँ चाहिए हो सकती हैं
A, B व D। SLR(1) व LALR(1) दोनों LR(0) अवस्था-समुच्चय पर बने हैं और केवल इसमें भिन्न हैं कि न्यूनन-प्रविष्टियाँ कैसे निकाली जाएँ, अतः उनकी अवस्था-गणनाएँ सहमत हैं (A) — और प्रामाणिक LR(1), जो कोर विलीन करने के बजाय लुकअहेड पृथक् रखता है, के पास कहीं अधिक हो सकती हैं (D)। B अंतर्वेशन LL(1) ⊂ LR(1) है, और वह कठोर है, अतः विलोम विफल है। C असत्य है: अस्पष्टता का अर्थ एक माला हेतु दो पार्स वृक्ष है, और निर्धारणवादी पार्सर के पास चुनने का आधार नहीं, अतः कोई अस्पष्ट व्याकरण किसी भी प्रकार का LR नहीं। इसीलिए अस्पष्ट व्याकरण कोई सारणी बनने से पूर्व अयोग्य हो जाता है, और इसीलिए डैंगलिंग else को अधिक शक्तिशाली पार्सर के बजाय नीति से सँभाला जाता है।शाब्दिक विश्लेषक से यह जाँचा नहीं जा सकता कि प्रोग्राम में कोष्ठक संतुलित हैं, क्योंकि:
उत्तर देखें
उत्तर: B — संतुलित कोष्ठक नियमित भाषा नहीं हैं
लेक्सर परिमित स्वचालित्र है, अतः वह ठीक नियमित भाषाएँ पहचानता है — और संतुलित कोष्ठक मानक अ-नियमित भाषा है, जिसे अपरिबद्ध गणना चाहिए जो कोई नियत अवस्था-संख्या नहीं दे सकती। वह समस्या-वर्ग के विषय में कथन है, पाइपलाइन में लेक्सर के स्थान (विकल्प A) या उसकी आँकड़ा-संरचनाओं (विकल्प C) के विषय में नहीं। कोष्ठक निश्चित रूप से टोकन हैं (विकल्प D); लेक्सर प्रसन्नता से प्रत्येक की सूचना देता है और सरलतः यह नहीं कह सकता कि वे युग्मित होते हैं या नहीं। उन्हें मिलाना पार्सर का काम है, और वह संदर्भ-मुक्त समस्या है यही कारण है कि पार्सर स्टैक प्रयोग करते हैं।LL(1) पार्सिंग सारणी भरने में किसी अ-टर्मिनल A का FOLLOW समुच्चय देखा जाता है:
उत्तर देखें
उत्तर: B — केवल A के उन उत्पादनों हेतु जिनका दक्षिण पक्ष ε व्युत्पन्न कर सके
प्रत्येक उत्पादन A → α, FIRST(α) के प्रत्येक टर्मिनल के अंतर्गत भरा जाता है; FOLLOW(A) केवल तब प्रयुक्त होता है जब α, ε व्युत्पन्न कर सके, क्योंकि वही एक स्थिति है जहाँ पार्सर को A को कुछ नहीं में विस्तारित करने और आगे जो आए उसे A के बुलाने वाले से सँभलवाने का निर्णय करना होता है। व्यावहारिक लाभ वास्तविक है: ε-उत्पादनों से रहित व्याकरण में FOLLOW सारणी को कभी स्पर्श नहीं करता, अतः उसकी गणना व्यर्थ काम है — और ऊपर के व्यंजक व्याकरण में केवल X व Y के FIRST समुच्चयों में ε है, और ठीक वहीं उनके FOLLOW समुच्चय अपना मूल्य चुकाते हैं। आरंभ से पूर्व ε-उत्पादन जाँचना बताता है कि आपको कितनी गणना चाहिए।yacc या bison जैसा उपकरण कौन-सा पार्सर उत्पन्न करता है?
उत्तर देखें
उत्तर: C — LALR(1)
LALR(1), और कारण वह सौदा है जो वह करता है: वह SLR(1) से कठोरतः अधिक शक्तिशाली है जबकि LR(0) जितनी ही अवस्थाएँ रखता है, क्योंकि वह कोर साझा करती LR(1) अवस्थाएँ विलीन करता है। प्रामाणिक LR(1) उससे भी अधिक शक्तिशाली है पर उसे कहीं अधिक अवस्थाएँ चाहिए हो सकती हैं, जिसने इन उपकरणों के लिखे जाने के समय उसे अव्यावहारिक बनाया और वह अब भी प्रायः सारणी-आकार के योग्य नहीं। विलयन की एक लागत जानने योग्य है: कोर विलीन करना ऐसे न्यूनन–न्यूनन संघर्ष ला सकता है जो प्रामाणिक LR(1) में न होते, अतः कोई व्याकरण LR(1) हो सकता है और LALR(1) नहीं — और ठीक इसीलिए अनुक्रम तुल्य लेबलों के समुच्चय के बजाय कठोर अंतर्वेशनों की श्रृंखला है।