Ich habe eine Auszeichnungssprache, die markdown ähnlich ist und die von SO verwendet wird.
Legacy-Parser basierte auf Regexes und war ein wahrer Alptraum. Daher habe ich mir eine eigene Lösung auf Basis der EBNF-Grammatik ausgedacht und diese über mxTextTools / SimpleParse implementiert.
Es gibt jedoch Probleme mit einigen Token, die sich gegenseitig einschließen können, und ich sehe keinen "richtigen" Weg, dies zu tun.
Hier ist ein Teil meiner Grammatik:
%Vor%Das erste Problem ist, Spoiler, stark und Betonung kann sich gegenseitig in beliebiger Reihenfolge einschließen. Und es ist möglich, dass ich später mehr solche Inline-Markups brauche.
Meine aktuelle Lösung besteht darin, für jede Kombination ein separates Token zu erstellen (inline_noast, inline_nostrong, usw.), aber offensichtlich wächst die Anzahl solcher Kombinationen mit zunehmender Anzahl von Markup-Elementen zu schnell.
Das zweite Problem ist, dass sich diese Lookaheads in strong / emphasis in einigen Fällen schlechter Markups wie __._.__*__.__...___._.____.__**___***
(viele zufällig platzierte Markup-Symbole) sehr schlecht verhalten. Es dauert Minuten, um einige kb solcher zufälligen Text zu analysieren.
Stimmt etwas nicht mit meiner Grammatik oder ich sollte eine andere Art von Parser für diese Aufgabe verwenden?
Wenn eine Sache eine andere enthält, behandeln Sie sie normalerweise als separate Token und verschachteln sie dann in der Grammatik. Lepl ( Ссылка , das ich geschrieben habe) und PyParsing (was wahrscheinlich der populärste Python-Parser ist) ermöglichen es Ihnen, Dinge rekursiv zu verschachteln .
In Lepl könnte man also etwas schreiben wie:
%Vor%Dann können Sie sehen, ich hoffe, wie Inhalte verschachtelte Verwendung von starken, Hervorhebung, etc .. passen.
Es gibt viel mehr als das, was Sie für Ihre endgültige Lösung tun können, und Effizienz könnte ein Problem in jedem reinen Python-Parser sein. Es gibt einige Parser, die in C implementiert sind, aber von Python aufgerufen werden können schwieriger zu verwenden, ich kann keine empfehlen, weil ich sie nicht benutzt habe).