LR पार्सर अस्पष्ट व्याकरण के नियमों को संभाल नहीं सकते हैं, डिजाइन द्वारा। (1970 के दशक में जब विचारों पर काम किया जा रहा था तो सिद्धांत को आसान बना दिया गया था)।
C और C ++ दोनों निम्नलिखित कथन की अनुमति देते हैं:
x * y ;
इसके दो अलग-अलग पर्स हैं:
- यह x की तरह सूचक के रूप में y की घोषणा हो सकती है
- यह एक्स और वाई की एक बहुतायत हो सकती है, उत्तर को दूर फेंक सकती है।
अब, आप सोच सकते हैं कि बाद वाला मूर्ख है और इसे अनदेखा किया जाना चाहिए। अधिकांश आपसे सहमत होंगे; हालाँकि, ऐसे मामले हैं जहाँ इसका साइड इफेक्ट हो सकता है (उदाहरण के लिए, यदि बहुतायत से अधिक भार हो तो)। लेकिन वह बात नहीं है। मुद्दा यह है कि दो अलग-अलग पर्स हैं, और इसलिए एक प्रोग्राम का मतलब अलग-अलग चीजें हो सकती हैं जो इस बात पर निर्भर करता है कि इसे कैसे पार्स किया जाना चाहिए था।
संकलक को उपयुक्त परिस्थितियों में उपयुक्त को स्वीकार करना चाहिए, और किसी भी अन्य जानकारी (जैसे, एक्स के प्रकार का ज्ञान) की अनुपस्थिति में दोनों को इकट्ठा करना होगा ताकि बाद में निर्णय लिया जा सके कि क्या करना है। इस प्रकार एक व्याकरण को इसकी अनुमति देनी चाहिए। और इससे व्याकरण अस्पष्ट हो जाता है।
इस प्रकार शुद्ध एलआर पार्सिंग इसे संभाल नहीं सकता है। न ही कई अन्य व्यापक रूप से उपलब्ध पार्सर जनरेटर, जैसे कि एंट्र, जावासीसी, वाईएसीसी, या पारंपरिक बाइसन, या यहां तक कि पीईजी-शैली के पार्सर्स, का उपयोग "शुद्ध" तरीके से किया जा सकता है।
बहुत अधिक जटिल मामले हैं (पार्सिंग टेम्प्लेट सिंटैक्स को मनमाने ढंग से देखने की आवश्यकता होती है, जबकि एलएएलआर (के) अधिकांश k टोकन पर आगे देख सकते हैं), लेकिन केवल शुद्ध एलआर (या अन्य) पार्सिंग को शूट करने के लिए केवल एक काउंटरएक्सप्लिमेंट लेता है ।
अधिकांश वास्तविक C / C ++ पार्सर्स एक अतिरिक्त हैक के साथ कुछ प्रकार के निर्धारक पार्सर का उपयोग करके इस उदाहरण को संभालते हैं: वे प्रतीक तालिका संग्रह के साथ पार्सिंग को परस्पर जोड़ते हैं ... ताकि जब तक "x" का सामना न हो जाए, तो parser जानता है कि क्या x एक प्रकार है या नहीं, और इस प्रकार दो संभावित पार्स के बीच चयन कर सकते हैं। लेकिन एक पार्सर जो ऐसा नहीं करता है वह संदर्भ मुक्त है, और एलआर पार्सर (शुद्ध वाले, आदि) संदर्भ में (सर्वोत्तम) संदर्भ मुक्त हैं।
एक, इस नियम को करने के लिए एलआर पार्सरों में प्रति-नियम कमी-समय अर्थ संबंधी जांच जोड़ सकता है। (यह कोड अक्सर सरल नहीं होता है)। अन्य पार्सर प्रकारों में से अधिकांश के पास पार्सिंग में विभिन्न बिंदुओं पर शब्दार्थ जांच जोड़ने के लिए कुछ साधन हैं, जिनका उपयोग यह करने के लिए किया जा सकता है।
और यदि आप पर्याप्त धोखा देते हैं, तो आप LR पार्सर को C और C ++ के लिए काम कर सकते हैं। जीसीसी के लोगों ने थोड़ी देर के लिए किया, लेकिन इसे हाथ से कोडित पार्सिंग के लिए छोड़ दिया, मुझे लगता है क्योंकि वे बेहतर त्रुटि निदान चाहते थे।
हालांकि, एक और दृष्टिकोण है, जो अच्छा और साफ है और सी और सी ++ को किसी भी प्रतीक तालिका हैकरी के बिना ठीक करता है: जीएलआर पार्सर्स । ये पूर्ण संदर्भ मुक्त पार्सर्स हैं (प्रभावी रूप से अनंत लुकहेड हैं)। जीएलआर पार्सर केवल एक "ट्री" (वास्तव में एक निर्देशित चक्रीय ग्राफ जो ज्यादातर पेड़ की तरह है) का निर्माण करते हुए दोनों पार्स को स्वीकार करते हैं, जो अस्पष्ट पार्स का प्रतिनिधित्व करता है। पोस्ट-पार्सिंग पास अस्पष्टताओं को हल कर सकता है।
हम इस तकनीक का उपयोग अपने डीएमएस सॉफ्टवेयर रेन्गिनियरिंग टूकिट के लिए C और C ++ फ्रंट एंड में करते हैं (जून 2017 तक ये MS और GNU बोलियों में पूर्ण C ++ 17 को हैंडल करते हैं)। स्रोत कोड के पूर्ण विवरण के साथ एएसटी का निर्माण करने वाले सटीक, सटीक पार्स के साथ, बड़े सी और सी ++ सिस्टम की लाखों लाइनों को संसाधित करने के लिए उनका उपयोग किया गया है। ( C ++ के सबसे डरावने पार्स के लिए एएसटी देखें । )