2010-01-30 8 views
22

मैंने हाल ही में एक मौजूदा उपकरण में स्रोत फ़ाइल पार्सिंग जोड़ा है जो जटिल कमांड लाइन तर्कों से आउटपुट फ़ाइलों को उत्पन्न करता है।क्या सी ++ के लिए टोकननाइज़र उत्पन्न करने के लिए लेक्स/फ्लेक्स की तुलना में बेहतर (अधिक आधुनिक) उपकरण है?

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

मैंने इस कस्टम स्रोत फ़ाइल प्रारूप के लिए टोकनेज़र उत्पन्न करने के लिए विंडोज़ के लिए फ्लेक्स 2.5.4 का उपयोग किया, और यह काम किया। लेकिन मुझे कोड से नफरत है। वैश्विक चर, व्यापक नामकरण सम्मेलन, और उत्पन्न सी ++ कोड भयानक था। मौजूदा कोड पीढ़ी बैकएंड फ्लेक्स के आउटपुट पर चिपकाया गया था - मैं yacc या bison का उपयोग नहीं करता हूं।

मैं उस कोड में वापस जा रहा हूं, और मैं एक बेहतर/अधिक आधुनिक उपकरण का उपयोग करना चाहता हूं। क्या किसी को कुछ पता है।

  • Windows में रन कमांड प्रॉम्प्ट (विजुअल स्टूडियो एकीकरण ठीक है, लेकिन मैं का निर्माण करने की फ़ाइलों का उपयोग करें)
  • उत्पन्न करता है एक उचित समझाया सी ++ tokenizer। (कोई वैश्विक चर)
  • tokenizing नियम
  • मुझे सी क्रम का उपयोग करने के लिए मजबूर नहीं करता है (या इसे नकली) फ़ाइल पढ़ने के लिए (लेक्स वाक्य रचना एक प्लस के साथ संगत) वर्णन करने के लिए नियमित अभिव्यक्ति का उपयोग करता है। (स्मृति से पार्स)
  • मुझे चेतावनी जब मेरे नियमों को पीछे tokenizer मजबूर (या यह स्वचालित रूप से ठीक करता है)
  • मुझे चर और विधि के नाम पर पूरा नियंत्रण देता है (इसलिए मैं अपने मौजूदा नामकरण सम्मेलन के अनुरूप कर सकते हैं)
  • मुझे नाम टकराव के बिना एक .exe में कई पारसर्स से जोड़ने के लिए
  • एक यूनिकोड (16 बिट यूसीएस -2) पार्सर उत्पन्न कर सकता हूँ अगर मैं चाहता हूँ यह करने के लिए
  • एक एकीकृत tokenizer + पार्सर जनरेटर नहीं है (मैं एक लेक्स चाहते अनुमति देता है प्रतिस्थापन, एक lex + yacc प्रतिस्थापन नहीं)

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

+3

बूस्ट। पाइरेट, बूस्ट.प्रोटो और बूस्ट.एक्सप्रेसिव विकल्प नहीं हैं? –

+0

@ कोनराड: वे हो सकते हैं, मैं उनसे परिचित नहीं हूं। सी ++ वर्ग की बजाय टेम्पलेट जेनरेट करने वाला कुछ स्वीकार्य होगा। –

उत्तर

11

रैगेल: http://www.complang.org/ragel/ यह आपकी अधिकांश आवश्यकताओं को फिट करता है।

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

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

+0

+1 पर एक नज़र डालेंगी यह आशाजनक लग रहा है। –

+0

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

+0

मैंने केल्बेट और रागेल के संयोजन में, एकाधिक प्रेषण संचालन के साथ एएसटी नोड परिभाषा के लिए वृक्षारोपण का भी उपयोग किया। इन दिनों, मेरे पास कुछ अतिरिक्त चाल (जैसे एएसटी-ट्रैवर्सिंग इटरेटर कक्षाएं) के साथ मेरा अपना प्रतिस्थापन है - मैं इसे भी जारी कर सकता हूं, एक दिन ... – Steve314

5

दो टूल्स हैं जो दिमाग में आते हैं, हालांकि आपको अपने लिए यह पता लगाना होगा कि उपयुक्त होगा, Antlr और GoldParser। दोनों टूल्स में भाषा बाइंडिंग उपलब्ध हैं जिसमें इसे सी ++ रनटाइम पर्यावरण में प्लग किया जा सकता है।

+0

जब मैं गुगलिंग के स्थान पर गया, तो बोलते हुए, बूस्ट लाइब्रेरी का उपयोग करके फ्लेक्स/बाइसन का एक ऑब्जेक्ट उन्मुख संस्करण है - इसे देखें http://dudka.cz/vyp08 – t0mm13b

+0

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

+0

@ tommeib75: dudka.cz अच्छा खोज। हो सकता है कि उसके पास क्लीन कोड में फ्लेक्स आउटपुट को झुकाव का बेहतर तरीका हो। एएनटीएलआर के लिए –

5

फ्लेक्स में सी ++ आउटपुट विकल्प भी है।
परिणाम कक्षाओं का एक सेट है जो उस पार्सिंग करते हैं। आप में स्रोत यह है तो

%option C++ 
%option yyclass="Lexer" 

:

std::fstream file("config"); 
Lexer   lexer(&file) 
while(int token = lexer.yylex()) 
{ 
} 
+0

हाँ, मैंने यह कोशिश की, यह सी कोड आईएमओ से भी बदतर है, लेकिन यह गोलबल चर और एकाधिक उदाहरण समस्या को हल करता है। –

+1

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

6

Boost.Spirit.Qi (पार्सर tokenizer) या बूस्ट

बस आप लेक्स फ़ाइल के सिर के लिए निम्न जोड़ें। Spirit.Lex (केवल टोकननाइज़र)। मैं बिल्कुल क्यूई से प्यार करता हूं, और लेक्स भी बुरा नहीं है, लेकिन मैं सिर्फ अपनी पार्सिंग जरूरतों के लिए क्यूई लेता हूं ...

क्यूई के साथ एकमात्र वास्तविक दोष संकलन समय में वृद्धि करता है, और यह हाथ से लिखे गए पार्सिंग कोड से थोड़ा धीमा चलता है। हालांकि, रेगेक्स के साथ पार्सिंग की तुलना में यह आमतौर पर बहुत तेज है।

http://www.boost.org/doc/libs/1_41_0/libs/spirit/doc/html/index.html

+0

धन्यवाद, मुझे Boost.Spirit.Lex –

2

boost.spirit और Yard parser मेरे मन में आते हैं। ध्यान दें कि लेक्सर जेनरेटर रखने का दृष्टिकोण कुछ हद तक टोकन निर्दिष्ट करने के लिए सी ++ आंतरिक डीएसएल (डोमेन-विशिष्ट भाषा) द्वारा प्रतिस्थापित किया जाता है। बस क्योंकि यह आपके व्याकरण को निर्दिष्ट करने के लिए नियमों की एक श्रृंखला का पालन करके बाहरी उपयोगिता के बिना आपके कोड का हिस्सा है।

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

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