parsing फ्लेक्स का उपयोग करते हुए मैं एक दो-पास स्कैनर कैसे लागू करूं?




bison flex-lexer (2)

एक पालतू-प्रोजेक्ट के रूप में, मैं अपने स्वयं के डिज़ाइन की मूल भाषा को लागू करने का प्रयास करना चाहता हूं जिसका उपयोग वेब-स्क्रिप्टिंग भाषा के रूप में किया जा सकता है अपाचे सीजीआई के रूप में एक सी ++ प्रोग्राम चलाने के लिए यह तुच्छ है, इसलिए असली काम यह है कि कैसे नॉन-कोड (एचटीएमएल / सीएसएस मार्कअप) और सर्वर-साइड कोड युक्त एक इनपुट फाइल को पार्स करना है।

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

उस और जो मैं करना चाहता हूँ, के बीच अंतर यह है कि PHP की तरह, इस भाषा में सादे एचटीएमएल मार्कअप और स्क्रिप्टिंग भाषा को निम्न में शामिल किया जा सकता है:

<p>Hello,
<? echo "World ?>
</p>

क्या यह मानते हुए मैं गलत हूं कि इनपुट फ़ाइल को पार्स करने में सक्षम होगा:

  1. स्क्रिप्ट प्रारंभ टैग तक इनपुट को स्कैन करें ('
  2. दूसरा स्कैनर इनपुट फ़ाइल के सर्वर-साइड स्क्रिप्ट अनुभाग को निरूपित करता है (खुले टैग से: '') और टोककर पार्सर को पास करता है, जिसमें फ़ाइल में मार्कअप के बारे में जानने की कोई आवश्यकता नहीं है।
  3. नियंत्रण को पहले स्कैनर पर लौटा दिया गया है जो इस सामान्य पैटर्न को जारी रखता है।

असल में, पहला स्कैनर केवल मार्कअप (जो सीधे ब्राउज़र को सीधे बदल दिया गया है) और कोड के बीच अंतर करता है, जो दूसरे स्कैनर को दिया जाता है, जो बदले में कोड को टोकन कर देता है और पार्सर को टोकन पास करता है।

यदि यह एक ठोस डिज़ाइन पैटर्न नहीं है, तो PHP जैसी भाषा कैसे स्कैनिंग इनपुट और पार्सिंग कोड कुशलता से संभालती है?


आप प्रारंभ की स्थिति को देखना चाहते हैं उदाहरण के लिए:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

आप राज्य 0 में शुरू करते हैं, राज्यों को बदलने के लिए BEGIN मैक्रो का उपयोग करें। एक विशेष स्थिति में केवल आरई के साथ मिलान करने के लिए, आरई के साथ राज्य के नाम से कोण-कोष्ठक से घिरा हुआ है।

उपरोक्त उदाहरण में, "PHP" राज्य है। "PHP_TOKEN" और "HTML_TOKEN" आपके yacc फ़ाइल द्वारा परिभाषित _% token_s हैं।


PHP स्कैनिंग और मार्कअप के बीच अंतर नहीं करता है यह केवल बफ़र को आउटपुट करता है जब मार्कअप मोड में, और फिर कोड मोड में पार्स करने के लिए स्विच होता है। आपको दो पास स्कैनर की आवश्यकता नहीं है, और आप ऐसा केवल एक फ्लेक्स लेक्सर के साथ कर सकते हैं।

यदि आप PHP में स्वयं कैसे कार्य करते हैं, में रुचि रखते हैं, स्रोत डाउनलोड करें (PHP4 स्रोत की कोशिश करें, यह समझने में बहुत आसान है)। आप क्या देखना चाहते हैं ज़ेंड डायरेक्टरी में है, zend_language_scanner.l

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







lexical-analysis