मैं एक एल्गोरिथ्म का वर्णन करता हूँ जो काम करता है। यह समय चल रहा है बहुत बुरा नहीं होना चाहिए। आप इस के साथ ही बहुत थोड़ा precompute कर सकते हैं।
मैं मान लेंगे कि nonterminals सम्मिलित नहीं होती (यह शायद आसान है कि मामले के लिए अनुकूल करने के लिए हालांकि) और यदि आप नहीं जानते कि एक्स , वाई या की व्युत्पत्ति एक । मैं यह भी मानूंगा कि आपके व्याकरण में ऐसी प्रस्तुतियों को शामिल नहीं किया जाता है जो कभी किसी व्युत्पत्ति में उपयोग नहीं की जाती हैं ( उदाहरण के लिए A → A )।axyaA→A
मुख्य मुद्दा वास्तव में एक को पार्स करना , जैसा कि आप जानना चाहते हैं कि आप किस प्रकार के राज्यों को समाप्त करते हैं, इसलिए आप जानते हैं कि क्या अनुसरण कर सकता है । यह इतना आसान नहीं है क्योंकि आप x नहीं जानते हैं ।aax
हम इयरली के एल्गोरिथ्म के एक अनुकूलन का उपयोग करते हैं । आप पहले उस एल्गोरिथ्म को समझना चाहेंगे। हमारा एल्गोरिथ्म लगभग उसी तरह से काम करता है, सिवाय इसके कि हमारा इनिशियलाइज़ेशन और पूरा होने के चरण अलग-अलग हैं।
प्रारंभ के लिए, हम हर की घटना के लिए एक Earley आइटम के साथ हमारा पहला सेट बीज (में पहले वर्ण एक अपने व्याकरण के किसी भी उत्पादन में)। हमने इस आइटम के बैक पॉइंटर को -1 पर सेट किया है, एक अमान्य मान। यह हमारे संशोधित पूर्ण होने में महत्वपूर्ण है। अनिवार्य रूप से, -1 का मतलब है 'मुझे नहीं पता कि यह उत्पादन कहाँ शुरू किया गया था।'a1a
अब, हम अर्ली एल्गोरिथ्म को हर संभव ऐसे आरंभिक ईयरली आइटम के लिए अलग से करते हैं। हम बस उन सभी को एक ही समय में नहीं कर सकते हैं, क्योंकि पार्स एक दूसरे के साथ हस्तक्षेप कर सकते हैं। मैं आसानी से यहाँ बैकट्रैकिंग की तुलना में तेज़ विधि नहीं देख सकता।
पूर्ण चरण के लिए, हमें केवल -1 बैक पॉइंटर्स को संभालने के लिए एक संशोधन करना होगा। जैसा कि हमने एक उत्पादन पूरा किया है जिसका मूल हमें पता नहीं है, हम मुसीबत में हैं। हालांकि, पेनेलो और डीमेरर द्वारा एल ए एल आर ( 1 ) लुकहेड सेट की गणना करने के लिए इस्तेमाल की जाने वाली विधिLALR(1) हमें बचाती है: हमें यहां जो भी चाहिए वह है एल ए एल आर ( 1 ) लुकहेड सेट। इन लुकहेड सेटों में प्रत्येक आइटम का व्याकरण में एक समान स्थान होता है, जो बदले में पूर्ण उत्पादन के संभावित निरंतरता के अनुरूप होता है।LALR(1)
दुर्भाग्य से, मैं वास्तव में यहाँ एक बार फिर से पीछे हटने के अलावा और कोई विकल्प नहीं देखता। लुकहेड सेट में हर स्थिति के लिए, आप इस स्थिति के साथ पूरा करने का कदम उठाते हैं, और वहां से पार्स जारी रखते हैं। आप इसे हर पारे के लिए अलग से करते हैं। ध्यान दें कि यदि आपका व्याकरण , तो आपका लुक ही विशिष्ट रूप से निर्धारित करेगा कि आपको किस स्थिति में जाना है, इसलिए आपको पीछे नहीं हटना है।LALR(1)
आप परे उपरोक्त एल्गोरिथ्म एक चरित्र के लिए जारी आप देख रहे हैं निर्धारित करते हैं, जहाँ आप इस अतिरिक्त विचार करें, आभासी चरित्र 'किसी भी चरित्र' है, जो तुरंत आप 'का पालन' देता है होना करने के लिए - किसी भी समय इस अंतिम के लिए स्कैनर चरण पाता कुछ सेट, आप इस चरित्र को अपने उत्तर सेट में जोड़ सकते हैं।a
संपादित करें: मुझे लगता है कि मैंने वह विधि ढूंढ ली है, जो बैकड्रैकिंग द्वारा शुरू किए गए ओवरहेड को हटा देती है। हम हर ईयरली आइटम को पहचानकर्ताओं के एक समूह के साथ जोड़ते हैं, जो तार हैं, क्योंकि हमें इन पहचानकर्ताओं के उपसर्गों का उपयोग करने की आवश्यकता होगी। आरंभीकरण पर, हम अर्ली सेट में सभी प्रारंभिक आइटम जोड़ते हैं, और हर सेट के साथ एक विशिष्ट पहचानकर्ता को जोड़ते हैं।
स्कैनर और प्रेडिक्टर चरणों पर, पहचानकर्ताओं को नई वस्तुओं पर ले जाया जाता है। एक ही अर्ली में इयरली आइटम सेट करते हैं कि उनके पहचानकर्ताओं में केवल अलग-अलग हैं और साथ में उनके पहचानकर्ताओं को एक साथ मर्ज करके मिलाया जाता है। ध्यान दें कि हम इन नई वस्तुओं पर स्कैनर और भविष्यवाणियों के चरणों की पहचान पहचानकर्ताओं के साथ कर सकते हैं, बिना प्रत्येक पहचानकर्ता के लिए इस चरण को अलग-अलग करने के लिए।
कंपाइलर पहचानकर्ताओं को अलग से मानता है, और केवल एक आइटम को पूरा करता है यदि पहले के आइटमसेट में संबंधित आइटम में एक पहचानकर्ता होता है जो पहचानकर्ता का एक उपसर्ग होता है। हर संभव पूर्णता के लिए (ताकि हर मद मेंLALR(1)
अनिवार्य रूप से, हम इन पहचानकर्ताओं का उपयोग करते हुए बैकट्रैकिंग करते हैं, ताकि हम स्कैनर और प्रेडिक्टर चरणों में दोहरा काम न करें।