ऑपरेटर-प्राथमिकता पार्सर

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

एडस्गर डाईक्स्ट्रा के शंटिंग यार्ड एल्गोरिथ्म का उपयोग सामान्यतः ऑपरेटर प्रीसीडेंस पार्सर को लागू करने के लिए किया जाता है।

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

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

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

प्रिसीडेंस क्लाइमिंग विधि
प्रिसीडेंस क्लाइमिंग विधि अभिव्यक्तियों को पार्स करने के लिए एक कॉम्पैक्ट, सक्षम और लचीला एल्गोरिथ्म है जिसे पहली बार मार्टिन रिचर्ड्स और कॉलिन व्हिटबी-स्ट्रेवेन्स द्वारा वर्णित किया गया था।

ईबीएनएफ प्रारूप में एक इन्फ़िक्स-नोटेशन अभिव्यक्ति व्याकरण सामान्यतः इस तरह दिखेगा

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

एल्गोरिथ्म दिज्क्स्ट्रा शंटिंग यार्ड एल्गोरिथ्म की तरह शुद्ध ऑपरेटर प्रीसीडेंस पार्सर नहीं है। यह मानता है कि प्राथमिक नॉनटर्मिनल को एक अलग सबरूटीन में पार्स किया जाता है, जैसे कि पुनरावर्ती डिसेंट पार्सर में किया जाता है।

स्यूडोकोड
एल्गोरिथम के लिए छद्मकोड इस प्रकार है। पार्सर फ़ंक्शन पार्सर प्रिसीडेंस पर प्रारंभ होता है। प्रीसीडेंस स्तर 0 से अधिक या उसके बराबर हैं।

पार्स   _expression return पार्स   _expression_1(पार्स    _primary, 0)

पार्स   _expression_1(lhs, min_precedence                                                                   lookahead :=   peek next token           while lookahead is a binary operator whose precedence is >= min_precedence         op := lookahead         advance to next token         rhs := पार्स    _primary          lookahead := peek next token         while lookahead is a binary operator whose precedence is greater                  than op 's, or a right-associative operator                  whose precedence is equal to op's             rhs := पार्स    _expression_1 (rhs, precedence of op + (1 if lookahead precedence is greater, else 0))             lookahead := peek next token         lhs := the result of applying op with operands lhs and rhs

return lhs ध्यान दें कि इस तरह के उत्पादन नियम के स्थिति में जहां ऑपरेटर केवल एक बार ही उपस्थित हो सकता है:

एल्गोरिथ्म को केवल उन बाइनरी ऑपरेटरों को स्वीकार करने के लिए संशोधित किया जाना चाहिए जिनकी प्रिसीडेंस >मीन प्रिसीडेंस है।

एल्गोरिथ्म का उदाहरण निष्पादन
अभिव्यक्ति 2 + 3 * 4 + 5 == 19 पर एक उदाहरण निष्पादन इस प्रकार है। हम समानता वाले एक्सप्रेशन को 0, योगात्मक एक्सप्रेशन को 1, गुणात्मक भावों को 2 प्रिसीडेंस देते हैं।

पार्स_एक्सप्रेशन_1 (lhs = 2,मीन_प्रिसीडेंस = 0)
 * यदि लुकआहेड टोकन "+" है और इसकी प्रिसीडेंस 1 है, तो बाहरी वाइल लूप को प्रवेश किया जाएगा।
 * ऑप + (प्रिसीडेंस1) है और इनपुट उन्नत है
 * आरएचएस 3 है
 * यदि लुकआहेड टोकन "*" है और इसकी प्रिसीडेंस 2 है, तो आप आंतरिक वाइल लूप में प्रवेश करेंगे। पार्स_अभिव्यक्ति_1 (एलएचएस = 3, न्यूनतम_प्रासंगिकता = 2)
 * लुकहेड टोकन * है,प्रिसीडेंस   2 के साथ। बाहरी लूप दर्ज किया गया है।
 * ऑप * (प्रिसीडेंस   2) है और इनपुट उन्नत है
 * आरएचएस 4 है
 * अगला टोकन + है,प्रिसीडेंस 1 के साथ आंतरिक लूप दर्ज नहीं किया गया है।
 * एलएचएस को 3*4 = 12 असाइन किया गया है
 * अगला टोकन + है, प्रिसीडेंस 1 के साथ बाहरी लूप बचा है।
 * 12 लौटा दिया गया है।

1 लौटा दिया गया है.
 * लुकहेड टोकन + है,प्रिसीडेंस 1 के साथ आंतरिक जबकि लूप दर्ज नहीं किया गया है।
 * एलएचएस को 2+12 = 14 अभिहस्तांकित किया गया है
 * यदि लुकआहेड टोकन "+" है और इसकी प्राधिकरण 1 है, और प्रभावीता के लिए पार्सिंग लॉजिक के अनुसार, बाहरी वाइल लूप  छोड़ दी गई है।
 * ऑप + (प्रिसीडेंस 1) है और इनपुट उन्नत है
 * आरएचएस 5 है
 * अगला टोकन == है, प्रिसीडेंस 0 के साथ आंतरिक जबकि लूप दर्ज नहीं किया गया है।
 * एलएचएस को 14+5 = 19 सौंपा गया है
 * अगला टोकन == है,प्रिसीडें 0 के साथ। बाहरी जबकि लूप नहीं छोड़ा गया है।
 * ऑप == (प्रिसीडेंस 0) है और इनपुट उन्नत है
 * आरएचएस 19 है
 * अगला टोकन एंड-ऑफ़-लाइन है, जो ऑपरेटर नहीं है। आंतरिक जबकि लूप दर्ज नहीं किया गया है।
 * एलएचएस को 19 == 19 के मूल्यांकन का परिणाम सौंपा गया है, उदाहरण के लिए 1।
 * अगला टोकन एंड-ऑफ़-लाइन है, जो ऑपरेटर नहीं है। बाहरी लूप बचा है।

प्रैट पार्सिंग
प्रैट पार्सिंग के रूप में जाना जाने वाला एक अन्य पूर्वता पार्सर का वर्णन पहली बार वॉन प्रैट ने 1973 के पेपर टॉप डाउन ऑपरेटर पूर्वता में किया था, पुनरावर्ती वंश पार्सर पर आधारित। हालाँकि यहप्रिसीडेंस   चढ़ाई से पहले का है, इसेप्रिसीडेंस    चढ़ाई के सामान्यीकरण के रूप में देखा जा सकता है। प्रैट ने पार्सर को मूल रूप से COLL  प्रोग्रामिंग भाषा को लागू करने के लिए डिज़ाइन किया था, और उनकी देखरेख में मास्टर्स थीसिस में इसका अधिक गहराई से इलाज किया गया था। ट्यूटोरियल और कार्यान्वयन:
 * डगलस क्रॉकफ़ोर्ड ने जेएसलिंट में जावास्क्रिप्ट पार्सर को प्रैट पार्सिंग पर आधारित किया।
 * प्रीसीडेंस क्लाइंबिंग और प्रैट पार्सिंग के पायथन कार्यान्वयन के बीच तुलना: प्रैट पार्सिंग और प्रीसीडेंस क्लाइंबिंग आर द सेम एल्गोरिथम (2016) एंडी चू द्वारा
 * रस्ट (प्रोग्रामिंग भाषा) का उपयोग करने वाला ट्यूटोरियल: सरल लेकिन शक्तिशाली प्रैट पार्सिंग (2020) एलेक्सी क्लाडोव द्वारा
 * पायथन (प्रोग्रामिंग भाषा) का उपयोग करने वाला ट्यूटोरियल: फ्रेड्रिक लुंड द्वारा पायथन में सरल टॉप-डाउन पार्सिंग (2008)
 * जावा (प्रोग्रामिंग भाषा) का उपयोग करने वाला ट्यूटोरियल: made-easy/ प्रैट पार्सर     : एक्सप्रेशन पार्सिंग मेड ईज़ी (2011) क्राफ्टिंग इंटरप्रिटर्स के लेखक बॉब निस्ट्रॉम द्वारा
 * सी शार्प (प्रोग्रामिंग भाषा) में कार्यान्वयन | सी #: Gratt: .NET मानक के लिए एक जेनेरिक वॉन प्रैट का टॉप-डाउन ऑपरेटर प्रीसीडेंस                  पार्सर (बॉब निस्ट्रॉम द्वारा प्रस्तुत जावा कार्यान्वयन से प्रेरित एक  सामान्य प्रोग्रामिंग  संस्करण made -ईज़ी/ प्रैट पार्सर      : एक्सप्रेशन पार्सिंग मेड ईज़ी )

वैकल्पिक तरीके
ऑपरेटर प्रीसीडेंस                  नियम लागू करने के अन्य तरीके भी हैं। एक है मूल अभिव्यक्ति का एक वृक्ष बनाना और फिर उस पर वृक्ष पुनर्लेखन नियम लागू करना।

ऐसे पेड़ों को पारंपरिक रूप से पेड़ों के लिए उपयोग की जाने वाली डेटा संरचनाओं का उपयोग करके लागू करने की आवश्यकता नहीं है। इसके बजाय, टोकन को फ्लैट संरचनाओं में संग्रहीत किया जा सकता है, जैसे कि टेबल, साथ ही एकप्रिसीडेंस   सूची बनाकर जो बताती है कि किस क्रम में किन तत्वों को संसाधित करना है।

पूर्ण कोष्ठक
एक अन्य तरीका यह है कि पहले अभिव्यक्ति को पूरी तरह से कोष्ठक में रखा जाए, प्रत्येक ऑपरेटर के चारों ओर कई कोष्ठक डाले जाएं, ताकि वे एक रैखिक, बाएं से दाएं पार्सर के साथ पार्स करने पर भी सहीप्रिसीडेंस   की ओर ले जाएं। इस एल्गोरिथ्म                  का उपयोग प्रारंभिक फोरट्रान#फोरट्रान कंपाइलर में किया गया था:  फोरट्रान I कंपाइलर प्रत्येक ऑपरेटर को कोष्ठकों के अनुक्रम के साथ विस्तारित करेगा। एल्गोरिथम के सरलीकृत रूप में, यह होगा हालांकि स्पष्ट नहीं है, एल्गोरिथ्म सही था, और, डोनाल्ड नुथ के शब्दों में, "परिणामस्वरूप सूत्र उचित रूप से कोष्ठक में रखा गया है, विश्वास करें या न करें।" 
 * बदलना  और   साथ   और , क्रमश;
 * बदलना  और   साथ   और , क्रमश;
 * जोड़ना  प्रत्येक अभिव्यक्ति की शुरुआत में और मूल अभिव्यक्ति में प्रत्येक बाएँ कोष्ठक के बाद; और
 * जोड़ना  अभिव्यक्ति के अंत में और मूल अभिव्यक्ति में प्रत्येक दाएँ कोष्ठक से पहले।

एक साधारण सी एप्लिकेशन का उदाहरण कोड जो बुनियादी गणित ऑपरेटरों के कोष्ठक को संभालता है (, ,  ,  ,  ,   और  ): उदाहरण के लिए, जब मापदंडों के साथ कमांड लाइन से संकलित और आह्वान किया जाता है a * b + c ^ d / e वह उत्पादन करता है ((((a))*((b)))+(((c)^(d))/((e)))) कंसोल पर आउटपुट के रूप में।

इस रणनीति की एक सीमा यह है कि यूनरी ऑपरेटरों को इंफिक्स ऑपरेटरों की तुलना में अधिकप्रिसीडेंस   मिलनी चाहिए। उपरोक्त कोड में नकारात्मक ऑपरेटर की घातांक की तुलना में अधिकप्रिसीडेंस    है। इस इनपुट के साथ प्रोग्राम चला रहे हैं - ए ^ 2 यह आउटपुट उत्पन्न करता है ((((-a)^(2)))) जो संभवतः वह उद्देश्य नहीं है।

बाहरी संबंध

 * Example C++ code by Keith Clarke for parsing infix expressions using the precedence climbing method
 * Parser for expression with infix notation using precedence lists
 * Parser for expression with infix notation using precedence lists
 * Parser for expression with infix notation using precedence lists