Parser für abschriftenähnliche Sprache implementieren

Ich habe eine Markup-Sprache, die der von SO verwendeten ähnlich ist.

Legacy-Parser basierte auf regulären Ausdrücken und war ein wahrer Alptraum. Daher habe ich mir eine eigene Lösung ausgedacht, die auf der EBNF-Grammatik basiert und über mxTextTools / SimpleParse implementiert wurde.

Es gibt jedoch Probleme mit einigen Tokens, die sich gegenseitig betreffen, und ich sehe keinen "richtigen" Weg, dies zu tun.

Hier ist ein Teil meiner Grammatik:

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)+

Erstes Problem ist, Spoiler, stark und Betonung können sich 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, nur ein separates Token für jede Kombination (inline_noast, inline_nostrong usw.) zu erstellen, aber die Anzahl solcher Kombinationen wächst offensichtlich mit zunehmender Anzahl von Markup-Elementen zu schnell.

S, zweites Problem ist, dass diese Lookaheads in stark / Betonung sehr schlecht auf einige Fälle von schlechten Markup wie @ verhalt__._.__*__.__...___._.____.__**___*** (viele zufällig platzierte Auszeichnungssymbole). Es dauert Minuten, um einige KB solchen zufälligen Texts zu analysieren.

Ist etwas mit meiner Grammatik nicht in Ordnung oder sollte ich für diese Aufgabe einen anderen Parser verwenden?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage