Ich hatte Probleme in Regexes, um einen Code in funktionale Komponenten aufzuteilen. Sie können brechen oder es kann lange dauern, bis sie fertig sind. Die Erfahrung wirft eine Frage auf:
"Wann sollte ich einen Parser verwenden?"
Sie sollten einen Parser verwenden, wenn Sie an der lexikalischen oder semantischen Bedeutung von Text interessiert sind, wenn Muster variieren können. Parser sind in der Regel übertrieben, wenn Sie einfach suchen oder Zeichenmuster ersetzen , unabhängig von ihrer funktionalen Bedeutung.
In Ihrem Fall scheinen Sie sich für die Bedeutung des Textes zu interessieren ("funktionale Komponenten" des Codes), daher wäre ein Parser die bessere Wahl. Parser können jedoch intern Regex verwenden, so dass sie nicht als sich gegenseitig ausschließend betrachtet werden sollten.
Ein "Parser" bedeutet nicht automatisch, dass es kompliziert sein muss. Wenn Sie beispielsweise an C-Code-Blöcken interessiert sind, können Sie einfach verschachtelte Gruppen von {und} parsen. Dieser Parser wäre nur an zwei Tokens ('{' und '}') und den Textblöcken zwischen ihnen interessiert.
Ein einfacher Regex-Vergleich ist hier jedoch wegen der verschachtelten Semantik nicht ausreichend. Nimm den folgenden Code:
%Vor%Ein Parser wird den Gesamtumfang von Foo sowie jeden inneren Bereich, der in Foo enthalten ist, verstehen (die if und else Blöcke). Wenn es auf jedes "{" Token trifft, "versteht" es ihre Bedeutung. Eine einfache Suche versteht jedoch nicht die Bedeutung hinter dem Text und kann folgendes als Block interpretieren, von dem wir natürlich wissen, dass er nicht korrekt ist:
%Vor%Es gibt einige überzeugende Anwendungsfälle für Parser gegenüber regulären Ausdrücken. Sie sollten einen Parser anstelle eines regulären Ausdrucks verwenden:
Das Drachenbuch enthält einen kleinen Abschnitt darüber, wofür Sie Reguläre Ausdrücke nicht verwenden können :
Für 1 und 2 gibt es eine einfache Erklärung: Sie können einen Teilstring nicht erfassen , damit Sie ihn später abgleichen können. Wenn Sie das täten, würden Sie einen Parser verwenden. Denken Sie nur daran, wie Sie für diese Fälle reguläre Ausdrücke verwenden würden, und Sie werden intuitiv zu dem Schluss kommen, dass Sie nicht können. :)
Für 3 ist es das gleiche wie das Problem in K & amp; R zum Parsen von String-Literalen. Sie können nicht einfach sagen, dass ein String-Literal zwischen dem ersten "" und dem zweiten "" liegt, aber was passiert, wenn ein entkalkeltes Zitat (\ ") existiert?
Was die Beziehung zu Russels Paradox betrifft, denke ich, dass Sie Vorstellungskraft haben, weil das Problem die begrenzten Selbstbeobachtungsfähigkeiten von Regex ist. Das Buch enthält Verweise auf die Beweise. Wenn Sie wollen, kann ich sie für Sie suchen.
Sie müssen einen Parser verwenden, sobald Sie ein Problem haben, das reguläre Ausdrücke nicht lösen sollen (oder einfach nicht lösen können). Das Zuordnen von (un) ausgeglichenen Klammern (rekursiv) ist beispielsweise eines dieser Probleme. Obwohl manche Geschmacksrichtungen, wie PCRE, dich sehr weit bringen, gewinnen sie keinen handgeschriebenen Parser.
Hier sind einige Anwendungsfälle, mit freundlicher Genehmigung von Steve Yegge: Rich Programmer Food .
Ihre Frage ist ein bisschen vage, aber ich denke, dass meine Meinung ist, dass ein Parser leichter wird, wenn Ihre Regex kompliziert wird oder zu lange dauert und Sie eine angemessen definierte "Sprache" haben.
Ich glaube nicht, dass Sie eine Linie in den Sand setzen können und sagen, dass alles auf einer Seite durch Regex gemacht werden kann, und auf der anderen Seite brauchen Sie einen Parser. Es hängt von der Situation ab.
Es gibt Dinge, die Regex nicht tun kann, während der Parser das kann.
Zum Beispiel:
Start :: = (Inner);
Inner :: = Start | x;
Regulärer Ausdruck wäre dazu nicht in der Lage, weil Regex nicht nachverfolgen kann, ob die Anzahl der offenen und schließenden Klammern gleich ist. Deshalb ist, wenn Sie versuchen, eine große Datei zu zerlegen und zu analysieren, wird Parser voraussichtlich verwendet werden, während regex einfach spezielles Muster (n) in der Datei finden.