Ich muss einige Dateien analysieren und in einige vordefinierte Datentypen konvertieren.
Haskell scheint dafür zwei Pakete anzubieten:
Was ist der Unterschied zwischen den beiden und welches ist besser geeignet, um eine Textdatei nach bestimmten Regeln zu analysieren?
haskell
parsec
attoparsec
Sibi
quelle
quelle
attoparsec
ist schneller, wird aberparsec
wahrscheinlich standardmäßig installiert und ist daher möglicherweise bequemer.uu-parsinglib
undpolyparse
.Antworten:
Parsec
Parsec ist gut für "benutzerbezogene" Parser: Dinge, bei denen Sie nur eine begrenzte Menge an Eingaben haben, aber Fehlermeldungen wichtig sind. Es ist nicht besonders schnell, aber wenn Sie kleine Eingaben haben, sollte dies keine Rolle spielen. Zum Beispiel würde ich Parsec für praktisch alle Programmiersprachen-Tools wählen, da - absolut gesehen - selbst die größten Quelldateien nicht so groß sind , aber Fehlermeldungen wirklich wichtig sind.
Parsec kann mit verschiedenen Eingabetypen arbeiten, dh Sie können es mit einem Standard
String
oder mit einem Stream von Token von einem externen Lexer verwenden. Da esString
Unicode verwenden kann , ist es für Sie perfekt geeignet . Die eingebauten Basis-Parser mögendigit
undletter
sind Unicode-fähig.Parsec wird auch mit einem Monadentransformator geliefert, sodass Sie ihn in einen Monad-Stapel legen können. Dies kann nützlich sein, wenn Sie beispielsweise während des Analysierens den zusätzlichen Status verfolgen möchten. Sie könnten sich auch für trippigere Effekte wie nicht deterministisches Parsen oder etwas anderes entscheiden - die übliche Magie von Monadentransformatoren.
Attoparsec
Attoparsec ist viel schneller als Parsec. Sie sollten es verwenden, wenn Sie erwarten, dass große Mengen an Input oder Leistung wirklich wichtig sind. Es eignet sich hervorragend für Netzwerkcode (Parsen der Paketstruktur), Parsen großer Rohdatenmengen oder Arbeiten mit binären Dateiformaten.
Attoparsec kann mit
ByteString
s arbeiten, bei denen es sich um Binärdaten handelt. Dies macht es zu einer guten Wahl für die Implementierung von Dingen wie binären Dateiformaten. Da dies jedoch für Binärdaten gilt, werden Dinge wie die Textcodierung nicht behandelt. Dafür sollten Sie das attoparsec-Modul für verwendenText
.Attoparsec unterstützt inkrementelles Parsen, was Parsec nicht tut. Dies ist für bestimmte Anwendungen wie Netzwerkcode sehr wichtig, für andere jedoch nicht.
Attorparsec hat schlechtere Fehlermeldungen als Parsec und opfert einige Funktionen auf hoher Ebene für die Leistung. Es ist auf
Text
oder spezialisiertByteString
, daher können Sie es nicht mit Token aus einem benutzerdefinierten Lexer verwenden. Es ist auch kein Monadentransformator.Welcher?
Letztendlich bedienen Parsec und Attoparsec sehr unterschiedliche Nischen. Der Hauptunterschied besteht in der Leistung: Wenn Sie ihn benötigen, wählen Sie Attoparsec. Wenn Sie dies nicht tun, gehen Sie einfach mit Parsec.
Meine übliche Heuristik ist die Auswahl von Parsec für Programmiersprachen, Konfigurationsdateiformate und Benutzereingaben sowie für fast alles, was ich sonst mit einem regulären Ausdruck tun würde. Dies sind Dinge, die normalerweise von Hand erstellt werden, sodass die Parser nicht skalieren müssen, sondern Fehler gut melden müssen.
Auf der anderen Seite würde ich Attoparsec wählen, um beispielsweise Netzwerkprotokolle zu implementieren, Binärdaten und Dateiformate zu verarbeiten oder große Mengen automatisch generierter Daten einzulesen. Dinge, bei denen Sie mit Zeitbeschränkungen oder großen Datenmengen zu tun haben, die normalerweise nicht direkt von einem Menschen geschrieben werden.
Wie Sie sehen, ist die Auswahl tatsächlich oft recht einfach: Die Anwendungsfälle überschneiden sich nicht sehr stark. Die Chancen stehen gut, dass es ziemlich klar ist, welches für eine bestimmte Anwendung verwendet werden soll.
quelle