मेरे पास मार्कअप भाषा है जो मार्कडाउन के समान है और एसओ द्वारा उपयोग की जाने वाली एक है।मार्कडाउन जैसी भाषा के लिए पार्सर लागू करना
विरासत पार्सर रेगेक्स पर आधारित था और बनाए रखने के लिए पूरी दुःस्वप्न था, इसलिए मैं अपने स्वयं के समाधान के साथ ईबीएनएफ व्याकरण के आधार पर आया हूं और एमएक्सटीक्स्टटूल/सरलपार्स के माध्यम से लागू किया गया है।
हालांकि, कुछ टोकन के साथ समस्याएं हैं जिनमें एक-दूसरे को शामिल किया जा सकता है, और मुझे ऐसा करने का 'सही' तरीका नहीं दिख रहा है।
newline := "\r\n"/"\n"/"\r"
indent := ("\r\n"/"\n"/"\r"), [ \t]
number := [0-9]+
whitespace := [ \t]+
symbol_mark := [*_>#`%]
symbol_mark_noa := [_>#`%]
symbol_mark_nou := [*>#`%]
symbol_mark_nop := [*_>#`]
punctuation := [\(\)\,\.\!\?]
noaccent_code := -(newline/'`')+
accent_code := -(newline/'``')+
symbol := -(whitespace/newline)
text := -newline+
safe_text := -(newline/whitespace/[*_>#`]/'%%'/punctuation)+/whitespace
link := 'http'/'ftp', 's'?, '://', (-[ \t\r\n<>`^'"*\,\.\!\?]/([,\.\?],?-[ \t\r\n<>`^'"*]))+
strikedout := -[ \t\r\n*_>#`^]+
ctrlw := '^W'+
ctrlh := '^H'+
strikeout := (strikedout, (whitespace, strikedout)*, ctrlw)/(strikedout, ctrlh)
strong := ('**', (inline_nostrong/symbol), (inline_safe_nostrong/symbol_mark_noa)* , '**')/('__' , (inline_nostrong/symbol), (inline_safe_nostrong/symbol_mark_nou)*, '__')
emphasis := ('*',?-'*', (inline_noast/symbol), (inline_safe_noast/symbol_mark_noa)*, '*')/('_',?-'_', (inline_nound/symbol), (inline_safe_nound/symbol_mark_nou)*, '_')
inline_code := ('`' , noaccent_code , '`')/('``' , accent_code , '``')
inline_spoiler := ('%%', (inline_nospoiler/symbol), (inline_safe_nop/symbol_mark_nop)*, '%%')
inline := (inline_code/inline_spoiler/strikeout/strong/emphasis/link)
inline_nostrong := (?-('**'/'__'),(inline_code/reference/signature/inline_spoiler/strikeout/emphasis/link))
inline_nospoiler := (?-'%%',(inline_code/emphasis/strikeout/emphasis/link))
inline_noast := (?-'*',(inline_code/inline_spoiler/strikeout/strong/link))
inline_nound := (?-'_',(inline_code/inline_spoiler/strikeout/strong/link))
inline_safe := (inline_code/inline_spoiler/strikeout/strong/emphasis/link/safe_text/punctuation)+
inline_safe_nostrong := (?-('**'/'__'),(inline_code/inline_spoiler/strikeout/emphasis/link/safe_text/punctuation))+
inline_safe_noast := (?-'*',(inline_code/inline_spoiler/strikeout/strong/link/safe_text/punctuation))+
inline_safe_nound := (?-'_',(inline_code/inline_spoiler/strikeout/strong/link/safe_text/punctuation))+
inline_safe_nop := (?-'%%',(inline_code/emphasis/strikeout/strong/link/safe_text/punctuation))+
inline_full := (inline_code/inline_spoiler/strikeout/strong/emphasis/link/safe_text/punctuation/symbol_mark/text)+
line := newline, ?-[ \t], inline_full?
sub_cite := whitespace?, ?-reference, '>'
cite := newline, whitespace?, '>', sub_cite*, inline_full?
code := newline, [ \t], [ \t], [ \t], [ \t], text
block_cite := cite+
block_code := code+
all := (block_cite/block_code/line/code)+
सबसे पहले समस्या है, स्पॉइलर, मजबूत और जोर मनमाना क्रम में एक दूसरे को शामिल कर सकते हैं:
यहाँ मेरी व्याकरण का हिस्सा है। और यह संभव है कि बाद में मुझे ऐसे इनलाइन मार्कअप की आवश्यकता होगी।
मेरे वर्तमान समाधान में प्रत्येक संयोजन (inline_noast, inline_nostrong, आदि) के लिए अलग टोकन बनाना शामिल है, लेकिन जाहिर है, ऐसे संयोजनों की संख्या मार्कअप तत्वों की बढ़ती संख्या के साथ बहुत तेजी से बढ़ती है।
दूसरी समस्या यह है कि मजबूत/जोर से इन लुकहेड व्यवहार __._.__*__.__...___._.____.__**___***
(यादृच्छिक रूप से चिह्नित मार्कअप प्रतीकों) के खराब मार्कअप के कुछ मामलों पर बहुत खराब हैं। ऐसे यादृच्छिक पाठ के कुछ केबी को पार्स करने में कुछ मिनट लगते हैं।
क्या यह मेरे व्याकरण के साथ कुछ गलत है या मुझे इस कार्य के लिए किसी अन्य प्रकार के पार्सर का उपयोग करना चाहिए?
[क्लीटस] (http://stackoverflow.com/users/18393/cletus) में मार्कडाउन [अपने ब्लॉग पर] पार्सिंग पर अपने काम का वर्णन करने वाली एक लंबी श्रृंखला है (http://www.cforcoding.com/search/लेबल/markdown)। उनके पास "मार्कडाउन, ब्लॉक पार्सिंग और द रोड टू नर्क" जैसे खिताब हैं। आपको कुछ प्रासंगिक जानकारी या अंतर्दृष्टि मिल सकती है। –
[PyParsing] पर एक नज़र डालें (http://pyparsing.wikispaces.com/) – leoluk
@ ग्रेग थैट्स दिलचस्प, साझा करने के लिए धन्यवाद। हालांकि ऐसा लगता है कि उन्होंने इनलाइन मार्कअप को हल नहीं किया है, और मुझे ब्लॉक मार्कअप के साथ कोई समस्या नहीं है। –