क्या पार्सर कॉम्बिनेटर के साथ अलग-अलग पार्सिंग और लेक्सिंग अच्छा अभ्यास है?


18

जब मैंने पार्सर कॉम्बिनेटरों का उपयोग करना शुरू किया तो मेरी पहली प्रतिक्रिया पार्सिंग और लेक्सिंग के बीच एक कृत्रिम अंतर की तरह महसूस होने वाली मुक्ति से थी। अचानक सब कुछ बस पार्स कर रहा था!

हालाँकि, मैं हाल ही में इस पोस्ट पर आया था codereview.stackexchange किसी को इस अंतर को बहाल करते हुए दिखाता है। पहले तो मुझे लगा कि यह उनके बारे में बहुत मूर्खतापूर्ण है, लेकिन फिर इस व्यवहार का समर्थन करने के लिए पारसेक में मौजूद तथ्य मुझे खुद से सवाल करने के लिए प्रेरित करते हैं।

पार्सर कॉम्बीनेटरों में पहले से ही लक्सड स्ट्रीम पर पार्स करने के क्या फायदे / नुकसान हैं?


कृपया कोई व्यक्ति [पार्सर-कॉम्बिनेटर] टैग जोड़ सकता है?
एली फ्रे

जवाबों:


15

पार्सिंग के तहत हम संदर्भ मुक्त भाषाओं के सबसे अधिक बार विश्लेषण को समझते हैं। एक संदर्भ मुक्त भाषा एक नियमित की तुलना में अधिक शक्तिशाली है, इसलिए पार्सर लेक्सिकल विश्लेषक के काम को बहुत दूर कर सकता है।

लेकिन, यह एक) काफी अप्राकृतिक ख) अक्सर अक्षम है।

एक के लिए), अगर मैं के बारे में सोचने के लिए कैसे उदाहरण के लिए एक ifअभिव्यक्ति दिखता है, मुझे लगता है कि यदि expr तो expr और के expr और नहीं 'मैं' 'म', हो सकता है कुछ रिक्त स्थान है, तो किसी भी चरित्र एक अभिव्यक्ति के साथ शुरू कर सकते हैं, आदि आपको मिल विचार।

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

आखिरकार, अगर आपको लगता है कि एक पार्सर को निम्न स्तर के सामान के साथ व्यस्त होना चाहिए, तो पात्रों को क्यों संसाधित करें? कोई इसे बिट्स के स्तर पर भी लिख सकता है! आप देखिए, ऐसे पार्सर जो बिट लेवल पर काम करते हैं, लगभग समझ से बाहर होंगे। यह पात्रों और टोकन के साथ समान है।

बस मेरे 2 सेंट।


3
बस सटीक के लिए: एक पार्सर हमेशा एक शाब्दिक विश्लेषक का काम कर सकता है ।
जियोर्जियो

इसके अलावा, दक्षता के बारे में: मुझे यकीन नहीं है कि एक पार्सर कम कुशल (धीमा) होगा। मैं उम्मीद करूंगा कि परिणामी व्याकरण में एक उप-व्याकरण होगा जो एक नियमित भाषा का वर्णन करता है, और उस उप-व्याकरण के लिए कोड एक समान लेक्सिकल विश्लेषक के रूप में तेज़ होगा। IMO वास्तविक बिंदु है (ए): कितना सरल, सहज है, एक सरल, अधिक सार पार्सर के साथ काम करना।
जियोर्जियो

@ जियोर्जियो - अपनी पहली टिप्पणी के बारे में: आप सही हैं। यहां मेरे पास जो मामले थे, वे ऐसे मामले हैं जहां लेक्सर व्यावहारिक रूप से कुछ काम करता है जो व्याकरण को आसान बनाता है, ताकि कोई व्यक्ति एलएएलआर (2) के बजाय एलएएलआर (1) का उपयोग कर सके।
इंगो

2
मैंने आगे के प्रयोग और प्रतिबिंब के बाद आपके उत्तर की अपनी स्वीकार्यता को हटा दिया है। यह कि आप दो Antlr एट के यॉन दुनिया से आते हैं। पार्सर कॉम्बिनेटरों की प्रथम श्रेणी की प्रकृति को ध्यान में रखते हुए, मैं अक्सर अपने टोकन पार्सर्स के लिए एक रैपर पार्सर को परिभाषित करता हूं जो प्रत्येक टोकन को पार्सर्स की पार्सिंग परत में एक ही नाम के रूप में छोड़ देता है। उदाहरण के लिए अगर आपका उदाहरण दिखेगा if = string "if" >> expr >> string "then" >> expr >> string "else" >> expr
एली फ्री

1
प्रदर्शन अभी भी एक खुला सवाल है, मैं कुछ बेंचमार्क करूंगा।
एली फ्री

8

हर कोई सुझाव देता है कि लेक्सिंग और पार्सिंग को अलग करना एक "अच्छा अभ्यास" है - मुझे असहमत होना पड़ता है - कई मामलों में एक ही पास में लेक्सिंग और पार्सिंग करने से बहुत अधिक शक्ति मिलती है, और प्रदर्शन निहितार्थ उतने बुरे नहीं हैं जितना कि वे प्रस्तुत किए जाते हैं। अन्य जवाब (देखें पैकरैट )।

यह दृष्टिकोण तब चमकता है जब किसी एकल इनपुट स्ट्रीम में कई विभिन्न भाषाओं को मिलाना होता है। यह न केवल कतहुद्दीन और एक जैसे अजीब मेटाप्रोग्रामिंग-उन्मुख भाषाओं द्वारा आवश्यक है , बल्कि बहुत अधिक मुख्यधारा के अनुप्रयोगों के लिए भी, जैसे साक्षर प्रोग्रामिंग (लेटेक्स और, सी + + को मिलाते हुए), टिप्पणियों में HTML का उपयोग करके, जावास्क्रिप्ट को HTML में भरकर, और जल्द ही।


मेरे जवाब में मैंने सुझाव दिया कि यह "कुछ संदर्भों में अच्छा अभ्यास" है और यह नहीं कि यह "सभी संदर्भों में बेहतर अभ्यास" है।
जियोर्जियो

5

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

दूसरी ओर, एक संदर्भ-मुक्त भाषा के कुछ तत्वों को एक नियमित भाषा (और इसलिए एक शाब्दिक विश्लेषक) के माध्यम से कैप्चर करना उपयोगी हो सकता है क्योंकि

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

तो लेक्सिकल विश्लेषण से पार्सिंग को अलग करने का यह फायदा है कि आप एक सरल संदर्भ-मुक्त व्याकरण के साथ काम कर सकते हैं और लेक्सिकल एनालाइज़र (डिवाइड एट एम्पा) में कुछ बुनियादी (अक्सर रूटीन) कार्यों को इनकैप्सुलेट कर सकते हैं।

संपादित करें

मैं पार्सर कॉम्बिनेटरों से परिचित नहीं हूं इसलिए मुझे यकीन नहीं है कि उपरोक्त विचार उस संदर्भ में कैसे लागू होते हैं। मेरी धारणा यह है कि भले ही पार्सर कॉम्बिनेटरों के साथ केवल एक ही संदर्भ-मुक्त व्याकरण हो, दो स्तरों (लेक्सिकल विश्लेषण / पार्सिंग) के बीच अंतर इस व्याकरण को अधिक मॉड्यूलर बनाने में मदद कर सकता है। जैसा कि कहा गया है, निचली लेक्सिकल-विश्लेषण परत में पहचानकर्ताओं, शाब्दिक और इसी तरह के मूल पुन: प्रयोज्य पार्सर हो सकते हैं।


2
लेक्समेस प्राकृतिक रूप से नहीं बल्कि नियमित रूप से व्याकरण में आता है, लेकिन सम्मेलन के बाद से, सभी लेक्सर्स नियमित अभिव्यक्ति इंजनों पर बनाए जाते हैं। यह उन भाषाओं की अभिव्यंजक शक्ति को सीमित कर रहा है जिन्हें आप डिज़ाइन कर सकते हैं।
SK- तर्क

1
क्या आप ऐसी भाषा का उदाहरण दे सकते हैं, जिसके लिए लेक्सम को परिभाषित करना उचित होगा जिसे एक नियमित भाषा के रूप में वर्णित नहीं किया जा सकता है?
जियोर्जियो

1
उदाहरण के लिए, मेरे द्वारा निर्मित डोमेन विशिष्ट भाषाओं के एक जोड़े में, पहचानकर्ता TeX अभिव्यक्तियां हो सकती \alpha'_1 (K_0, \vec{T})थीं, जिसने कोड को सुंदर-छपाई करना आसान बना दिया, उदाहरण के लिए, जैसे कि एक अभिव्यक्ति , जहां \ Alpha'_1, K_0 और \ vec {T}। पहचानकर्ता हैं।
SK- तर्क

1
एक संदर्भ-मुक्त व्याकरण को देखते हुए आप हमेशा एक गैर-टर्मिनल एन ले सकते हैं और उन शब्दों का इलाज कर सकते हैं जो उन इकाइयों के रूप में प्राप्त हो सकते हैं जो अपने आप में एक उपयोगी अर्थ रखते हैं (जैसे एक अभिव्यक्ति, एक शब्द, एक संख्या, एक बयान)। यह इस बात पर ध्यान दिए बिना किया जा सकता है कि आप उस इकाई (पार्सर, पार्सर + लेक्सर, आदि) की परवाह किए बिना कैसे। IMO एक पार्सर + लेक्सर की पसंद एक तकनीकी एक है (कैसे पार्सिंग को लागू करने के लिए) सिमेंटिक एक (स्रोत कोड के ब्लॉक का अर्थ क्या है जिसे आप पार्स करते हैं)। हो सकता है कि मैं कुछ अनदेखी कर रहा हूं, लेकिन दो पहलू मुझे रूढ़िवादी लग रहे हैं।
जियोर्जियो

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

3

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

लेक्स के लिए एक पार्सिंग एल्गोरिथ्म का उपयोग करके आप बेकार हो रहे हैं।


यदि आप लेक्सिकल विश्लेषण करने के लिए एक पार्सर का उपयोग करते हैं, तो पीडीए कभी भी स्टैक का उपयोग नहीं करेगा, यह मूल रूप से डीएफए के रूप में काम करेगा: बस इनपुट का उपभोग करना और राज्यों के बीच कूदना। मुझे 100% यकीन नहीं है, लेकिन मुझे लगता है कि अनुकूलन तकनीकों (राज्यों की संख्या को कम करते हुए) जिन्हें डीएफए पर लागू किया जा सकता है, उन्हें पीडीए पर भी लागू किया जा सकता है। लेकिन हाँ: अधिक शक्तिशाली उपकरण का उपयोग किए बिना इस तरह से लेक्सिकल एनालाइज़र लिखना आसान है, और फिर इसके ऊपर एक सरल पार्सर लिखना है।
जियोर्जियो

इसके अलावा, यह पूरी चीज़ को अधिक लचीला और मुख्य बना देता है। उदाहरण के लिए, मान लें कि हमारे पास लेआउट नियम के बिना हास्केल भाषा के लिए एक पार्सर है (यानी, अर्धविराम और ब्रेसिज़ के साथ)। यदि हमारे पास एक अलग लेसर है, तो हम अब केवल टोकन के ऊपर एक और पास करके, लेआउट और अर्धविराम जोड़कर लेआउट नियमों को जोड़ सकते हैं। या, एक आसान उदाहरण के लिए: मान लीजिए कि हमने केवल पहचानकर्ताओं में ASCII वर्णों का समर्थन करने वाली भाषा के साथ शुरुआत की और अब हम पहचानकर्ताओं में यूनिकोड अक्षरों का समर्थन करना चाहते हैं।
इंगो

1
@Ingo, और आपको इसे अलग लेक्सर में करने की आवश्यकता क्यों होगी? बस उन टर्मिनलों को बाहर कारक।
SK-लॉजिक

1
@ एसके-तर्क: मुझे यकीन नहीं है कि मैं आपके प्रश्न को समझता हूं। क्यों एक अलग लेक्सर एक अच्छा विकल्प हो सकता है जिसे मैंने अपने पोस्ट में समझाने की कोशिश की है।
इंगो

जियोर्जियो, नहीं। स्टैक सामान्य LALR स्टाइल पार्सर का एक महत्वपूर्ण घटक है। एक पार्सर के साथ लेक्सिंग करना स्मृति का एक छिपी हुई बर्बादी है (दोनों स्थिर भंडारण और गतिशील रूप से आवंटित) और बहुत धीमी होगी। Lexer / Parser मॉडल कुशल है - इसका उपयोग करें :)
riwalk

1

अलग-अलग पार्स / लेक्स के मुख्य लाभ में से एक मध्यवर्ती प्रतिनिधित्व है - टोकन स्ट्रीम। इसे विभिन्न तरीकों से संसाधित किया जा सकता है जो अन्यथा संयुक्त लेक्स / पार्स के साथ संभव नहीं होगा।

उस ने कहा, मैंने पाया है कि अच्छा 'ol पुनरावर्ती सभ्य कुछ पार्सर जनरेटर सीखने के साथ काम करने के लिए कम जटिल और आसान हो सकता है, और यह पता लगाने के लिए कि पार्सर जनरेटर के नियमों के भीतर ग्रामर की कमजोरी को कैसे व्यक्त किया जाए।


क्या आप उन व्याकरणों के बारे में अधिक बता सकते हैं जो पहले से तय समय पर किए गए पूर्वनिर्मित स्ट्रीम पर अधिक आसानी से व्यक्त किए जाते हैं? मेरे पास केवल खिलौना भाषाओं को लागू करने का अनुभव है और कुछ डेटा प्रारूप हैं, इसलिए शायद मैंने कुछ याद किया है। क्या आपने अपने हाथ से लुढ़के आरडी पार्सर / लेक्स कोम्बोस और बीएनएफ फीड (मैं मान रहा हूं) जनरेटर के बीच किसी भी प्रदर्शन विशेषताओं पर ध्यान दिया है?
एली फ्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.