Erstellen eines generischen Parsers zum Konvertieren einer Textdatei in eine Datenstruktur in C #

8

Ich habe eine Definition für eine SPAN-Datei ( Ссылка ), die ich gerne verwenden würde Konstruieren eines Parsers zum Analysieren der Zeichenfolgendaten in eine In-Memory-Auflistungsklasse (oder sogar Verwenden einer Lazy-Evaluierung mit dem Yield-Schlüsselwort).

Alle Parsing-Techniken und -Bibliotheken, die ich gesehen habe, gelten für die Konstruktion von Syntaxbäumen für die Implementierung von Sprachen; Ich würde einfach gerne alle guten Techniken kennen lernen, um in eine Datenstruktur zu parsen, ähnlich wie XML in ein XMLDocument im .NET Framework geparst wird, aber unter Verwendung der durch SPAN definierten Regeln.

    
Pierreten 18.08.2010, 19:57
quelle

3 Antworten

2

SPAN scheint eine Reihe von Datensatztypen zu sein, jeder Datensatz mit vielen Details.

Es sollte einfach sein, eine klassische Grammatik zu definieren, die alle Datensätze abdeckt (als Nichtterminale), in Bezug auf beliebige Subdatensätze (als Nichtterminale) und terminale Datentypen, die die verschiedenen Datentypen repräsentieren definiert durch SPAN. Es könnte viele Nichtterminale geben, aber das macht nur eine große Grammatik, aber nicht ein komplizierter.

Die meisten Programmiersprachen haben einen kleinen Satz von Terminal-Tokens, die generell überall erscheinen können. Die Wahrheit ist, dass Grammatiken Erwartungen darüber definieren, was als nächstes erscheinen kann (in der LR-Parser-Literatur "erste" und "Folge" -Sätze genannt), einschließlich einer sehr begrenzten Menge von Terminals. Eine SPAN-Grammatik wäre nicht anders; Jeder "Parse-Zustand" eines Parsers beinhaltet eine begrenzte Menge von Terminals, die als nächstes kommen, und man organisiert einen Parser, um dies auszunutzen. (Ich habe L (AL) R-Parser gebaut, und man könnte leicht den "aktuellen" Zustand verwenden, um die Teilmenge von Terminals zu bestimmen, die als nächstes passieren könnte). So könnte ein SPAN-Parser nur die kleine Menge von Token bestimmen, die als nächstes in jedem Zustand auftreten können, und diese verwenden, um die Zeichen aus den nächsten Token auszuwählen (sie müssen disjunkte Mengen bilden!).

Eine einfache Möglichkeit, dies zu implementieren, ist ein rekursiver Descent-Parser.

Ich behaupte also, dass die ganze Parsing-Maschinerie für das Parsen von SPAN gut geeignet sein könnte, mit ein bisschen individueller Arbeit, um die Token zu holen.

Parsing-Aktionen für herkömmliche Parser bauen Bäume, aber es ist ebenso einfach, Felder einer Datenstruktur zu füllen.

    
Ira Baxter 19.08.2010, 02:18
quelle
2

Recursive decent ist ein ziemlich einfacher Ansatz für solche Dinge.

Sie beginnen mit einem Wrapper für den zugrunde liegenden Stream, mit dem Sie ein Zeichen (oder möglicherweise eine Karte / einen Datensatz in Ihrem Fall) lesen können.

Sie schreiben dann eine Reihe von Funktionen, die Dinge wie "Lesen einer Zahl, Parsen" und "Lesen eines Zeichens, und überprüfen Sie, ob es X ist".

Diese Funktionen sind entweder erfolgreich und bringen den Stream voran oder scheitern mit einer parse-Ausnahme.

Schließlich ist es praktisch, einen Satz von Kombinatoren zu erstellen, die die obigen Funktionen übernehmen und kombinieren, zum Beispiel 'A lesen, dann B' oder 'A lesen, und wenn das nicht gelingt, versuche stattdessen B'.

    
Phil 19.08.2010 14:43
quelle
1

Untersuchen Sie den Gardens Point Parser-Generator , eine App, die einen C # -Parser für jede Sprache mit einer YACC-ähnlichen Sprachdefinition generiert.

    
Dour High Arch 19.08.2010 02:58
quelle