Wann sollte ich einen Parser verwenden?

8

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?"

    
Léo Léopold Hertz 준영 11.04.2009, 12:28
quelle

8 Antworten

9

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%     
lc. 11.04.2009, 12:35
quelle
3

Sie benötigen einen Parser, wenn:

  1. Sprache ist nicht regulär ( Wikipedia )
  2. Sie benötigen einen Syntaxbaum (allgemeiner, wenn Sie Aktionen kontextabhängig ausführen müssen)
  3. wenn der resultierende reguläre Ausdruck zu dunkel / komplex ist

Meine 2 Cent.

    
dfa 11.04.2009 14:10
quelle
2

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:

  • Immer wenn die Art der Ausdrücke, mit denen Sie arbeiten möchten, komplexer sind als einige semantische Einheiten (Tags, Variablen, Telefonnummern, etc.).
  • Wann immer Sie die semantische Bedeutung von Text kennen müssen, anstatt nur einem Muster zu entsprechen. Wenn Sie zum Beispiel versuchen, alle möglichen Möglichkeiten zum Schreiben einer Telefonnummer zu finden, ist ein Parser wahrscheinlich besser als eine Regex. Wenn Sie versuchen, ein bestimmtes Muster zu finden, das zufällig einer Telefonnummer entspricht, ist eine Regex wahrscheinlich in Ordnung.
  • Wann immer es nicht garantiert werden kann, dass die Eingabe gut ist.
  • Wenn Sie vollständig innerhalb der Struktur einer klar definierten Sprache arbeiten, die eine Syntaxspezifikation (C #, XML, C ++, Ruby usw.) hat, wird es bereits einen Parser geben, so dass Sie etwas Arbeit erledigt haben für dich.
John Feminella 11.04.2009 12:39
quelle
2

Das Drachenbuch enthält einen kleinen Abschnitt darüber, wofür Sie Reguläre Ausdrücke nicht verwenden können :

  • Sie können keine Wiederholung einer Zeichenkette feststellen, was bedeutet, dass Sie keine Konstrukte wie 'wcw' zuordnen können, wobei w die gleiche Folge von Symbolen ist
  • Sie können nur eine feste Anzahl von Wiederholungen oder eine unbestimmte Anzahl von Wiederholungen erkennen, dh Sie können ein bereits analysiertes Token nicht verwenden, um die Anzahl der Wiederholungen zu bestimmen, etwa wie folgt: 'n s1 s2 ... sn "
  • "Reguläre Ausdrücke können nicht verwendet werden, um symmetrische oder verschachtelte Konstrukte zu beschreiben, [wie] die Menge von Strings aller symmetrischen Klammern"

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.

    
Andrei Vajna II 12.04.2009 23:09
quelle
1

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.

    
Martijn Laarman 11.04.2009 12:36
quelle
1

Hier sind einige Anwendungsfälle, mit freundlicher Genehmigung von Steve Yegge: Rich Programmer Food .

    
Yuval F 11.04.2009 13:09
quelle
0

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.

    
Epcylon 11.04.2009 12:36
quelle
0

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.

    
codingbear 12.04.2009 23:19
quelle

Tags und Links