Parser generator भी अच्छी errors generate कर सकते हैं.
(dalinaum.github.io)Go भाषा के डेवलपर Russ Cox द्वारा 2010 में पोस्ट किए गए लेख का अनुवाद.
-
यह मिथक फैला हुआ था कि yacc जैसे parser generator syntax errors को अच्छी तरह generate नहीं कर पाते.
-
लेकिन इस समस्या को Clinton Jeffery ने 2003 में ही हल कर दिया था, और इसे सुलझाने के लिए parser को हाथ से लिखना ज़रूरी नहीं है.
-
यदि (bison) state और input token से मेल खाने वाली सामग्री को table में खोज लिया जाए, तो साधारण syntax error की तुलना में बेहतर error का उपयोग किया जा सकता है.
3 टिप्पणियां
(नीचे Korean Rust Discord सर्वर में लिखी गई बातों को संक्षेप में व्यवस्थित किया गया है.)
इस लेख की सबसे बड़ी समस्या यह है कि क्या Go अभी parser generator का इस्तेमाल करता है। नहीं। मुख्य Go parser अब भी हाथ से लिखा गया है। सटीक कारण तो मुझे नहीं पता, लेकिन यह काफी संभव है कि rsc को यह ठीक लगा हो, पर दूसरे Go डेवलपर्स ने इसे ठीक न माना हो।
Jeffrey का विचार compiler के संदर्भ में peephole optimizer से तुलना की जा सकती है। मशीन कोड निकालने से पहले, वह हाल ही में निकले मशीन कोड निर्देशों की एक तय संख्या को बनाए रखता है (इसीलिए उसे ऐसा नाम मिला है—वह उस window को peep hole की तरह झाँकता है), और जब कोई खास pattern दिखता है तो वहीं पर उस निर्देश को अधिक तेज निर्देश से बदल देता है। peephole optimizer एक सुविधाजनक चीज़ है जिसे अन्य सामान्य optimization pass के साथ-साथ इस्तेमाल किया जा सकता है, लेकिन केवल peephole optimizer के सहारे compiler द्वारा अपेक्षित हर तरह का optimization नहीं किया जा सकता। उसी तरह, हाल के tokens से error उत्पन्न करने वाला approach भी सभी parsing errors को cover नहीं कर सकता। ऊपर से, यह कोई ऐसा स्वतंत्र approach है जिसे parser generator न होने पर भी लागू किया जा सकता है, इसलिए केवल इस approach के मौजूद होने से parser generator की समस्या खत्म हो जाती है, यह दावा करना सही नहीं है।
व्यक्तिगत रूप से मुझे लगता है कि parser generator की अवधारणा बुरी नहीं है, समस्या उस सोच में है जिसे parser generator "थोपता" है। parser लिखते समय, चाहे वह generated हो या हाथ से लिखा गया हो, left recursion और right recursion पर विचार करना पड़ता है, और "natural" grammar को ज्यों का त्यों code में नहीं बदला जा सकता। लेकिन हाथ से लिखते समय तो यह समझौता जान-बूझकर किया जाता है; अगर parser generator इस्तेमाल करने पर भी LL/LR जैसे खास parsing algorithm से बँधे "grammar" के subset के अनुसार ही लिखना पड़े, तो generator के फायदे काफी घट जाते हैं। (GLR जैसे algorithm थोड़ी अधिक गुंजाइश देते हैं, लेकिन उनकी भी सीमाएँ हैं।) आज अधिकांश production-level language implementations parser generator का इस्तेमाल नहीं करतीं, या कभी-कभी PEG जैसे ऐसे parser generator approach का इस्तेमाल करती हैं जो सामान्य generator के फायदों को बिलकुल भी नहीं अपनाता—इसके पीछे कारण हैं।
मैं इस बात से सहमत हूँ कि कोई व्यक्ति parser generator का इस्तेमाल इसलिए न करे क्योंकि वह उसके द्वारा सीमित की गई grammar में बंधना नहीं चाहता, लेकिन यह कहना भी अजीब है कि parser generator उपयोगकर्ता पर कोई खास grammar थोप रहा है.
parser generator इसलिए आए क्योंकि linear-time parsing का फायदा देने वाले LR grammar parsing table बनाना बहुत कठिन है, और इन्हें उसी में मदद के लिए बनाया गया था; nondeterministic context-sensitive grammar को parse करना या ऐसे recursive parser बनाना जिनका parsing कब खत्म होगा यह भी पता न हो, शायद parser generator के शोधकर्ताओं/डेवलपर्स की रुचि का विषय नहीं है.
इसलिए मुझे लगता है कि parser generator कोई ऐसा प्रोग्राम नहीं है जो गैर-सहज LR या LALR grammar पर अंधविश्वास करे और उन्हें थोपे, बल्कि यह linear-time parsing और उसके लिए parsing table निर्माण जैसी बेहद कठिन समस्या को हल करने वाला एक उपयोगी tool है, और यह अपनी भूमिका ठीक से निभा रहा है.
वास्तव में दिखने वाली लगभग सभी भाषाओं का व्याकरण LL(1) होता है, इसलिए LR parser का उपयोग किए बिना भी linear-time parsing संभव है। (इसका मतलब यह नहीं है कि उन भाषाओं के लिए पसंदीदा व्याकरण LL(1) है।) इसलिए यह कहना कि linear-time parsing के लिए LR parser का उपयोग करना पड़ता है, लेकिन parsing table बनाना कठिन होता है इसलिए generator की ज़रूरत पड़ती है, कारण-परिणाम के क्रम को उलट देना है। साथ ही, parsing table बनाने की प्रक्रिया स्वयं मूल रूप से जटिल नहीं है (कठिन तो algorithm का proof है)।