Ich möchte zu Lernzwecken etwas Parsing und Tokenisierung in C++ durchführen. Nun bin ich beim Lesen über dieses Thema im Internet oft auf bison/yacc und lex gestoßen. Gäbe es einen großen Vorteil der Verwendung dieser über zum Beispiel ein Tokenizer/Parser mit STL oder boost::regex oder vielleicht sogar nur C geschrieben?
Antworten
Zu viele Anzeigen?Vor kurzem habe ich einen einfachen Lexer und Parser geschrieben.
Es stellte sich heraus, dass es einfacher war, den Lexer von Hand zu programmieren. Aber der Parser war etwas schwieriger. Mein von Bison generierter Parser funktionierte fast auf Anhieb und gab mir eine Menge hilfreicher Meldungen darüber, wo ich Zustände vergessen hatte. Später habe ich denselben Parser von Hand geschrieben, aber es brauchte viel mehr Fehlersuche, bis er perfekt funktionierte.
Der Reiz der Generierungswerkzeuge für Lexer und Parser liegt darin, dass Sie die Spezifikation in einer sauberen, leicht lesbaren Sprache schreiben können, die einer möglichst kurzen Wiedergabe Ihrer Spezifikation nahe kommt. Ein handgeschriebener Parser ist normalerweise mindestens doppelt so umfangreich. Außerdem enthält der automatische Parser (/lexer) eine Menge Diagnosecode und Logik, die Ihnen bei der Fehlersuche helfen.
Eine Parser/Lexer-Spezifikation in einer BNF-ähnlichen Sprache ist auch viel einfacher zu ändern, wenn sich Ihre Sprache oder Ihre Anforderungen ändern. Wenn Sie es mit einem handgeschriebenen Parser/Lexer zu tun haben, müssen Sie möglicherweise tief in Ihren Code eindringen und erhebliche Änderungen vornehmen.
Da sie häufig als endliche Zustandsautomaten ohne Backtracking implementiert werden (bei Bison gibt es unzählige Optionen, so dass dies nicht immer gegeben ist), ist es durchaus möglich, dass Ihr automatisch generierter Code effizienter ist als Ihr von Hand codiertes Produkt.
Es ist einfacher und sie sind allgemeiner. Bison/Lex kann eine beliebige Grammatik tonkenisieren und parsen und sie in einem möglicherweise einfacheren Format darstellen. Sie könnten auch schneller sein, je nachdem, wie gut Sie Ihre Regex schreiben.
Ich würde keinen eigenen Parser in C schreiben wollen, da die Sprache keine große Intuition für Zeichenketten hat. Wenn Sie Ihren eigenen Parser schreiben, würde ich Perl empfehlen, um die Regex zu vereinfachen (oder möglicherweise Python).
Es ist wahrscheinlich schneller, vorhandene Werkzeuge zu verwenden, aber es macht vielleicht nicht so viel Spaß. Wenn Sie Zeit haben und es nur zum Lernen ist, sollten Sie es versuchen. C++ ist eine gute Sprache, um damit anzufangen.