2012-03-08 19 views
18

के लिए फ्लेक्स (लेक्सर) समर्थन मैं सोच रहा हूं कि फ्लेक्स का नवीनतम संस्करण यूनिकोड का समर्थन करता है या नहीं?यूनिकोड

यदि हां, तो चीनी अक्षरों से मेल खाने के लिए पैटर्न का उपयोग कैसे किया जा सकता है?

अधिक: Use regular expression to match ANY Chinese character in utf-8 encoding

उत्तर

14

फिलहाल, फ्लेक्स केवल जो मूल रूप से आप UTF-8 उपयोग करने के लिए सीमित करता है 8 बिट स्कैनर उत्पन्न करता है। तो अगर आप एक पैटर्न है:

肖晗 { printf ("xiaohan\n"); } 

यह अपेक्षा के अनुरूप काम करेंगे, पैटर्न में बाइट्स की अनुक्रम के रूप में और इनपुट में एक ही हो जाएगा। चरित्र वर्ग क्या अधिक कठिन है। आप या तो चरित्र 肖 या 晗 मिलान करना चाहते हैं, तो आप नहीं लिख सकते हैं:

[肖晗] { printf ("xiaohan/2\n"); } 

क्योंकि यह छह बाइट्स 0xe8, के पास 0x82, 0x96, 0xe6, 0x99 और 0x97, में से प्रत्येक से मिलान करेगा जो अभ्यास साधन में कि यदि आप इनपुट के रूप में 肖晗 की आपूर्ति करते हैं, तो पैटर्न छह बार मेल खाता है। तो इस साधारण मामले में, आपको पैटर्न को (肖|晗) पर फिर से लिखना होगा।

श्रेणियों के लिए, हंस Aberg एक tool in Haskell कि 8-बिट पैटर्न में इन बदल देती लिखा है:

Unicode> urToRegU8 0 0xFFFF 
[\0-\x7F]|[\xC2-\xDF][\x80-\xBF]|(\xE0[\xA0-\xBF]|[\xE1-\xEF][\x80-\xBF])[\x80-\xBF] 
Unicode> urToRegU32 0x00010000 0x001FFFFF 
\0[\x01-\x1F][\0-\xFF][\0-\xFF] 
Unicode> urToRegU32L 0x00010000 0x001FFFFF 
[\x01-\x1F][\0-\xFF][\0-\xFF]\0 

यह सुंदर नहीं है, लेकिन यह काम करना चाहिए।

+0

कामकाज पर अधिक संकेत? – xiaohan2012

+0

मैंने मेलिंग सूची से जवाब में जवाब का जवाब दिया। –

+0

धन्यवाद। मुझे बहुत प्रेरित करने के लिए लगता है! – xiaohan2012

15

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

यह सामान्य प्रोग्रामिंग भाषाओं के लिए अच्छी तरह से काम करेगा, जहां आप अपने कार्यान्वयन के उपयोगकर्ताओं को जोर दे सकते हैं कि स्रोत भाषा ASCII/UTF-8 में लिखी गई है (और कोई अन्य एन्कोडिंग समर्थित नहीं है, अवधि)।

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

विचार यह है कि आप एक लेक्स नियम का उपयोग कर एक पैटर्न जो UTF-8 बाइट्स शामिल पहचान सकते हैं (और फिर शायद yytext लेते हैं, और UTF-8 में से परिवर्तित या कम से कम उसे सत्यापित करने में।)

ASC  [\x00-\x7f] 
ASCN [\x00-\t\v-\x7f] 
U  [\x80-\xbf] 
U2  [\xc2-\xdf] 
U3  [\xe0-\xef] 
U4  [\xf0-\xf4] 

UANY {ASC}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} 
UANYN {ASCN}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} 
UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} 

आप देख सकते हैं, हम पैटर्न ASCII मैच के लिए परिभाषित कर सकते हैं: http://www.kylheku.com/cgit/txr/tree/parser.l

इस अनुभाग में नीचे स्क्रॉल:

एक काम उदाहरण के लिए, इस फ़ाइल को विशेष रूप से, TXR भाषा के स्रोत कोड को देखने के characte आरएस के साथ ही यूटीएफ -8 प्रारंभ और निरंतर बाइट्स। यूटीएफ -8 एक व्याख्यात्मक संकेत है, और यह एक व्याख्यात्मक विश्लेषक जनरेटर है, इसलिए ... कोई समस्या नहीं!

कुछ स्पष्टीकरण: UANY का मतलब है किसी भी चरित्र, एकल-बाइट ASCII या बहु-बाइट यूटीएफ -8 से मेल खाता है। UANYN का अर्थ UANY है लेकिन न्यूलाइन से मेल नहीं खाता है। यह टोकन के लिए उपयोगी है जो लाइनों के अंत में # से एक टिप्पणी कहने के लिए लाइनों को तोड़ नहीं देते हैं, जिसमें अंतरराष्ट्रीय पाठ होता है।UONLY का अर्थ केवल एक यूटीएफ -8 विस्तारित चरित्र से मेल खाता है, न कि ASCII एक। यह एक लेक्स नियम लिखने के लिए उपयोगी है जिसे कुछ विशिष्ट ASCII वर्णों को बाहर करने की आवश्यकता है (केवल नई लाइन नहीं) लेकिन सभी विस्तारित वर्ण ठीक हैं।

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

+0

बस सोच रहा है, यू 4 की परिभाषा नहीं होनी चाहिए: 'U4 [\ xf0- \ xf7]' वास्तव में 11110000 से 11110111 तक सभी संभावनाओं को समायोजित करने के लिए? – exa

+0

@exa विस्तार पर अच्छा ध्यान दें! बाइट की पूरी श्रृंखला हमें 'यू + 3 एफएफएफएफएफ' तक कोड पॉइंट देगी। 'एफ 4'' यू +10 एफएफएफएफ 'तक सीमित है। – Kaz

+0

मुझे आश्चर्य है कि प्रस्तावित दृष्टिकोण सुरक्षित है या नहीं। इन टीआरएक्स पैटर्न में अमान्य यू + डी 800-यू + डीएफएफएफ रेंज शामिल है (यूटीएफ 016 सरोगेट हिस्सों अमान्य यूनिकोड हैं) और '{यू 4} {यू} {यू} {यू}' यूनिकोड ऊपरी बाउंड यू +10 एफएफएफएफ से अधिक है, जैसा कि आपने कहा है अंतिम कोड बिंदु '\ xf4 [\ x80- \ x8f] होना चाहिए [\ x80- \ xbf] [\ x80- \ xbf] '\ xf4 [\ x80- \ xbf] [\ x80- \ xbf] [\ x80- \ xbf] '। –

1

मुझे आश्चर्य है कि फ्लेक्स का नवीनतम संस्करण यूनिकोड का समर्थन करता है या नहीं?

यदि हां, तो चीनी अक्षरों से मेल खाने के लिए पैटर्न का उपयोग कैसे किया जा सकता है?

एक फ्लेक्स की तरह शाब्दिक विश्लेषक के साथ चीनी अक्षरों और अन्य यूनिकोड कोड अंकों के साथ प्रतिमानों से मिलान करने के लिए, आप सी ++ कि फ्लेक्स के साथ पीछे संगत है के लिए RE/flex lexical analyzer इस्तेमाल कर सकते हैं। आरई/फ्लेक्स यूनिकोड का समर्थन करता है और लेक्सन और पार्सर्स बनाने के लिए बाइसन के साथ काम करता है। यूनिकोड सक्षम करने के लिए

%option flex unicode 
%% 
[肖晗] { printf ("xiaohan/2\n"); } 
%% 

उपयोग वैश्विक %option unicode:

आप इस तरह के रूप RE/फ्लेक्स विशिष्टताओं में यूनिकोड पैटर्न (और UTF-8 नियमित अभिव्यक्ति) लिख सकते हैं। आप किसी एकल पैटर्न के लिए यूनिकोड को प्रतिबंधित करने के लिए एक स्थानीय संशोधक (?u:) उपयोग कर सकते हैं (ताकि सब कुछ अभी भी ASCII/8 बिट फ्लेक्स में के रूप में है): तो तुम yytext उपयोग कर सकते हैं

%option flex 
%% 
(?u:[肖晗]) { printf ("xiaohan/2\n"); } 
(?u:\p{Han}) { printf ("Han character %s\n", yytext); } 
.    { printf ("8-bit character %d\n", yytext[0]); } 
%% 

विकल्प flex, फ्लेक्स संगतता सक्षम बनाता है, yyleng, ECHO, और इसी तरह। flex विकल्प RE/फ्लेक्स के बिना Lexer विधि कॉल की उम्मीद: text() (या str() और wstr()std::string और std::wstring के लिए), size() (या विस्तृत चार लंबाई के लिए wsize()), और echo()। आरई/फ्लेक्स विधि कॉल क्लीनर IMHO हैं, और विस्तृत चार संचालन शामिल हैं।