2010-04-16 9 views
6

छोड़ दिया निकालने से निम्नलिखित व्याकरण प्रत्यावर्तनप्रत्यावर्तन

E= E+T|T 
T= T*F|F 
F= a|b|c 

छोड़ दिया है यह कैसे दूर करने के लिए? क्या इसके लिए कोई सामान्य प्रक्रिया है?

उत्तर

13

हां, एक सामान्य प्रक्रिया है, उदाहरण देखें। wikipedia

E = TE' 
E'= (e) | +TE' 
T = FT' 
T'= (e) | *FT' 
F = a | b | c 

यह उल्लेखनीय है कि इस + और * की संबद्धता बाएं से दाएं बदल देता है। यही है, जहां a + b + c से पहले (a + b) + c के रूप में पार्स किया गया था, अब इसे a + (b + c) के रूप में पार्स किया गया है।

यह अतिरिक्त और गुणा के लिए कोई समस्या नहीं है, लेकिन उदाहरण के लिए, यह घटाव और विभाजन के लिए एक समस्या होगी।

विकिपीडिया लेख में बाएं-रिकर्सन हटाने की प्रक्रिया और इसकी जटिलताओं पर अधिक जानकारी है।

+4

तो उस समस्या को कैसे हल करें?(सहयोगीता को उलटाने के) मैं बाएं रिकर्सन को हटाने के इस एल्गोरिदम के कई प्रतियां (अप्रत्यक्ष प्रत्यक्ष) देखता हूं, और वे हमेशा सहयोगीता को तोड़ने के बारे में चेतावनी लिखते हैं, लेकिन मैंने इस तरह के किसी भी लेख में उस समस्या का अभी तक कोई समाधान नहीं देखा है । क्या कोई समाधान है? या केवल समस्या? और दूसरा सवाल यह है: यह क्यों काम करता है? – SasQ

+2

मैं पूछता हूं क्योंकि मैंने उस एल्गोरिदम के किसी भी विश्वसनीय प्रमाण को नहीं देखा है। वहां "सबूत" थे जो दिखाते हैं कि रूपांतरित व्याकरण से प्राप्त भाषा अभी भी वही है, लेकिन मेरे लिए ऐसे सबूतों में एक त्रुटि है: एक धारणा है कि यदि वाक्यविन्यास एक ही आउटपुट उत्पन्न करता है, तो यह वही है। क्योंकि यह नहीं है! यह एक पूरी तरह से अलग भाषा है, क्योंकि इसमें एक अलग पार्स पेड़ है, इसलिए यह मशीन द्वारा अलग-अलग "समझा" है। "सार सिंटेक्स ट्री" को "सार (सिंटेक्स ट्री)" और "(सार सिंटेक्स) वृक्ष" के रूप में व्याख्या करने के बीच एक ही अंतर - दो अलग-अलग चीजें। – SasQ

+1

वही बाएं-रिकर्सिव और दाएं-पुनरावर्ती वाक्यविन्यास के लिए जाता है। एक बाएं-सहयोगी है, दूसरा सही-सहयोगी है। और मुझे सही-सहयोगीता के साथ बाएं-रिकर्सिव वाक्यविन्यास रखने के किसी भी तरीके के बारे में पता नहीं है। क्या आप जानते है? – SasQ

2

जैसा कि अन्य ने बताया है, सही रिकर्सन के साथ बाएं रिकर्सन को बदलने के लिए एक सामान्य प्रक्रिया है। अन्य उत्तरों ने दिखाया है कि दी गई व्याकरण में बाएं रिकर्सन को हटाने के लिए उस सामान्य प्रक्रिया का उपयोग कैसे करें।

यहां एक ऐसा समाधान है जो दिए गए व्याकरण को उस व्याकरण के लिए विशिष्ट तरीके से पुनर्गठन करता है।

E= T+E|T 
T= F*T|F 
F= a|b|c 
+0

तो आप वास्तव में कह रहे हैं कि बाएं-रिकर्सन में आपका प्रस्तावित व्याकरण मुक्त है? मैं सोच रहा हूं क्योंकि मैं औपचारिक भाषाओं में एक कोर्स में आया था और इसे बाएं-रिकर्सिव कहा गया था? –

3

सामान्य प्रक्रिया Wikipedia पर मिली है, उदाहरण के लिए। मैं E = E+T|T के लिए प्रदर्शित करूंगा:

E बाएं-रिकर्सिव गैर-टर्मिनल है। +T गैर-शून्य अनुक्रम (अल्फा) है। T अनुक्रम है जो ई (बीटा) से शुरू नहीं होता है।

हम "आराम" के लिए एक नया nonterminal बनाते हैं, यानी। गैर-शून्य अनुक्रम। यह रिकर्सन को संभालता है।

E' = epsilon|+TE'

और हम प्रत्यावर्तन को संभालने के लिए नई nonterminal उपयोग करने के लिए मूल नियम को बदला।

E = TE'

1

उत्पादन

E = E+T 
    | T 
T = T*F 
    | F 
F = a|b|c 

E= T ('+' T)* 
T= F ('*' F)* 
F= a|b|c 

को जाता है एक ही प्रसंस्करण जहां मुट्ठी ई असंबद्ध A(E,T) के साथ कार्रवाई की है बनाए रखने के लिए। नया संस्करण उपयोग करता है:

ret = T1; 
while(set.more()) ret = A(ret, set.pop_front().T); 
संबंधित मुद्दे