Cthulhu रास्ता पार्स करने के खिलाफ क्या तर्क हैं?


24

मुझे एक उपकरण के लिए एक डोमेन विशिष्ट भाषा को लागू करने का काम सौंपा गया है जो कंपनी के लिए काफी महत्वपूर्ण हो सकता है। भाषा सरल है, लेकिन तुच्छ नहीं है, यह पहले से ही नेस्टेड छोरों, स्ट्रिंग संघनन, आदि की अनुमति देता है और यह व्यावहारिक रूप से सुनिश्चित है कि अन्य निर्माणों को परियोजना अग्रिम के रूप में जोड़ा जाएगा।

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

परिणाम मेरी आँखों के लिए बहुत शानदार है, कोड बहुत संक्षिप्त, सुरुचिपूर्ण और पठनीय / धाराप्रवाह है। मैं मानता हूं कि यह थोड़ा अजीब लग सकता है यदि आपने कभी भी जावा / सी # के अलावा किसी और चीज में प्रोग्राम नहीं किया है, लेकिन फिर यह जावा / सी # में नहीं लिखी गई किसी भी चीज के बारे में सच होगा।

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

मैं सकारात्मक हूं कि चर्चा प्रबंधन के सामने फिर से जा रही है, इसलिए मैं कुछ ठोस तर्क तैयार कर रहा हूं।

ये पहले कुछ कारण हैं जो मेरे दिमाग में एक स्ट्रिंग से बचने के लिए आते हैं। समाधान आधारित समाधान:

  • आपको विशेष मामलों और चीजों को नियंत्रण से बाहर सर्पिल करने के लिए बहुत सारे ifs की आवश्यकता होती है
  • बहुत सारे हार्डकोड एरंड इंडेक्स रखरखाव को दर्दनाक बनाते हैं
  • फंक्शन कॉल जैसी चीजों को विधि तर्क के रूप में संभालना बेहद कठिन है (उदाहरण के लिए। (a, b जोड़ें), c)
  • वाक्यविन्यास त्रुटियों के मामले में सार्थक त्रुटि संदेश प्रदान करने के लिए बहुत मुश्किल है (ऐसा होने की संभावना है)
  • मैं सभी सादगी, स्पष्टता और अनावश्यक स्मार्ट-गुप्त चीजों से बचने के लिए हूं, लेकिन मेरा मानना ​​है कि यह कोडबेस के हर हिस्से को गूंगा करने के लिए एक गलती है, ताकि एक बर्गर फ्लिपर भी इसे समझ सके। यह वही तर्क है जो मैं इंटरफेस का उपयोग नहीं करने, चिंताओं को अलग करने, कोडिंग-पेस्टिंग कोड को अपनाने, आदि के लिए नहीं सुनता हूं। न्यूनतम तकनीकी योग्यता और सीखने की इच्छा के बाद सॉफ्टवेयर प्रोजेक्ट पर काम करना आवश्यक है। (मैं इस तर्क का उपयोग नहीं करूंगा क्योंकि यह संभवतः आक्रामक लगेगा, और युद्ध शुरू करना किसी की मदद करने वाला नहीं है)

Cthulhu रास्ता पार्स करने के खिलाफ आपके पसंदीदा तर्क क्या हैं ? *

* बेशक अगर आप मुझे समझा सकते हैं कि वह सही है तो मैं भी पूरी तरह से खुश रहूंगा


9
मुझे लगता है कि आपके सहकर्मी आपके लिए DSL प्रोजेक्ट करने के लिए स्वेच्छा से काम कर रहे हैं!
ग्रैंडमास्टरबी

23
"मुझे पार्सिंग को फिर से नहीं करना चाहिए, लेकिन बस एक स्टैक का उपयोग करें और स्ट्रिंग करें। जैसा कि हर कोई करता है" - लानत है, उस आदमी को खुशी होनी चाहिए कि अज्ञानता को चोट नहीं पहुंचे ...
माइकल Borgwardt

4
अपने सहकर्मी को इस चर्चा में न लौटने की सलाह दें जब तक कि वह पूरी ड्रैगन बुक न पढ़ ले और एक परीक्षा पास न कर ले। अन्यथा उसे कुछ भी पार्सिंग-संबंधी चर्चा करने का अधिकार नहीं है।
लॉजिक

4
क्षमा करें, पार्सिंग को कौन रोक रहा था?
रवांग

2
मुझे लगता है कि मेरा सिर अगली बार फट जाएगा जब मैं किसी को "शाब्दिक" शब्द का प्रयोग करते हुए देखूंगा।

जवाबों:


33

दो दृष्टिकोणों के बीच महत्वपूर्ण अंतर यह है, कि वह जिसे एकमात्र सही तरीका मानता है, वह जरूरी है और आपका घोषणापत्र है।

  • आपका दृष्टिकोण स्पष्ट रूप से नियमों की घोषणा करता है, अर्थात व्याकरण के नियम (लगभग) आपके कोड में सीधे एन्कोडेड हैं, और पार्सर लाइब्रेरी स्वचालित रूप से कच्चे इनपुट को पार्स आउटपुट में बदल देती है, जबकि राज्य और अन्य चीजों को संभालना मुश्किल है। आपका कोड अमूर्तता की एक एकल परत के भीतर लिखा गया है, जो समस्या डोमेन के साथ मेल खाता है: पार्सिंग। पार्सेक की शुद्धता को मान लेना उचित है, जिसका अर्थ है कि यहां त्रुटि के लिए एकमात्र कमरा है, आपकी व्याकरण की परिभाषा गलत है। लेकिन तब फिर से आपके पास पूरी तरह से योग्य नियम वस्तुएं हैं और वे आसानी से अलगाव में परीक्षण किए जाते हैं। यह भी ध्यान देने योग्य हो सकता है, कि एक महत्वपूर्ण विशेषता के साथ परिपक्व पार्सर पुस्तकालयों जहाज: त्रुटि रिपोर्टिंग। पार्सिंग गलत होने पर डिसेंट एरर रिकवरी तुच्छ नहीं है। प्रमाण के रूप में, मैं PHP के parse error, unexpected T_PAAMAYIM_NEKUDOTAYIM: D का आह्वान करता हूं

  • उनका दृष्टिकोण स्ट्रिंग्स को हेरफेर करता है, स्पष्ट रूप से राज्य को बनाए रखता है और कच्चे इनपुट को पार्स किए गए इनपुट को मैन्युअल रूप से उठाता है। आपको त्रुटि रिपोर्टिंग सहित खुद को सब कुछ लिखना होगा। और जब कुछ गलत होता है, तो आप पूरी तरह से खो जाते हैं।

विडंबना यह है कि आपके दृष्टिकोण के साथ लिखे गए पार्सर की शुद्धता अपेक्षाकृत आसानी से साबित होती है। उनके मामले में, यह लगभग असंभव है।

एक सॉफ्टवेयर डिज़ाइन के निर्माण के दो तरीके हैं: एक तरीका यह है कि इसे इतना सरल बनाया जाए कि स्पष्ट रूप से कोई कमी न हो, और दूसरा तरीका यह है कि इसे इतना जटिल बना दिया जाए कि कोई स्पष्ट कमी न रहे। पहली विधि कहीं अधिक कठिन है।

कार होयर

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

हालांकि, अंत में सवाल यह है कि इसे बनाए रखने के लिए कौन है? अगर यह आप है, तो यह आपकी कॉल है, कोई भी कुछ भी कहता है। यदि यह उसे होने जा रहा है, तो केवल दो संभावनाएं हैं: उसे पार्सर लाइब्रेरी को समझने का तरीका खोजें या उसके लिए एक अनिवार्य पार्सर लिखें। मेरा सुझाव है कि आप इसे अपने पार्सर संरचना से उत्पन्न करते हैं: डी


दो दृष्टिकोणों के बीच अंतर का उत्कृष्ट विवरण।
smarmy53

6
आपने जाहिरा तौर पर प्रोग्रामर के लिए TVTropes से लिंक किया है। अलविदा दोपहर ...
इज़्काता

10

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

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

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

व्यक्तिगत रूप से, मेरा पहला झुकाव जब मुझे DSL बनाने की आवश्यकता होती है, तो Boo (.Net) या Groovy (JVM) जैसी किसी चीज़ का उपयोग करने के लिए होगा, क्योंकि मुझे मौजूदा प्रोग्रामिंग भाषा की ताकत और अविश्वसनीय कस्टमाइज़ेबिलिटी के साथ एनआरओएस और सरल समायोजन का निर्माण करने की शक्ति मिलती है। कंपाइलर पाइपलाइन के बिना, थकाऊ सामान को लागू करने के बिना, जिसे मैं शून्य (लूप, चर, ऑब्जेक्ट मॉडल, आदि) से शुरू करने पर करूंगा। अगर मैं रूबी या लिस्प विकास करने वाली एक दुकान में था, तो मैं सिर्फ उन मुहावरों का उपयोग करूँगा जो वहां समझ में आते हैं (मेटाप्रोग्रामिंग, आदि)

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


9

मैं पार्सिंग एल्गोरिदम और पसंद करने में पारंगत नहीं हूं, लेकिन मुझे लगता है कि पुडिंग का प्रमाण खाने में है। इसलिए यदि अन्य सभी विफल हो जाते हैं, तो आप उसे पार्सर को अपने तरीके से लागू करने की पेशकश कर सकते हैं। फिर

  • या तो समाधानों में निवेश किए गए समय की तुलना करें,
  • एक व्यापक स्वीकृति परीक्षण के माध्यम से दोनों समाधानों को देखें, जिसमें कम कीड़े हों, और
  • एक स्वतंत्र जज ने आकार और स्पष्टता में परिणामी कोड की आपकी तुलना की।

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


यह एक महान विचार है! कमोंट यूनिट टेस्टिंग फ्रेमवर्क का उपयोग करना भी आसान होगा।
smarmy53

1
सह-कार्यकर्ता होने के लिए +1 विभाजित संस्करण करते हैं ... ओपी को इसे बनाने का काम सौंपा गया था, इसलिए वह वह है जो इसका समर्थन करने वाला है - सहकर्मी नहीं। बस उसे अपने अन्य काम के शीर्ष पर यह सुझाव देना कि वह उसे आपकी पीठ से हटाने के लिए पर्याप्त हो सकता है।
इजाकाता

7

आपने यह पूछा है कि क्या आपके पास एक तकनीकी प्रश्न है, लेकिन जैसा कि आप शायद पहले से ही जानते हैं, यहां कोई तकनीकी प्रश्न नहीं है। चरित्र स्तर पर कुछ हैक करने के लिए आपका दृष्टिकोण बहुत बेहतर है।

वास्तविक समस्या यह है कि आपके (संभवतः अधिक अनुभवी) सहकर्मी असुरक्षित हैं, और आपके ज्ञान से खतरा महसूस होता है। आप उसे तकनीकी तर्कों के साथ राजी नहीं करेंगे ; यह सिर्फ उसे और अधिक रक्षात्मक बना देगा। इसके बजाय आपको उसके डर को कम करने के लिए कोई रास्ता निकालना होगा। मैं कई सुझाव नहीं दे सकता, लेकिन आप विरासत कोड के अपने ज्ञान के लिए उच्च संबंध दिखाने की कोशिश कर सकते हैं।

अंत में, यदि आपका प्रबंधक अपने विशिष्ट तकनीकी तर्कों से सहमत है और आपके समाधान को त्याग देता है, तो मुझे लगता है कि आपको किसी अन्य पद पर देखना होगा। स्पष्ट रूप से आप अधिक परिष्कृत संगठन में अधिक मूल्यवान और अधिक मूल्यवान होंगे।


आप सही हैं मैं पहले से ही जानता था कि मेरा दृष्टिकोण बेहतर है, हालांकि मैं एक अच्छा, समझाने-समझाने के साथ बाहर आने में विफल रहा, यह वह तकनीकी जानकारी है जिसकी मुझे तलाश है। समस्या का "मानव अंतःक्रिया" पक्ष उतना ही महत्वपूर्ण है जितना कि तकनीकी एक (यदि अधिक नहीं)।
smarmy53

4

मैं संक्षिप्त हूँ:

Cthulhu रास्ता पार्स करना मुश्किल है। यह उसके खिलाफ सबसे सरल और सबसे ठोस तर्क है।

यह सरल भाषाओं के लिए चाल कर सकता है; नियमित भाषाएं बोलें। यह शायद एक नियमित अभिव्यक्ति की तुलना में आसान नहीं होगा, हालांकि।

यह थोड़ा और अधिक जटिल भाषाओं के लिए ट्रिक भी कर सकता है।

हालांकि, मैं घोंसले के शिकार के साथ किसी भी भाषा के लिए Cthulhu parser देखना चाहता हूं, या सिर्फ "काफी स्टेटफुल" - गणितीय अभिव्यक्तियाँ, या आपका उदाहरण (नेस्टेड फंक्शन कॉल)।

कल्पना कीजिए कि अगर किसी ने ऐसी (गैर-तुच्छ संदर्भ-मुक्त) भाषा के लिए एक पार्सर को समझाने की कोशिश की तो क्या होगा । बशर्ते वह एक सही पार्सर लिखने के लिए पर्याप्त स्मार्ट हो, मैं शर्त लगाऊंगा कि कोडिंग के दौरान वह पहले टोकेनिज़ॉन को खोजेगा, और फिर किसी तरह से पुनरावर्ती वंशज पार्सिंग करेगा।

उसके बाद, इस बात को सरल: "अरे देखो, आपने कुछ लिखा है जिसे एक पुनरावर्ती वंशीय पार्सर कहा जाता है? क्या आप जानते हैं कि इसे नियमित व्याकरण की तरह एक साधारण व्याकरण विवरण से स्वचालित रूप से उत्पन्न किया जा सकता है?


लंबी कहानी छोटी:
एक ही चीज जो किसी को सभ्य दृष्टिकोण का उपयोग करने से रोक सकती है, वह है उनका अज्ञान।


1

शायद एक अच्छे DSL शब्दार्थ पर काम करना भी महत्वपूर्ण है (वाक्य रचना मायने रखती है, लेकिन शब्दार्थ भी)। यदि आप इन मुद्दों से परिचित नहीं हैं, तो मैं कुछ पुस्तकों को पढ़ने का सुझाव दूंगा , जैसे प्रोग्रामिंग लैंग्वेजेज प्रैग्मैटिक्स (एम.एस.कोट) और क्रिश्चियन क्विनेक। छोटे टुकड़ों में लिस्प । कैम्ब्रिज यूनिवर्सिटी प्रेस, 1996।

डीएसएल सम्मेलनों में हाल के पेपरों को पढ़ना, उदाहरण के लिए DSL2011 को भी मदद करनी चाहिए।

डोमेन विशिष्ट भाषा को डिज़ाइन करना और कार्यान्वित करना कठिन है (और अधिकांश कठिनाई पार्सिंग नहीं है !)।

मुझे वास्तव में समझ में नहीं आता है कि Cthulhu रास्ता पार्स करने से आपका क्या मतलब है ; मुझे लगता है कि आप किसी भी तरह विचित्र फैशन में पार्स करने का मतलब है।


अच्छा लिंक। Cthulhu के लिए, क्षमा करें, मैं लिंक भूल गया। यह एक क्लासिक कोडिंगहोरर आर्टिकल का संदर्भ है: कोडिंगहोरर . com / blog / 2009 / 11 / parsing-html-the-cthulhu-way.html । मैंने मूल पोस्ट को अपडेट किया।
smarmy53
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.