2 या अपने खुद के मार्कअप का अनुवाद करने की कला

+ बोनस: सी ++ में एक दूसरे में कक्षाओं का आपसी समावेश


नमस्कार, हेब्र! यह लेख हमारे अपने हाथों से लेख द आर्ट ऑफ़ परसिंग या डीओएम की प्रत्यक्ष निरंतरता है , जहां हमने एक HTML दस्तावेज़ को पार्स किया है और इसके आधार पर एक सार सिंटैक्स ट्री (एएसटी) का निर्माण किया है जिसमें केवल मानक सी ++ लाइब्रेरी का उपयोग करके अनुक्रमण के माध्यम से किसी भी तत्व तक पहुंचा जा सकता है, दूसरे शब्दों में, हमने अपने स्वयं के आधार पर पार्स करना सीखा। एक्सएमएल की तरह सामान। आपको याद दिला दूं कि पार्सिंग, या पार्सिंग / पार्सिंग की प्रक्रिया में दो चरण होते हैं: लेक्सिकल पार्सिंग (पार्सिंग टेक्स्ट को टोकन में) और एएसटी का निर्माण। यदि हमने उदाहरणों और स्रोत कोड के साथ पहले महान विवरण की जांच की, तो दूसरे का वर्णन एक खाली तितली गुड़िया की तरह दिखता है, जिसमें केवल एक खोल है, और लेखक ने प्रकाशन से पहले उत्कृष्ट सामग्री निकाली। एक पेड़ बनाने के लिए HTML के लिए एक कारण था वास्तव में सरल है, आपको केवल 4 कक्षाएं चाहिए: एक खाली टैग, ब्लॉक, टेक्स्ट नोड और ब्लॉक से विरासत में मिली दस्तावेज़ जड़। आज हम ऐसी सरलता को पीछे छोड़ देंगे और एक ऐसा पेड़ बनाएंगे, जहां तत्वों के गुण, दोनों खाली और ब्लॉक होते हैं, वे टैग की विशेषताओं में शामिल नहीं होंगे, लेकिन सीधे कक्षाओं में, और इसके लिए आपको बहुत सारी कक्षाएं बनानी होंगी। वास्तव में बहुत कुछ। हम सरल प्रसिद्ध मार्कअप भाषाओं से नहीं, बल्कि कट के नीचे की छवि में दिखाए गए नियमों के साथ अपना खुद का निर्माण करेंगे। इसके अलावा, अंत में, हम अनुवाद करेंगे, या, अधिक सही ढंग से, पिछले लेख के साथ दस्तावेज़ का अनुवाद करेंगे , हमारी भाषा में, HTML में, और एक बोनस के रूप में, मैं नौसिखिए C ++ प्रोग्रामर को एक तुच्छ लेकिन मुश्किल-से-खोजने वाले प्रश्न का उत्तर दूंगा: एक दूसरे में कक्षाएं कैसे शामिल करें?



व्याकरण नोट्स


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

... <ordered_list_item> = <number_marker> <div> <number_marker> = <number> "." {<number> "."} " " <number> = <digit> {<digit>} !! link ending ">" and image/span ending "]" can't follow "\n" or document start 

अनुवाद: ">" लिंक का अंत और छवि / इनलाइन तत्व "]" तुरंत एक पंक्ति या दस्तावेज़ की शुरुआत का पालन नहीं कर सकता है

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

आइए इस भाषा का पूरा विवरण देखें:

 <article> = {<article_item>} <article_item> = <underline> | <section> (* ARTICLE ITEMS *) <underline> = "___" {"_"} "\n" <section> = <div> {<div>} <div> = <paragraphs> | <title> | <quote> | <cite> | <unordered_list> | <ordered_list> (* SECTION ITEMS *) <paragraphs> = <paragraph> {"\n" <paragraph>} <paragraph> = <span> {<span>} ("\n" | <END>) <span> = <bold> | <italic> | <underlined> | <overlined> | <throwlined> | <subscript> | <superscript> | <marked> | <monospace> | <text> | <image> | <link> | <notification> <title> = <number signs> <left_angle_bracket> {<span>} <right_angle_bracket> ("\n" | <END>) <number signs> "######" | "#####" | "####" | "###" | "##" | "#" <quote> = "> " {<span>} ("\n" | <END>) <cite> = ">>" <number> ("\n" | <END>) <number> = <digit> {<digit>} (* PARAGRAPH ITEMS *) <bold> = "*[" {<span>} "]" <italic> = "%[" {<span>} "]" <underlined> = "_[" {<span>} "]" <overlined> = "^[" {<span>} "]" <throwlined> = "~[" {<span>} "]" <subscript> = "&[" {<span>} "]" <superscript> = "+[" {<span>} "]" <marked> = "=[" {<span>} "]" <monospace> = "`[" {<span>} "]" <text> = <textline> "\n" {<textline> "\n"} <textline> = <symbol> {<symbol>} <symbol> = /^[\n]/ <link> = "<<" <text> ">" {<span>} ">" <image> = "[<" <text> ">" [<text>] "]" <notification> = (" " | "\n") "@" <word> (" " | "\n" | <END>) <word> = (<letter> | <digit>) {<letter> | <digit>} <letter> = "a" | "b" | "c" | "d" | ... | "_" | "-" <digit> = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" (* LISTS *) <unordered_list> = <unordered_list_item> {<unordered_list_item>} <ordered_list> = <ordered_list_item> {<ordered_list_item>} <unordered_list_item> = <marker> <div> <marker> = ("*" {"*"}) | ("+" {"+"}) " " <ordered_list_item> = <number_marker> <div> <number_marker> = <number> "." {<number> "."} " " <number> = <digit> {<digit>} !! link ending ">" and image/span ending "]" can't follow "\n" or document start 

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

 (* TERMINALS *) "___...", "\n", "\n\n", "> ", ">>...", "###...[", "*[", "%[", "_[", "^[", "~[", "&[", "+[", "=[", "`[", "]", "<<", "[<", ">", " @... ", "\n@...\n", " @...\n", "\n@... ", "***... ", "+++... ", "123.56. " (* KEYS *) "_", "\n" ">", "#", "*", "%", "^", "~", "&", "+", "=", "`", "<", "[", "]", " ", "@", "1..9", ".", <END> 

अपेक्षित प्रकार के टोकन का ढेर


पिछली बार, फिर से, सब कुछ सरल था, हमारे पास केवल 10 प्रकार के टोकन थे, अंत की गिनती नहीं थी, और टोकन के इस चिड़ियाघर में खो जाने की संभावना कम थी। अब स्पष्ट रूप से अधिक प्रकार हैं। आपको याद दिला दूं कि लेसर का कार्य पार्सर को यथासंभव कम काम छोड़ना है, आदर्श रूप से, केवल एक पेड़ का निर्माण करना। इसलिए, टोकन के प्रकारों के सेट को उनके सार को यथासंभव सटीक रूप से प्रतिबिंबित करना चाहिए। पहले लेख में मैंने एक अच्छे सेट का उदाहरण दिया था, इसमें मैं इसे "विरोधी उदाहरण" के साथ देता हूँ। टर्मिनलों को इनलाइन टेक्स्ट एलिमेंट्स (बोल्ड - बोल्ड, इटैलिक - इटैलिक, आदि) देखना शुरू करें? हम उन्हें टोकन की एक जोड़ी के रूप में पार्स कर सकते हैं: नेता ("*", "%", आदि) और दास ("[") और इस रूप में इसे पार्सर को पास करते हैं। यह अनुमान लगाना आसान है कि लेक्सर स्तर पर एक पाठ तत्व की सटीक परिभाषा बनाना बेहतर है, अर्थात। परिभाषित "* [" के रूप में "bold_start", "% [" के रूप में "italic_start", आदि। अधिक प्रकार और अधिक सटीक रूप से वे खुद को प्रतिबिंबित करते हैं - बेहतर। इसके अलावा, दूसरा पहले की तुलना में अधिक महत्वपूर्ण है। उदाहरण के लिए, हम "@" प्रतीक और उपयोगकर्ता नाम के लिए अधिसूचना को पार्स कर सकते हैं, लेकिन जाहिर है, उन्हें एक टोकन में संयुक्त रूप से छोड़ना बेहतर है।
खैर, हमने प्रकारों पर फैसला किया। पाठ को टोकन में पार्स करने की प्रक्रिया कहाँ से शुरू करें? तब से, शुरू से शुरू करें। पार्स किए गए दस्तावेज़ की शुरुआत के तुरंत बाद क्या हो सकता है? अपनी उंगलियों को मोड़ने के लिए जल्दी मत करो। HTML के विपरीत, यहां सभी 22 प्रकार शुरू हो सकते हैं। यह ठीक है, थोड़ा एकीकरण के साथ सशस्त्र, हम इस तरह लिखते हैं:

 curr_token_type = TEXT | UNDERLINE | TITLE_START | QUOTE_START | CITE | BOLD_START | ... 

और प्रतीक प्रसंस्करण समारोह में:

 case TEXT | UNDERLINE | TITLE_START | QUOTE_START | CITE | ... 

यदि आपको समझ में नहीं आ रहा है कि दांव पर क्या है, तो पहला लेख पढ़ें

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

यह सरल है, अपने लिए देखें:

 if (c == '_') { buffer.push_back('_'); curr_token_type = TEXT | UNDERLINE | UNDERLINED_START; 

अंडरलाइन ने तुरंत तीन प्रकारों में से एक के निर्माण के तहत टोकन को निर्धारित किया: सादा पाठ, क्षैतिज रेखा या रेखांकित पाठ की शुरुआत ("_ [")।

समस्या पर लौटते हुए, सभी सामान्य प्रकारों पर नज़र कैसे रखें और उन सभी को संसाधित करना याद रखें? ढेर हो जाओ ... एक नोटबुक में! यह सही है, सूची में "cur_token_type = ..." के बाद आने वाले सभी सामान्य प्रकारों को लिखें और एक को संसाधित करने के बाद, दूसरे को सूची से अंत तक ले जाएं। आप सूची के साथ और कतार के साथ काम को व्यवस्थित कर सकते हैं, इससे ज्यादा फर्क नहीं पड़ता। मुख्य बात यह है कि आप यह नहीं भूलेंगे कि कौन से प्रकार पहले से ही संसाधित हैं और जिन्हें अभी भी संसाधित किया जाना है।

वर्ग वृक्ष


अंत में, हम पार्स करने के लिए मिला। यहां आपको भविष्य के पेड़ के नोड्स (नोड्स) के वर्गों को उसी तरह निर्धारित करने की आवश्यकता है जैसे हमने टोकन के प्रकारों के साथ निर्धारित किया था। ऐसा करने के लिए, नोटबुक को फिर से खोलें और निम्नलिखित लिखें:

 Node { Node * parent, Node_type type } #- Root { Root_item[] children, ulong children_count } 

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

हम जाली के बाद सूचियों के रूप में इन निर्भरताओं को निरूपित करते हैं, और हमें निम्नलिखित दस्तावेज मिलते हैं:

 Node { Node * parent, Node_type type } #- Root { Root_item[] children, ulong children_count } #Underline, #Section Root_item {} #- Underline {} Section { Div[] children, ulong children_count } #Paragraph, #Title, #Quote, #Cite, #Unordered_list, #Ordered_list Div {} #- Paragraph { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Title { char level, Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Quote { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Cite { ulong number } #- Unordered_list { Div } #Paragraph, #Title, #Quote, #Cite, #Ordered_list Ordered_list { Div } #Paragraph, #Title, #Quote, #Cite, Unordered list Span {} #- Bold { Span[] children, ulong children_count } #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Italic { Span[] children, ulong children_count } #Bold, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Underlined { Span[] children, ulong children_count } #Bold, #Italic, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Overlined { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Throwlined { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Subscript { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Superscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Superscript { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Marked, #Monospace, #Text, #Image, #Link, #Notification Marked { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Monospace, #Text, #Image, #Link, #Notification Monospace { Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Text, #Image, #Link, #Notification Text { string text } #- Image { string src, string alt } #- Link { string URL, Span[] children, ulong children_count } #Bold, #Italic, #Underlined, #Overlined, #Throwlined, #Subscript, #Superscript, #Marked, #Monospace, #Text, #Image, #Notification Notification { string user } #- 

यहाँ मैंने "# -" पर निर्भरता की अनुपस्थिति को चिह्नित किया और अपने आप में कक्षाओं के समावेश को हटा दिया।
हम देखते हैं कि सभी अंतर्निहित स्वरूपण कक्षाएं (बोल्ड, इटैलिक, ...) एक दूसरे पर और इसके अलावा, लिंक वर्ग पर निर्भर हैं, जो उन पर भी निर्भर है! एक समान स्थिति में Unordered_list और Ordered_list हैं। हेडर को एक-दूसरे में शामिल करने से न केवल उनमें से एक को अनदेखा करना होगा, जैसा कि अपेक्षित होगा, लेकिन प्रीप्रोसेसर द्वारा सत्यापन भी पास नहीं होगा, और एक-तरफा समावेशन हमें क्लास तत्व को खोलने और लिंक को वापस करने के लिए शामिल वर्ग के फ़ंक्शन की घोषणा करने की अनुमति नहीं देगा। कैसे हो? इसके दो तरीके हैं।

एक दूसरे में वर्गों का समावेश


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

लेकिन इस तरह की ट्रिक लिंक क्लास के साथ काम नहीं करेगी, क्योंकि इसमें एक अतिरिक्त फ़ील्ड है - URL स्ट्रिंग। हम दूसरी विधि का उपयोग करेंगे।

क्या हर कोई जानता है कि वर्गों को घोषणाओं और परिभाषाओं में अलग करना C ++ प्रोग्रामिंग में एक अच्छा रूप है? एक्सटेंशन के साथ हेडर में .h या .hpp - घोषणा, एक्सटेंशन के साथ स्रोत में .cpp - परिभाषा, सही? और अब मैं नए लोगों को प्रोग्रामिंग की ओर मोड़ता हूं: बैठ जाओ और अपनी सीट बेल्ट को जकड़ें, क्योंकि यह अप्रिय होगा। आखिरकार, हम एक्सटेंशन के साथ एक फाइल में जो लिखते हैं, वह एक वर्ग परिभाषा से ज्यादा कुछ नहीं है। और .cpp फ़ाइल में, इस वर्ग के तरीकों का कार्यान्वयन पहले से ही है। नहीं समझे? हमें स्कूल में धोखा दिया गया था। एक वर्ग को एक फ़ंक्शन के रूप में घोषित किया जाता है, एक पंक्ति में, यदि इसमें टेम्पलेट नहीं हैं।

यह फ़ंक्शन की तुलना में भी सरल है, क्योंकि इसमें कोई तर्क नहीं है। यहाँ एक विशिष्ट वर्ग की घोषणा है :

 class MyClass; 

और यह बात है! और खेतों और विधियों की घोषणाएं पहले से ही इसकी परिभाषा हैं

हम इसका फायदा उठाएंगे। हम इनलाइन क्लास के शीर्षक को लिंक क्लास के शीर्षक में शामिल करते हैं, और इसमें इनलाइन क्लास को परिभाषित करने से पहले लिंक क्लास को ही घोषित करते हैं। इनलाइन। H फ़ाइल इस तरह दिखनी चाहिए:

 #ifndef INLINE_H #define INLINE_H #include "AST/span.h" #include "AST/text.h" #include "AST/image.h" #include "AST/notification.h" class Link; class Inline : public Span { public: static const unsigned long MAX_CHILDREN_COUNT = 0xFFFFFF; private: Span ** children; unsigned long children_count; unsigned long extended; void extend(); public: Inline(const Node * parent, const Node_type &type); Inline(const Span * span); ~Inline(); Inline * add_text(const string &text); Inline * add_image(const string &src, const string &alt); Inline * add_notification(const string &user); Link * open_link(const string &URL); ... 

इनलाइन वर्ग अभी भी लिंक वर्ग, उसके क्षेत्रों और विधियों के बारे में कुछ भी नहीं जानता है, लेकिन यह अपने अस्तित्व के बारे में निश्चित रूप से जानता है। इसलिए, हम उन तरीकों को घोषित कर सकते हैं जो एक संकेतक को लिंक क्लास के ऑब्जेक्ट पर लौटाते हैं, या इसे एक तर्क के रूप में स्वीकार करते हैं। सूचक शब्द को यादृच्छिक रूप से नहीं चुना गया था , इनलाइन वर्ग को अभी तक पता नहीं है कि प्रकार की वस्तुओं का निर्माण कैसे किया जाता है, क्योंकि इसके निर्माता तक पहुंच नहीं है, लेकिन सभी बिंदुओं के साथ काम कर सकते हैं, क्योंकि वे सभी एक ही इंटरफ़ेस है। लेकिन हमें यहां वस्तुओं की आवश्यकता नहीं है। लेकिन ओपन_लिंक विधि के कार्यान्वयन में, लिंक की एक वस्तु बनाई जाती है और इसे करने के लिए एक संकेतक लौटा दिया जाता है, जिसका अर्थ है कि जब तक प्रीप्रोसेसर इस विधि में प्रवेश करता है, तब तक कंस्ट्रक्टर और अन्य लिंक विधियां जिन्हें ओपन_लिंक विधि की आवश्यकता होती है, घोषित किया जाना चाहिए। यहां हम स्रोत कोड को हेडर और कार्यान्वयन के साथ अलग-अलग फ़ाइलों में विभाजित करने का लाभ उठाते हैं। इनलाइन। H फ़ाइल इनलाइन .pp फ़ाइल ("अंडरक्लाउड") में शामिल है, लेकिन इनलाइन.h फ़ाइल में लिंक शामिल नहीं है। तो, इनलाइन सहित। इसमें प्रीप्रोसेसर के लिए पहला समावेश होगा। फिर inline.cpp फ़ाइल इस तरह शुरू होगी:

 #include "inline.h" #include "link.h" ... 

मैं उपरोक्त सभी को दोहराता हूं। क्लास आह की हेडिंग को क्लास ए के हेडिंग में हमेशा की तरह शामिल किया गया है, और क्लास बी को क्लास ए से पहले घोषित किया जाता है और हम इसकी हेडिंग को स्रोत A.cpp में शामिल करते हैं। मेरी राय में यह तरीका एकमात्र नहीं है, बल्कि सबसे सरल है।

मैं ध्यान देता हूं कि वर्गों का ऐसा पारस्परिक समावेश कक्षा B को वर्ग A से विरासत में लेने से नहीं रोकता है, अगर हमने कक्षा A की परिभाषा से पहले इसकी घोषणा को लिख दिया है। ठीक यही मैंने किया है, Unordered_list से Ordered_list विरासत में मिली।

एक पेड़ का निर्माण


तो, हम एक सार वाक्यविन्यास पेड़ के निर्माण के लिए मिला। अंतिम लेख में, फ़ंक्शन 50 लाइनों में फिट होता है। Spoiler: इस बार यह लगभग 1400 हो गया है। ऑपरेशन का सिद्धांत समान है: हम प्रत्येक टोकन के प्रकार की जांच करते हैं और इसके आधार पर, एक निश्चित अनुभाग को निष्पादित करते हैं, स्मृति में एक खुले पेड़ के नोड को संग्रहीत करते हैं। लेकिन अगर HTML को पार्स करने के लिए लगभग सभी खंडों में एक और केवल तीन आदेश होते हैं: खुले के अंदर एक खाली नोड जोड़ें, खुले में एक नया नोड खोलें और अपने नोड को वापस लौटाएं, इसके अभिभावक को, फिर यहां वांछित कार्रवाई भी खुले नोड के प्रकार पर निर्भर करती है। उदाहरण के लिए, यदि "क्षैतिज रेखा" टोकन प्रसंस्करण में आया था, और खुला नोड दस्तावेज़ रूट है, तो सभी की जरूरत है कि इस खुले नोड में कास्टिंग और सशर्त नाम add_line () के साथ फ़ंक्शन का उपयोग करते हुए एक पंक्ति को जोड़ना है, ऐसा कुछ।

 if (type == Node::ROOT) static_case<Root*>(open_node)->add_line(); 

लेकिन अगर ओपन नोड एक पैराग्राफ (पैराग्राफ) है, तो पहले आपको इसे बंद करने की आवश्यकता है और सभी संभावित पूर्वजों (बुलेटेड और क्रमांकित सूची) जब तक कि ओपन नोड "अनुभाग" प्रकार का नहीं हो जाता है, और तब इसे बंद करें:

 else if (type == Node::PARAGRAPH) { open_node = static_cast<Paragraph*>(open_node)->close(); while (open_node->get_type() != Node::SECTION) { if (open_node->get_type() == Node::UNORDERED_LIST) open_node = static_cast<Unordered_list*>(open_node)->close(); else if (open_node->get_type() == Node::UNORDERED_LIST) open_node = static_cast<Unordered_list*>(open_node)->close(); else if (open_node->get_type() == Node::PARAGRAPH) open_node = static_cast<Paragraph*>(open_node)->close(); } open_node = static_cast<Section*>(open_node)->close(); open_node = tree->add_line(); } 

यदि खुली नोड छवि के लिए एक कैप्शन है, तो क्षैतिज रेखा व्याकरण को पूरी तरह से तोड़ देती है, और एक अपवाद को फेंक दिया जाना चाहिए, और यदि खुला नोड एक लिंक नहीं है, और आने वाला टोकन ">" प्रकार का "LINKFINISH" है, तो इसे लिंक के अंत के रूप में संसाधित नहीं किया जाना चाहिए, लेकिन कैसे पाठ, आदि

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

उसके बाद, हमारे पास पहले से ही ऐसा एक छोटा-पेड़ होगा:

 <article> | +-<section> | +-<h1> | +-"   DOM  " 

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

लेख ही
 @2che >>442964 #[   DOM  ] , !          markdown,       ,   —           « »,     .   ,    ,    , ,  LibreOffice Writer,  %[ ],   — %[].     ,        «parser example», «html to DOM», «how to parse html»  .   ,              ,    ,   flex, bison, llvm  yacc. ,      ,    (gumbo, jsoup, rapidjson,  Qt  .)  ,              C++     ,              .  ,        AST (  ),    ,      ,       .  , —    —       ,       .           .           ,      .    ,    ,     .    HTML,      .  , ,  %[ ] —         .      : 1. *[ ]    —    ,    . 2. *[ ] —        %[  ] (AST — abstract syntax tree),  %[  ] (DOM — document object model).    .  ,     IDE   ,     .   -    — %[ - ()]  %[  -].    ,     .        : > `[<> = <_1> <_> <_2>]       ,    . ,   ,     «»   ..   ?            : %[]  %[]. *[] — ,  : > `[<_1> = <> (<_> | <_>) <>] *[] ,    .      : > `[<> = <_1> "+" <_2> <_1> = <> ("*" | "/") <>]  "+", "*", "/" — .      ,          , —   .       <<https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0>>  <<https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0>>.    —    ,   .          ,     . ,     , ,        .     ,             ,        ,   . ,    .     HTML5   : > `[stub]   ,      (   , ..  ,      ).     :  ,                , ? ,       ,  .  .  ,  disassemble(ifsteam &file)   ,             process(const char &c),    . ,   process   switch,              .     :    switch    ,     .  ,       ,   . ,      : , ,  ,      HTML    ( PHP,   "<?… ?>".        case.   ?    .       (  —  ,      —      ).         (1, 2, 4, 8  .).        : 0001, 0010, 0100  ..,           .      ,  .   : > `[enum Token_type { END = 1, TEXT = 2, OPENING_BLOCK_TAG_NAME = 4, CLOSING_BLOCK_TAG_NAME = 8, EMPTY_TAG_NAME = 16, COMMENT = 32, MACRO_TAG = 64, ATTRIBUTE_NAME = 128, UNQUOTED_ATTRIBUTE_VALUE = 256, SINGLE_QUOTED_ATTRIBUTE_VALUE = 512, DOUBLE_QUOTED_ATTRIBUTE_VALUE = 1024 };]   process: > `[stub]    switch    ( ),    case       .    ,    :     ,      ,      (),   .               .       ()    ,      «»  ..         gedit: [<https://hsto.org/webt/72/fw/tw/72fwtwt_waeie4ulzftkxua356w.png>]     ,           .     disassemble: > `[stub]        TEXT,       END    ( ,  ).         HTML-  ,    - PHP,         "[ "<_>": <_> ]".   : > =[ `[stub]] =[ `[stub]]        —   .     ,             -.         DOM,    .        HTML-?   —      ,         ,     —   «Node»,     «Block» (,     )       «Root».      ,    , ,  <p>, <li>, <strong>  ,      .    .      ,    —            :     ,     ,    .   ,   ,    Node,   ,    .    %[  ].  : > `[stub]   !     ,      : `[| +--<ROOT> | +--<!DOCTYPE> | +--<html> | +--<head> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<meta> | | | +--<title> | | | +--<link> | | | +--<link> | | | +--<COMMENT> | +--<body> | +--<header> | | | +--<div> | +--<nav> | | | +--<ul> | | | +--<li> | | | | | +--<a> | | | +--<li> | | | | | +--<a> | | | +--<li> | | | +--<a> | +--<main> | | | +--<MACRO> | +--<footer> | +--<hr> | +--<small>] ,       DOM,   jQuery, Jsoup, beautifulsoup  Gumbo   ,   ,       ,     <style>  <script>,      .   ,     . . PS     <<https://gitlab.com/2che/nyHTML>>. , ,      . 

 0: ["2che": अधिसूचना]
1: ["
": NEWLINE]
2: ["442964": CITE]
3: ["# [": TITLE_START]
4: ["द आर्ट ऑफ पार्सिंग या डू-इट-योरसेल्फ डोम": पाठ]
5: ["]": SPAN_OR_IMAGE_FINISH]
6: ["

": DOUBLE_NEWLINE]
7: [ ", !          markdown,       ,   —           « »,     .   ,    ,    , ,  LibreOffice Writer,  " : TEXT ]
8: [ "%[" : ITALIC_START ]
9: [ " " : TEXT ]
10: [ "]" : SPAN_OR_IMAGE_FINISH ]
11: [ ",   — " : TEXT ]
12: [ "%[" : ITALIC_START ]
13: [ "" : TEXT ]
14: [ "]" : SPAN_OR_IMAGE_FINISH ]
15: [ ".     ,        «parser example», «html to DOM», «how to parse html»  .   ,              ,    ,   flex, bison, llvm  yacc. ,      ,    (gumbo, jsoup, rapidjson,  Qt  .)  ,              C++     ,              .  ,        AST (  ),    ,      ,       ." : TEXT ]
16: [ "

" : DOUBLE_NEWLINE ]
17: [ " , —    —       ,       .           .           ,      .    ,    ,     .    HTML,      ." : TEXT ]
18: [ "

" : DOUBLE_NEWLINE ]
19: [ " , ,  " : TEXT ]
20: [ "%[" : ITALIC_START ]
21: [ " " : TEXT ]
22: [ "]" : SPAN_OR_IMAGE_FINISH ]
23: [ " —         .      :" : TEXT ]
24: [ "
" : NEWLINE ]
25: [ "1. " : ORDERED_LIST_ITEM_MARKER ]
26: [ "*[" : BOLD_START ]
27: [ " " : TEXT ]
28: [ "]" : SPAN_OR_IMAGE_FINISH ]
29: [ "    —    ,    ." : TEXT ]
30: [ "
" : NEWLINE ]
31: [ "2. " : ORDERED_LIST_ITEM_MARKER ]
32: [ "*[" : BOLD_START ]
33: [ " " : TEXT ]
34: [ "]" : SPAN_OR_IMAGE_FINISH ]
35: [ " —        " : TEXT ]
36: [ "%[" : ITALIC_START ]
37: [ "  " : TEXT ]
38: [ "]" : SPAN_OR_IMAGE_FINISH ]
39: [ " (AST — abstract syntax tree),  " : TEXT ]
40: [ "%[" : ITALIC_START ]
41: [ "  " : TEXT ]
42: [ "]" : SPAN_OR_IMAGE_FINISH ]
43: [ " (DOM — document object model)." : TEXT ]
44: [ "

" : DOUBLE_NEWLINE ]
45: [ "   .  ,     IDE   ,     .   -    — " : TEXT ]
46: [ "%[" : ITALIC_START ]
47: [ " - ()" : TEXT ]
48: [ "]" : SPAN_OR_IMAGE_FINISH ]
49: [ "  " : TEXT ]
50: [ "%[" : ITALIC_START ]
51: [ "  -" : TEXT ]
52: [ "]" : SPAN_OR_IMAGE_FINISH ]
53: [ ".    ,     .        :" : TEXT ]
54: [ "
" : NEWLINE ]
55: [ "> " : QUOTE_START ]
56: [ "`[" : MONOSPACE_START ]
57: [ "<" : TEXT ]
58: [ ">" : LINK_FINISH ]
59: [ " = <_1" : TEXT ]
60: [ ">" : LINK_FINISH ]
61: [ " <_" : TEXT ]
62: [ ">" : LINK_FINISH ]
63: [ " <_2" : TEXT ]
64: [ ">" : LINK_FINISH ]
65: [ "]" : SPAN_OR_IMAGE_FINISH ]
66: [ "

" : DOUBLE_NEWLINE ]
67: [ "      ,    . ,   ,     «»   .." : TEXT ]
68: [ "

" : DOUBLE_NEWLINE ]
69: [ "  ?" : TEXT ]
70: [ "

" : DOUBLE_NEWLINE ]
71: [ "           : " : TEXT ]
72: [ "%[" : ITALIC_START ]
73: [ "" : TEXT ]
74: [ "]" : SPAN_OR_IMAGE_FINISH ]
75: [ "  " : TEXT ]
76: [ "%[" : ITALIC_START ]
77: [ "" : TEXT ]
78: [ "]" : SPAN_OR_IMAGE_FINISH ]
79: [ ". " : TEXT ]
80: [ "*[" : BOLD_START ]
81: [ "" : TEXT ]
82: [ "]" : SPAN_OR_IMAGE_FINISH ]
83: [ " — ,  :" : TEXT ]
84: [ "
" : NEWLINE ]
85: [ "> " : QUOTE_START ]
86: [ "`[" : MONOSPACE_START ]
87: [ "<_1" : TEXT ]
88: [ ">" : LINK_FINISH ]
89: [ " = <" : TEXT ]
90: [ ">" : LINK_FINISH ]
91: [ " (<_" : TEXT ]
92: [ ">" : LINK_FINISH ]
93: [ " | <_" : TEXT ]
94: [ ">" : LINK_FINISH ]
95: [ ") <" : TEXT ]
96: [ ">" : LINK_FINISH ]
97: [ "]" : SPAN_OR_IMAGE_FINISH ]
98: [ "

" : DOUBLE_NEWLINE ]
99: [ "*[" : BOLD_START ]
100: [ "" : TEXT ]
101: [ "]" : SPAN_OR_IMAGE_FINISH ]
102: [ " ,    .      :" : TEXT ]
103: [ "
" : NEWLINE ]
104: [ "> " : QUOTE_START ]
105: [ "`[" : MONOSPACE_START ]
106: [ "<" : TEXT ]
107: [ ">" : LINK_FINISH ]
108: [ " = <_1" : TEXT ]
109: [ ">" : LINK_FINISH ]
110: [ " "+" <_2" : TEXT ]
111: [ ">" : LINK_FINISH ]
112: [ "
" : NEWLINE ]
113: [ "<_1" : TEXT ]
114: [ ">" : LINK_FINISH ]
115: [ " = <" : TEXT ]
116: [ ">" : LINK_FINISH ]
117: [ " ("*" | "/") <" : TEXT ]
118: [ ">" : LINK_FINISH ]
119: [ "]" : SPAN_OR_IMAGE_FINISH ]
120: [ "

" : DOUBLE_NEWLINE ]
121: [ " "+", "*", "/" — ." : TEXT ]
122: [ "
" : NEWLINE ]
123: [ "     ,          , —   ." : TEXT ]
124: [ "

" : DOUBLE_NEWLINE ]
125: [ "      " : TEXT ]
126: [ "<<" : LINK_START ]
127: [ "https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0" : TEXT ]
128: [ ">" : LINK_FINISH ]
129: [ "" : TEXT ]
130: [ ">" : LINK_FINISH ]
131: [ "  " : TEXT ]
132: [ "<<" : LINK_START ]
133: [ "https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0" : TEXT ]
134: [ ">" : LINK_FINISH ]
135: [ "" : TEXT ]
136: [ ">" : LINK_FINISH ]
137: [ ".    —    ,   .          ,     . ,     , ,        .     ,             ,        ,   . ,    .     HTML5   :" : TEXT ]
138: [ "
" : NEWLINE ]
139: [ "> " : QUOTE_START ]
140: [ "`[" : MONOSPACE_START ]
141: [ "stub" : TEXT ]
142: [ "]" : SPAN_OR_IMAGE_FINISH ]
143: [ "

" : DOUBLE_NEWLINE ]
144: [ "  ,      (   , ..  ,      ).     :  ,                , ? ,       ,  .  .  ,  disassemble(ifsteam &file)   ,             process(const char &c),    . ,   process   switch,              .     :    switch    ,     .  ,       ,   . ,      : , ,  ,      HTML    ( PHP,   "<?… ?" : TEXT ]
145: [ ">" : LINK_FINISH ]
146: [ "".        case.   ?    .       (  —  ,      —      ).         (1, 2, 4, 8  .).        : 0001, 0010, 0100  ..,           .      ,  .   :" : TEXT ]
147: [ "
" : NEWLINE ]
148: [ "> " : QUOTE_START ]
149: [ "`[" : MONOSPACE_START ]
150: [ "enum Token_type {" : TEXT ]
151: [ "
" : NEWLINE ]
152: [ " END = 1, TEXT = 2," : TEXT ]
153: [ "
" : NEWLINE ]
154: [ " OPENING_BLOCK_TAG_NAME = 4, CLOSING_BLOCK_TAG_NAME = 8, EMPTY_TAG_NAME = 16, COMMENT = 32, MACRO_TAG = 64," : TEXT ]
155: [ "
" : NEWLINE ]
156: [ " ATTRIBUTE_NAME = 128, UNQUOTED_ATTRIBUTE_VALUE = 256, SINGLE_QUOTED_ATTRIBUTE_VALUE = 512, DOUBLE_QUOTED_ATTRIBUTE_VALUE = 1024" : TEXT ]
157: [ "
" : NEWLINE ]
158: [ "};" : TEXT ]
159: [ "]" : SPAN_OR_IMAGE_FINISH ]
160: [ "

" : DOUBLE_NEWLINE ]
161: [ "  process:" : TEXT ]
162: [ "
" : NEWLINE ]
163: [ "> " : QUOTE_START ]
164: [ "`[" : MONOSPACE_START ]
165: [ "stub" : TEXT ]
166: [ "]" : SPAN_OR_IMAGE_FINISH ]
167: [ "

" : DOUBLE_NEWLINE ]
168: [ "   switch    ( ),    case       .    ,    :     ,      ,      (),   .               .       ()    ,      «»  ..         gedit:" : TEXT ]
169: [ "
" : NEWLINE ]
170: [ "[<" : IMAGE_START ]
171: [ "https://hsto.org/webt/72/fw/tw/72fwtwt_waeie4ulzftkxua356w.png" : TEXT ]
172: [ ">" : LINK_FINISH ]
173: [ "]" : SPAN_OR_IMAGE_FINISH ]
174: [ "

" : DOUBLE_NEWLINE ]
175: [ "    ,           .     disassemble:" : TEXT ]
176: [ "
" : NEWLINE ]
177: [ "> " : QUOTE_START ]
178: [ "`[" : MONOSPACE_START ]
179: [ "stub" : TEXT ]
180: [ "]" : SPAN_OR_IMAGE_FINISH ]
181: [ "

" : DOUBLE_NEWLINE ]
182: [ "       TEXT,       END    ( ,  )." : TEXT ]
183: [ "

" : DOUBLE_NEWLINE ]
184: [ "        HTML-  ,    - PHP,         "[ "<_" : TEXT ]
185: [ ">" : LINK_FINISH ]
186: [ "": <_" : TEXT ]
187: [ ">" : LINK_FINISH ]
188: [ " " : TEXT ]
189: [ "]" : SPAN_OR_IMAGE_FINISH ]
190: [ "".   :" : TEXT ]
191: [ "
" : NEWLINE ]
192: [ "> " : QUOTE_START ]
193: [ "=[" : MARKED_START ]
194: [ " " : TEXT ]
195: [ "`[" : MONOSPACE_START ]
196: [ "stub" : TEXT ]
197: [ "]" : SPAN_OR_IMAGE_FINISH ]
198: [ "]" : SPAN_OR_IMAGE_FINISH ]
199: [ "
" : NEWLINE ]
200: [ "=[" : MARKED_START ]
201: [ " " : TEXT ]
202: [ "`[" : MONOSPACE_START ]
203: [ "stub" : TEXT ]
204: [ "]" : SPAN_OR_IMAGE_FINISH ]
205: [ "]" : SPAN_OR_IMAGE_FINISH ]
206: [ "

" : DOUBLE_NEWLINE ]
207: [ "       —   .     ,             -.         DOM,    ." : TEXT ]
208: [ "

" : DOUBLE_NEWLINE ]
209: [ "       HTML-?" : TEXT ]
210: [ "

" : DOUBLE_NEWLINE ]
211: [ "  —      ,         ,     —   «Node»,     «Block» (,     )       «Root».      ,    , ,  <p" : TEXT ]
212: [ ">" : LINK_FINISH ]
213: [ ", <li" : TEXT ]
214: [ ">" : LINK_FINISH ]
215: [ ", <strong" : TEXT ]
216: [ ">" : LINK_FINISH ]
217: [ "  ,      .    .      ,    —            :     ,     ,    .   ,   ,    Node,   ,    .    " : TEXT ]
218: [ "%[" : ITALIC_START ]
219: [ "  " : TEXT ]
220: [ "]" : SPAN_OR_IMAGE_FINISH ]
221: [ "." : TEXT ]
222: [ "

" : DOUBLE_NEWLINE ]
223: [ " :" : TEXT ]https://gitlab.com/2che/markedit
224: [ "
" : NEWLINE ]
225: [ "> " : QUOTE_START ]
226: [ "`[" : MONOSPACE_START ]
227: [ "stub" : TEXT ]
228: [ "]" : SPAN_OR_IMAGE_FINISH ]
229: [ "

" : DOUBLE_NEWLINE ]
230: [ "  !     ,      :" : TEXT ]
231: [ "
" : NEWLINE ]
232: [ "`[" : MONOSPACE_START ]
233: [ "| " : TEXT ]
234: [ "
" : NEWLINE ]
235: [ "+--<ROOT" : TEXT ]
236: [ ">" : LINK_FINISH ]
237: [ "
" : NEWLINE ]
238: [ " | " : TEXT ]
239: [ "
" : NEWLINE ]
240: [ " +--<!DOCTYPE" : TEXT ]
241: [ ">" : LINK_FINISH ]
242: [ "
" : NEWLINE ]
243: [ " | " : TEXT ]
244: [ "
" : NEWLINE ]
245: [ " +--<html" : TEXT ]
246: [ ">" : LINK_FINISH ]
247: [ "
" : NEWLINE ]
248: [ " | " : TEXT ]
249: [ "
" : NEWLINE ]
250: [ " +--<head" : TEXT ]
251: [ ">" : LINK_FINISH ]
252: [ "
" : NEWLINE ]
253: [ " | | " : TEXT ]
254: [ "
" : NEWLINE ]
255: [ " | +--<meta" : TEXT ]
256: [ ">" : LINK_FINISH ]
257: [ "
" : NEWLINE ]
258: [ " | | " : TEXT ]
259: [ "
" : NEWLINE ]
260: [ " | +--<meta" : TEXT ]
261: [ ">" : LINK_FINISH ]
262: [ "
" : NEWLINE ]
263: [ " | | " : TEXT ]
264: [ "
" : NEWLINE ]
265: [ " | +--<meta" : TEXT ]
266: [ ">" : LINK_FINISH ]
267: [ "
" : NEWLINE ]
268: [ " | | " : TEXT ]
269: [ "
" : NEWLINE ]
270: [ " | +--<meta" : TEXT ]
271: [ ">" : LINK_FINISH ]
272: [ "
" : NEWLINE ]
273: [ " | | " : TEXT ]
274: [ "
" : NEWLINE ]
275: [ " | +--<meta" : TEXT ]
276: [ ">" : LINK_FINISH ]
277: [ "
" : NEWLINE ]
278: [ " | | " : TEXT ]
279: [ "
" : NEWLINE ]
280: [ " | +--<meta" : TEXT ]
281: [ ">" : LINK_FINISH ]
282: [ "
" : NEWLINE ]
283: [ " | | " : TEXT ]
284: [ "
" : NEWLINE ]
285: [ " | +--<meta" : TEXT ]
286: [ ">" : LINK_FINISH ]
287: [ "
" : NEWLINE ]
288: [ " | | " : TEXT ]
289: [ "
" : NEWLINE ]
290: [ " | +--<meta" : TEXT ]
291: [ ">" : LINK_FINISH ]
292: [ "
" : NEWLINE ]
293: [ " | | " : TEXT ]
294: [ "
" : NEWLINE ]
295: [ " | +--<meta" : TEXT ]
296: [ ">" : LINK_FINISH ]
297: [ "
" : NEWLINE ]
298: [ " | | " : TEXT ]
299: [ "
" : NEWLINE ]
300: [ " | +--<title" : TEXT ]
301: [ ">" : LINK_FINISH ]
302: [ "
" : NEWLINE ]
303: [ " | | " : TEXT ]
304: [ "
" : NEWLINE ]
305: [ " | +--<link" : TEXT ]
306: [ ">" : LINK_FINISH ]
307: [ "
" : NEWLINE ]
308: [ " | | " : TEXT ]
309: [ "
" : NEWLINE ]
310: [ " | +--<link" : TEXT ]
311: [ ">" : LINK_FINISH ]
312: [ "
" : NEWLINE ]
313: [ " | | " : TEXT ]
314: [ "
" : NEWLINE ]
315: [ " | +--<COMMENT" : TEXT ]
316: [ ">" : LINK_FINISH ]
317: [ "
" : NEWLINE ]
318: [ " | " : TEXT ]
319: [ "
" : NEWLINE ]
320: [ " +--<body" : TEXT ]
321: [ ">" : LINK_FINISH ]
322: [ "
" : NEWLINE ]
323: [ " | " : TEXT ]
324: [ "
" : NEWLINE ]
325: [ " +--<header" : TEXT ]
326: [ ">" : LINK_FINISH ]
327: [ "
" : NEWLINE ]
328: [ " | | " : TEXT ]
329: [ "
" : NEWLINE ]
330: [ " | +--<div" : TEXT ]
331: [ ">" : LINK_FINISH ]
332: [ "
" : NEWLINE ]
333: [ " | " : TEXT ]
334: [ "
" : NEWLINE ]
335: [ " +--<nav" : TEXT ]
336: [ ">" : LINK_FINISH ]
337: [ "
" : NEWLINE ]
338: [ " | | " : TEXT ]
339: [ "
" : NEWLINE ]
340: [ " | +--<ul" : TEXT ]
341: [ ">" : LINK_FINISH ]
342: [ "
" : NEWLINE ]
343: [ " | | " : TEXT ]
344: [ "
" : NEWLINE ]
345: [ " | +--<li" : TEXT ]
346: [ ">" : LINK_FINISH ]
347: [ "
" : NEWLINE ]
348: [ " | | | " : TEXT ]
349: [ "
" : NEWLINE ]
350: [ " | | +--<a" : TEXT ]
351: [ ">" : LINK_FINISH ]
352: [ "
" : NEWLINE ]
353: [ " | | " : TEXT ]
354: [ "
" : NEWLINE ]
355: [ " | +--<li" : TEXT ]
356: [ ">" : LINK_FINISH ]
357: [ "
" : NEWLINE ]
358: [ " | | | " : TEXT ]
359: [ "
" : NEWLINE ]
360: [ " | | +--<a" : TEXT ]
361: [ ">" : LINK_FINISH ]
362: [ "
" : NEWLINE ]
363: [ " | | " : TEXT ]
364: [ "
" : NEWLINE ]
365: [ " | +--<li" : TEXT ]
366: [ ">" : LINK_FINISH ]
367: [ "
" : NEWLINE ]
368: [ " | | " : TEXT ]
369: [ "
" : NEWLINE ]
370: [ " | +--<a" : TEXT ]
371: [ ">" : LINK_FINISH ]
372: [ "
" : NEWLINE ]
373: [ " | " : TEXT ]
374: [ "
" : NEWLINE ]
375: [ " +--<main" : TEXT ]
376: [ ">" : LINK_FINISH ]
377: [ "
" : NEWLINE ]
378: [ " | | " : TEXT ]
379: [ "
" : NEWLINE ]
380: [ " | +--<MACRO" : TEXT ]
381: [ ">" : LINK_FINISH ]
382: [ "
" : NEWLINE ]
383: [ " | " : TEXT ]
384: [ "
" : NEWLINE ]
385: [ " +--<footer" : TEXT ]
386: [ ">" : LINK_FINISH ]
387: [ "
" : NEWLINE ]
388: [ " | " : TEXT ]
389: [ "
" : NEWLINE ]
390: [ " +--<hr" : TEXT ]
391: [ ">" : LINK_FINISH ]
392: [ "
" : NEWLINE ]
393: [ " | " : TEXT ]
394: [ "
" : NEWLINE ]
395: [ " +--<small" : TEXT ]
396: [ ">" : LINK_FINISH ]
397: [ "]" : SPAN_OR_IMAGE_FINISH ]
398: [ "
" : NEWLINE ]
399: [ " " : TEXT ]
400: [ "
" : NEWLINE ]
401: [ ",       DOM,   jQuery, Jsoup, beautifulsoup  Gumbo   ,   ,       ,     <style" : TEXT ]
402: [ ">" : LINK_FINISH ]
403: [ "  <script" : TEXT ]
404: [ ">" : LINK_FINISH ]
405: [ ",      .   ,     . ." : TEXT ]
406: [ "

" : DOUBLE_NEWLINE ]
407: [ "PS     " : TEXT ]
408: [ "<<" : LINK_START ]
409: [ "https://gitlab.com/2che/nyHTML" : TEXT ]
410: [ ">" : LINK_FINISH ]
411: [ "" : TEXT ]
412: [ ">" : LINK_FINISH ]
413: [ ". , ,      ." : TEXT ]
414: [ "
" : NEWLINE ]
415: [ "" : END ]


 <pre><article> | +-<section> | +-<p> | | | +-@2che | | | +-"\n" | +->>442964 | +-<h1> | | | +-"   DOM  " | +-<p> | | | +-", !       ..." | | | +-<i> | | | | | +-" " | | | +-",   — " | | | +-<i> | | | | | +-"" | | | +-".     ,   ..." | +-<p> | | | +-" , —    —   ..." | +-<p> | | | +-" , ,  " | | | +-<i> | | | | | +-" " | | | +-" —        ..." | | | +-"\n" | | | +-<b> | | | | | +-" " | | | +-"    —    ,  ..." | | | +-"\n" | | | +-<b> | | | | | +-" " | | | +-" —        " | | | +-<i> | | | | | +-"  " | | | +-" (AST — abstract syntax tree),  " | | | +-<i> | | | | | +-"  " | | | +-" (DOM — document object model)." | +-<p> | | | +-"   .  ,     ..." | | | +-<i> | | | | | +-" - ()" | | | +-"  " | | | +-<i> | | | | | +-"  -" | | | +-".    ,     .  ..." | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"<" | | | +-">" | | | +-" = <_1" | | | +-">" | | | +-" <_" | | | +-">" | | | +-" <_2" | | | +-">" | +-<p> | | | +-"      , ..." | +-<p> | | | +-"  ?" | +-<p> | | | +-"      ..." | | | +-<i> | | | | | +-"" | | | +-"  " | | | +-<i> | | | | | +-"" | | | +-". " | | | +-<b> | | | | | +-"" | | | +-" — ,  :" | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"<_1" | | | +-">" | | | +-" = <" | | | +-">" | | | +-" (<_" | | | +-">" | | | +-" | <_" | | | +-">" | | | +-") <" | | | +-">" | +-<p> | | | +-<b> | | | | | +-"" | | | +-" ,    .   ..." | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"<" | | | +-">" | | | +-" = <_1" | | | +-">" | | | +-" "+" <_2" | | | +-">" | | | +-"\n" | | | +-"<_1" | | | +-">" | | | +-" = <" | | | +-">" | | | +-" ("*" | "/") <" | | | +-">" | +-<p> | | | +-" "+", "*", "/" — ." | | | +-"\n" | | | +-"     ,  ..." | +-<p> | | | +-"      " | | | +-<a> | | | | | +-"" | | | +-"  " | | | +-<a> | | | | | +-"" | | | +-".    —    ..." | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"  ,     ..." | | | +-">" | | | +-"".        case.   ..." | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"enum Token_type {" | | | +-"\n" | | | +-" END = 1, TEXT = 2," | | | +-"\n" | | | +-" OPENING_BLOCK_TAG_NAME = 4, CLOSING_BLOCK_TAG_NAME = 8, EMPTY_TAG_NAME = 16, COMMENT = 32, MACRO..." | | | +-"\n" | | | +-" ATTRIBUTE_NAME = 128, UNQUOTED_ATTRIBUTE_VALUE = 256, SINGLE_QUOTED_ATTRIBUTE_VALUE = 512, DOUBL..." | | | +-"\n" | | | +-"};" | +-<p> | | | +-"  process:" | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"   switch    (  ..." | | | +-"\n" | +-<p> | | | +-<img /> | +-<p> | | | +-"    ,   ..." | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"      ..." | +-<p> | | | +-"        HTML- ..." | | | +-">" | | | +-"": <_" | | | +-">" | | | +-" " | | | +-"]" | | | +-"".   :" | | | +-"\n" | +-<blockquote> | | | +-<mark> | | | | | +-" " | | | | | +-<pre> | | | | | +-"stub" | | | +-"\n" | | | +-<mark> | | | +-" " | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"       —  ..." | +-<p> | | | +-"       HTML-..." | +-<p> | | | +-"  —      ,  ..." | | | +-">" | | | +-", <li" | | | +-">" | | | +-", <strong" | | | +-">" | | | +-"  ,      .  ..." | | | +-<i> | | | | | +-"  " | | | +-"." | +-<p> | | | +-" :" | | | +-"\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"  !     ,   ..." | | | +-"\n" | | | +-<pre> | | | | | +-"| " | | | | | +-"\n" | | | | | +-"+--<ROOT" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<!DOCTYPE" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<html" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<head" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<meta" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<title" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<link" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<link" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<COMMENT" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<body" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<header" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<div" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<nav" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<ul" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<li" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | | " | | | | | +-"\n" | | | | | +-" | | +--<a" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<li" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | | " | | | | | +-"\n" | | | | | +-" | | +--<a" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<li" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<a" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<main" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | | " | | | | | +-"\n" | | | | | +-" | +--<MACRO" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<footer" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<hr" | | | | | +-">" | | | | | +-"\n" | | | | | +-" | " | | | | | +-"\n" | | | | | +-" +--<small" | | | | | +-">" | | | +-"\n" | | | +-" " | | | +-"\n" | | | +-",       ..." | | | +-">" | | | +-"  <script" | | | +-">" | | | +-",      .    ..." | +-<p> | +-"PS     " | +-<a> | | | +-"" | +-". , ,     ..." | +-"\n" </pre> 

, , , . , , , , . , .., . , , ,

:
 <pre><article> | +-<section> | +-<p> | | | +-@2che | | | +-"\n" | +->>442964 | +-<h1> | | | +-"   DOM  " | +-<p> | | | +-", !       ..." | | | +-<i> | | | | | +-" " | | | +-",   — " | | | +-<i> | | | | | +-"" | | | +-".     ,   ..." | +-<p> | | | +-" , —    —   ..." | +-<p> | | | +-" , ,  " | | | +-<i> | | | | | +-" " | | | +-" —        ..." | | | +-<b> | | | | | +-" " | | | +-"    —    ,  ..." | | | +-<b> | | | | | +-" " | | | +-" —        " | | | +-<i> | | | | | +-"  " | | | +-" (AST — abstract syntax tree),  " | | | +-<i> | | | | | +-"  " | | | +-" (DOM — document object model)." | +-<p> | | | +-"   .  ,     ..." | | | +-<i> | | | | | +-" - ()" | | | +-"  " | | | +-<i> | | | | | +-"  -" | | | +-".    ,     .  ..." | +-<blockquote> | | | +-<pre> | | | +-"<> = <_1> <_> <_2>" | +-<p> | | | +-"      , ..." | +-<p> | | | +-"  ?" | +-<p> | | | +-"      ..." | | | +-<i> | | | | | +-"" | | | +-"  " | | | +-<i> | | | | | +-"" | | | +-". " | | | +-<b> | | | | | +-"" | | | +-" — ,  :\n" | +-<blockquote> | | | +-<pre> | | | +-"<_1> = <> (<_> | <_>) < ..." | +-<p> | | | +-<b> | | | | | +-"" | | | +-" ,    .   ..." | +-<blockquote> | | | +-<pre> | | | +-"<> = <_1> "+" <_2>\n<_1> = <..." | +-<p> | | | +-" "+", "*", "/" — .\n    ..." | +-<p> | | | +-"      " | | | +-<a> | | | | | +-"" | | | +-"  " | | | +-<a> | | | | | +-"" | | | +-".    —    ..." | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"  ,     ..." | +-<blockquote> | | | +-<pre> | | | +-"enum Token_type {\n END = 1, TEXT = 2,\n OPENING_BLOCK_TAG_NAME = 4, CLOSING_BLOCK_TAG_NAME = ..." | +-<p> | | | +-"  process:\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"   switch    (  ..." | +-<p> | | | +-<img /> | +-<p> | | | +-"    ,   ..." | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"      ..." | +-<p> | | | +-"        HTML- ..." | +-<blockquote> | | | +-<mark> | | | | | +-" " | | | | | +-<pre> | | | | | +-"stub" | | | +-"\n" | | | +-<mark> | | | +-" " | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"       —  ..." | +-<p> | | | +-"       HTML-..." | +-<p> | | | +-"  —      ,  ..." | | | +-<i> | | | | | +-"  " | | | +-"." | +-<p> | | | +-" :\n" | +-<blockquote> | | | +-<pre> | | | +-"stub" | +-<p> | | | +-"  !     ,   ..." | | | +-<pre> | | | | | +-"| \n+--<ROOT>\n | \n +--<!DOCTYPE>\n | \n +--<html>\n | \n +--<head>\n | | \n | +--<..." | | | +-"\n \n,     ..." | +-<p> | +-"PS     " | +-<a> | | | +-"" | +-". , ,     ..." </pre> 

— HTML-. : ( html body, head) . : to_HTML() , , , , . , , Inline ( ):
 string Inline::to_HTML (const unsigned int &level) { string HTML; // ******    -   ****** switch (type) { case BOLD: { HTML.append("<b>"); break; } case ITALIC: { HTML.append("<i>"); break; } case UNDERLINED: { HTML.append("<ins>"); break; } case OVERLINED: { HTML.append("<span class=\"overlined\">"); break; } case THROWLINED: { HTML.append("<del>"); break; } case SUBSCRIPT: { HTML.append("<sub>"); break; } case SUPERSCRIPT: { HTML.append("<sup>"); break; } case MARKED: { HTML.append("<mark>"); break; } case MONOSPACE: { HTML.append("<pre>"); break; } default: throw string("invalid inline type: " + type_str() + "!"); } // *** *** *** *** // ******   -    ****** for (unsigned long i(0); i < children_count; i++) HTML.append(children[i]->to_HTML(level+1)); // *** *** *** *** // ******    -   ****** switch (type) { case BOLD: { HTML.append("</b>"); break; } case ITALIC: { HTML.append("</i>"); break; } case UNDERLINED: { HTML.append("</ins>"); break; } case OVERLINED: { HTML.append("</span>"); break; } case THROWLINED: { HTML.append("</del>"); break; } case SUBSCRIPT: { HTML.append("</sub>"); break; } case SUPERSCRIPT: { HTML.append("</sup>"); break; } case MARKED: { HTML.append("</mark>"); break; } case MONOSPACE: { HTML.append("</pre>"); break; } default: throw string("invalid inline type: " + type_str() + "!"); } // *** *** *** *** return HTML; } 

वह सब है। , , , . — . . .

PS . : — ("\"), , true, . , , , "[", , . false .

Source: https://habr.com/ru/post/hi444876/


All Articles