2011-03-19 13 views
11

मैं शैक्षिक उद्देश्यों के लिए आईएमएपी प्रोटोकॉल के लिए एक लेक्सर लिख रहा हूं और मुझे लगता है कि मुझे लेक्सर और पार्सर के बीच रेखा को आकर्षित करना चाहिए। यहमुझे लेक्सर और पार्सर के बीच की रेखा कहां खींचना चाहिए?

mailbox-data = "FLAGS" SP flag-list 
flag-list  = "(" [flag *(SP flag)] ")" 
flag   = "\Answered"/"\Deleted" 

क्योंकि वे स्ट्रिंग शाब्दिक (उर्फ "टर्मिनल" टोकन) के रूप में निर्दिष्ट कर रहे हैं होगा: IMAP सर्वर प्रतिक्रिया के इस उदाहरण लें:

* FLAGS (\Answered \Deleted) 

यह प्रतिक्रिया इस तरह औपचारिक वाक्य रचना में परिभाषित किया गया है

(TknAnsweredFlag) 
(TknSpace) 
(TknDeletedFlag) 

या यह बस के रूप में someth फेंकना सही होगा: lexer तरह प्रत्येक के लिए एक अद्वितीय टोकन फेंकना के लिए, और अधिक सही हो इस तरह ing: - अगर \Answered दो अलग-अलग संदर्भों में दो अर्थ था lexer सही टोकन उत्सर्जन नहीं होगा

(TknBackSlash) 
(TknString "Answered") 
(TknSpace) 
(TknBackSlash) 
(TknString "Deleted") 

मेरे भ्रम की स्थिति है कि पूर्व विधि lexer overcomplicate सकता है। एक उत्तीर्ण उदाहरण के रूप में (यह स्थिति नहीं होगी क्योंकि ई-मेल पते उद्धरणों में संलग्न हैं), लेक्सर ई-मेल पते से कैसे निपटेंगे जैसे \ [email protected]? या औपचारिक वाक्यविन्यास है जो कभी ऐसी अस्पष्टता उत्पन्न करने की अनुमति नहीं देता है?

उत्तर

7

एक सामान्य नियम के रूप में, आप व्याकरण में प्रचार करने के लिए लेक्सिकल सिंटैक्स नहीं चाहते हैं, क्योंकि इसकी विस्तृत जानकारी है। उदाहरण के लिए, कंप्यूटर प्रोग्रामिंग लैंगेज के लिए एक लेक्सर निश्चित रूप से संख्याओं को पहचान लेगा, लेकिन यह आमतौर पर HEXNUMBER और DECIMALNUMBER टोकन का उत्पादन करने के लिए अनुचित है, क्योंकि यह व्याकरण के लिए महत्वपूर्ण नहीं है।

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

यदि आपका लक्ष्य केवल ध्वज मूल्यों को पढ़ने के लिए है, तो वास्तव में आपको उनमें से अंतर करने की आवश्यकता नहीं है, और कोई संबंधित सामग्री वाला TknFlag पर्याप्त नहीं होगा।

यदि आपका लक्ष्य अलग-अलग ध्वज मूल्यों को संसाधित करना है, तो आपको यह जानना होगा कि आपको उत्तर दिए गए और/या हटाए गए संकेत हैं या नहीं। वे व्याख्यात्मक रूप से वर्तनी कैसे हैं अप्रासंगिक है; इसलिए मैं आपके TknAnssejFlag समाधान के साथ जाऊंगा। मैं TknSpace को डंप कर दूंगा, क्योंकि झंडे के किसी भी अनुक्रम में, हस्तक्षेप करने वाली जगहें होनी चाहिए (आपका स्पेस ऐसा कहता है), इसलिए मैं जो भी व्हाइटस्पेस दमन मशीनरी आप लेक्सर ऑफ़र का उपयोग कर समाप्त करने की कोशिश करता हूं।

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

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

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

0

मैं लेक्सर और पार्सर को अलग करने से बचने की सलाह दूंगा - आधुनिक पार्सिंग दृष्टिकोण (जैसे PEGs) लेक्सिंग और पार्सिंग मिश्रण करने की अनुमति देता है। इस तरह आपको टोकन की आवश्यकता नहीं होगी।

1

मैं पहले सीएफजी के साथ आउंगा और जो भी टर्मिनल इसे अपनी नौकरी करने की ज़रूरत है वह है कि लेक्सर को क्या पहचानना चाहिए; अन्यथा आप स्ट्रिंग को टोकननाइज़ करने के उचित तरीके से अनुमान लगा रहे हैं।

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