2009-05-26 26 views
6

में एक शिफ्ट-कम संघर्ष को हल करने में समस्या Irony के साथ मैं एक छोटा पार्सर लिखने की कोशिश कर रहा हूं। दुर्भाग्य से मुझे "शिफ्ट-कम संघर्ष" मिलता है। ग्रामर मेरे मजबूत बिंदु नहीं हैं, और मुझे केवल यह एक छोटी सी काम करने की आवश्यकता है। यहाँ कम व्याकरण कि त्रुटि पैदा करता है:मेरे व्याकरण

ExpressionTerm := "asd" 
LogicalExpression := 
    ExpressionTerm | 
    LogicalExpression "AND" LogicalExpression | 
    LogicalExpression "OR" LogicalExpression 

क्या करता है "पाली-कम कर संघर्ष" मतलब और मैं इसे कैसे हल कर सकते हैं? मैं इकट्ठा करता हूं कि इसका मतलब है कि मेरा व्याकरण संदिग्ध है, लेकिन मैं यह देखने के लिए पर्याप्त रूप से अपने तर्क को मोड़ नहीं सकता।

जोड़ा गया: स्पष्ट करने के लिए - "asd" बस एक शाब्दिक स्ट्रिंग "asd" है। इसलिए मैं उम्मीद होती है कि निम्न भाव इस व्याकरण द्वारा पार्स किए जाते हैं:

asd 
asd AND asd 
asd AND asd OR asd 
asd OR asd AND asd OR asd 

जोड़ा गया 2: कहने के लिए, व्याकरण की जड़ LogicalExpression है भूल।

जोड़ा गया 3: आह, मुझे मिल गया!

(asd AND asd) OR asd 
asd AND (asd OR asd) 

लेकिन मैं यह कैसे हल कर सकते हैं: अस्पष्टता क्योंकि

asd AND asd OR asd 

की तरह एक अभिव्यक्ति दो अलग तरीके से व्याख्या की जा सकती है? ठीक है, मैं एक और या OR को दूसरे की तुलना में मजबूत कर सकता हूं (मैंने वैसे भी किया था)। लेकिन अब मैं देखता हूं कि त्रुटि तब भी दिखाई देती है जब केवल एक ऑपरेटर होता है। दूसरे शब्दों में, यह भी एक ही त्रुटि पैदा करता है:

LogicalExpression := "asd" | LogicalExpression "OR" LogicalExpression 

इस मामले में मैं यह चाहता हूँ:

asd OR asd OR asd 

यह करने के लिए पार्स किया जा सकता:

(asd OR asd) OR asd 

गैर क्या है ऐसा करने का अस्पष्ट तरीका?

जोड़ा गया 4: समझ गया!

LogicalExpression1 := LogicalExpression1 "OR" LogicalExpression2 | LogicalExpression2 
LogicalExpression2 := LogicalExpression2 "AND" LogicalExpression3 | LogicalExpression3 
LogicalExpression3 := "NOT" LogicalExpression4 | LogicalExpression4 
LogicalExpression4 := "asd" | "(" LogicalExpression1 ")" 

इस रूप में नहीं-> and- ऑपरेटर पूर्वता> या के साथ सभी बूलियन भाव पार्स करते। "asd" को आपकी शर्तों के लिए अभिव्यक्ति के साथ प्रतिस्थापित किया जा सकता है।

+0

हे, यह सोचने के लिए, मैं इस याद करने के लिए शुरू कर आ ExpressionTerm में प्रतिस्थापित किया जा सकता है और यह भी LogicalExpression व्याकरण के नियमों समतल विश्वविद्यालय में मेरे दिनों से पैटर्न। : डी –

उत्तर

3

आपका व्याकरण संदिग्ध है, अगर आप केवल एक ही लुकहेड का उपयोग करते हैं। उदाहरण के लिए, "asd" क्या है? क्या यह एक अभिव्यक्ति टर्म या लंबी अवधि है। यह बदलाव-संघर्ष को कम करता है। मुझे यहां कम संघर्ष को कम करने का संदेह है।

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

+0

"asd" बस एक शाब्दिक स्ट्रिंग "asd" है। –

+0

मुझे अभी भी समझ में नहीं आता है। और और इस मामले में वही प्राथमिकता होनी चाहिए। –

+0

1 वर्ण लुकहेड के साथ, आप और AND के बारे में भूल सकते हैं। संघर्ष पहले है :) – leppie

1

शिफ्ट-कमी संघर्ष का मतलब है कि आपका व्याकरण संदिग्ध है। आपके रिकर्सिव नियम के साथ एक टोकन "asd" को ExpressionTerm या LogicalExpression के हिस्से के रूप में व्याख्या किया जा सकता है और पार्सर कौन सा निर्णय नहीं ले सकता है। टाई तोड़ने के लिए एक अतिरिक्त नियम की आवश्यकता है।

0

शिफ्ट को कम करने के लिए शिफ्ट को पार्सर्स की बात करते समय अपने दिमाग को पाने के लिए कठिन चीजों में से एक है। संघर्ष को वर्णन करने के लिए सबसे आसान तरीका यह छद्म कोड में है:

if (a) then 
    if (b) then 
    printf('a + b'); 
    else 
    print('this could be a + !b or !a'); 

किसी और बयान पहले या यदि दूसरे करने के लिए बाध्य कर सकता है। संदिग्ध व्याकरण के मामले में, आप आम तौर पर अपेक्षित शिफ्ट की संख्या को इंगित करने के लिए एक मान परिभाषित करते हैं-आपके व्याकरण में चेतावनियों को कम करते हैं।

वैकल्पिक रूप से, आप एलएल (के) या एलएल (*) पार्सर का उपयोग कर सकते हैं। इन प्रकार के पार्सर्स में शिफ्ट/अस्पष्टता कम नहीं होती है। आपके आवेदन के आधार पर वे एलएएलआर (1) पार्सर से आसान या कठिन हो सकते हैं।

0

व्याकरण LL(1) या LALR(1) में अस्पष्ट है के बाद से asd टोकन पारी को हल करने/संघर्ष को कम करने

संबंधित मुद्दे