Parsen in C++: Glaubensfrage oder anwendungsspezifisch? (flex+bison, boost, etc)
-
Hallo zusammen,
Ich beschäftige mich erst seit sehr kurzer Zeit mit Tools zum Parsen. Es gibt wohl einige verschiedene Möglichkeiten, so etwas zu nutzen und meine Frage lautet allgemein, ist es hauptsächlich eine Glaubensfrage, welche man benutzt oder kann man je nach Voraussetzungen bestimmte Tools eher empfehlen als andere?
Ich habe mich jetzt vor allem mit einigen Tutorials und Dokumentationen über flex und bison beschäftigt und hier auch begonnen, selbst zu testen. Das ganze hat aber sogar einen ganz realen Hintergrund:
In einem Programm von mir werden Strings aus einer Datenbank gelesen und bislang mit Hilfe von regulären Ausdrücken verarbeitet. Auf lange Sicht wäre es wünschenswert, diese Arbeit durch eines der genannten Parsertools erledigen zu lassen.
Dabei würde ich einen Parser aufrufen und der soll dann wiederum in bestimmten Fällen Methoden meiner Klasse (Singleton, also zumindest gäbe es wohl kein Zugriffsproblem) aufrufen.Ein paar Dinge sind mir wichtig dabei:
- Ich hätte gerne C++ Code, den ich in mein Projekt einbinden kann
- freie Software (also tatsächlich alles erlaubt)
- Da ich Visual Studio 2008 Express Edition nutze, sollte es damit kompatibel sein (habe gehört, eine alte bison-Version zB macht da Probleme)
- Unterstützung von Unicode (es könnten kyrillische und koreanische Zeichen im Parsingbereich vorkommen)Google und auch das Forum hier haben mir gezeigt, dass es noch einige andere Tools gäbe, die für mich in Frage kommen, z.B. Gold Parser oder Boost::Spirit (wobei letzteres mir auf den ersten Blick attraktiver erscheint, weil mir der Output von Gold nicht so recht zusagt) und noch ein paar andere. Von flex und bison gibt es ja dann auch noch die ++-Versionen und sogar ein bisonc++, mit dem richtigen Skelettfile sollen auch die 'Originale' C++-Output generieren. Viele Tools also, die ja prinzipiell die gleiche Aufgabe bewältigen wollen.
Nach welchen Kriterien wählt man aber das 'richtige' aus? Reichen meine Anforderungen bereits für eine Entscheidung oder muss ich erst tiefer einsteigen in die möglichen Tools?
Grüße, pygo
-
pygo schrieb:
Nach welchen Kriterien wählt man aber das 'richtige' aus? Reichen meine Anforderungen bereits für eine Entscheidung oder muss ich erst tiefer einsteigen in die möglichen Tools?
Nach den Kriterien die du brauchst. Wenns kostenlos und frei sein muss dann kannst du ja bison und felx nehmen. Ansonsten musst du nach der Grammatik schauen die die Parser beherschen. Kannst sie alles abdecken. Ist sie leicht wartbar. Wie siehts mit links (oder war es rechts?) -Rekursion aus. Kannst du einfach eigene Methoden (z.B. zur Fehlerbehandlung oder Fehlerausgabe) zum generierten Code hinzufügen.
Am besten du probierst ein bis drei Parser und Scanner aus und entscheidest dich dann, welcher dir besser gefällt.
-
Wenns unkompliziert sein soll dann nimm flex+bison. Bei spirit habe ich den Eindruck, dass sich die Einarbeitung nicht lohnt. Zuviel Spielerei und das Debuggen ist unglaublich umständlich. Der Code sieht zwar toll aus wenn man da der absolute Crack ist, aber das ist auch nicht alles. Diese EBNF-"Emulation" in C++ ist vielleicht für kleine Sachen ganz toll, aber für komplexe und robuste Parser würde ich immer zu flex+bison greifen. Da sind die Compilezeiten auch nicht so extrem, wobei spirit sich da auch gebessert haben soll.
-
Mein Eindruck ist auch, dass spirit vor allem für kleinere Parser toll ist. Für was größeres würde ich dann eher eine andere Lösung hernehmen. Allerdings fand ich die Einarbeitungszeit nicht soo schlimm, die Beispiele sind recht ausführlich.
-
Jester schrieb:
Mein Eindruck ist auch, dass spirit vor allem für kleinere Parser toll ist.
Dieser Eindruck zwängt sich mir (obwohl noch nicht eine Zeile davon genutzt) auch auf, auch die angepriesene Skalierbarkeit würde dafür sprechen.
Also doch eher flex+bison, wenn man sowieso vor hat, mindestens 60% der Funkionalitäten zu nutzen?! Prima, dann ist zumindest die Einarbeitung in die beiden bislang nicht umsonst gewesen.
Gibt es noch andere sinnvolle Alternativen? ANTLR oder sonst was empfehlenswertes?
Gruß, pygo
-
Warum nicht direkt die Daten anständig in der Datenbank unterbringen? Wenn du da zu parsende Strings drin speicherst zerbombst du dir irgendwie die Vorteile.
Ich verzichte weitesgehend auf Parsen in C++, wenn dann mal was kleines mit Spirit (das Debuggen ist wirklich hässlich). Aber auch nur, weil ich damit schon umgehen kann, entsprechend solltest du, wenn du mit bison+flex umgehen kannst meines Erachtens das benutzen anstatt dich nochmal großartig in was anderes einzuarbeiten.
-
spirit2.0 ist zur Zeit noch nicht Compilezeit optimiert, daher kompiliert das etwas länger, würde (und habe schon) aber durchaus auch bei größerem Spirit verwenden.
-
pygo schrieb:
Gibt es noch andere sinnvolle Alternativen? ANTLR oder sonst was empfehlenswertes?
Gruß, pygo