Vorteile von Antlr (im Vergleich zu Lex / Yacc / Bison) [geschlossen]

143

Ich habe in der Vergangenheit Lex und Yacc (normalerweise Bison) für verschiedene Projekte verwendet, normalerweise Übersetzer (z. B. eine Teilmenge von EDIF, die in eine EDA-App gestreamt wird). Außerdem musste ich Code unterstützen, der auf Lex / Yacc-Grammatiken basiert, die Jahrzehnte zurückreichen. Ich kenne mich also mit den Werkzeugen aus, obwohl ich kein Experte bin.

Ich habe in der Vergangenheit in verschiedenen Foren positive Kommentare zu Antlr gesehen und bin gespannt, was mir möglicherweise fehlt. Wenn Sie also beide verwendet haben, sagen Sie mir bitte, was in Antlr besser oder fortgeschrittener ist. Meine aktuellen Einschränkungen sind, dass ich in einem C ++ - Shop arbeite und jedes Produkt, das wir versenden, kein Java enthält, sodass die resultierenden Parser dieser Regel folgen müssten.

Don Wakefield
quelle

Antworten:

145

Update / Warnung: Diese Antwort ist möglicherweise veraltet!


Ein Hauptunterschied besteht darin, dass ANTLR einen LL (*) -Parser generiert, während YACC und Bison beide Parser generieren, die LALR sind. Dies ist eine wichtige Unterscheidung für eine Reihe von Anwendungen, wobei die Betreiber am offensichtlichsten sind:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR ist völlig unfähig, diese Grammatik so zu behandeln, wie sie ist. Um ANTLR (oder einen anderen LL-Parser-Generator) zu verwenden, müssen Sie diese Grammatik in etwas konvertieren, das nicht linksrekursiv ist. Bison hat jedoch kein Problem mit Grammatiken dieser Form. Sie müssten '+' und '-' als linksassoziative Operatoren deklarieren, dies ist jedoch für die Linksrekursion nicht unbedingt erforderlich. Ein besseres Beispiel könnte der Versand sein:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

Beachten Sie, dass sowohl die exprals auch die actualsRegeln linksrekursiv sind. Dies führt zu einem viel effizienteren AST, wenn es um die Codegenerierung geht, da mehrere Register und unnötiges Verschütten nicht erforderlich sind (ein nach links geneigter Baum kann reduziert werden, ein nach rechts geneigter Baum nicht).

In Bezug auf den persönlichen Geschmack denke ich, dass LALR-Grammatiken viel einfacher zu konstruieren und zu debuggen sind. Der Nachteil ist, dass Sie sich mit etwas kryptischen Fehlern wie Shift-Reduce und (der gefürchteten) Reduce-Reduce auseinandersetzen müssen. Dies sind Fehler, die Bison beim Generieren des Parsers abfängt, sodass sie die Endbenutzererfahrung nicht beeinträchtigen, aber den Entwicklungsprozess etwas interessanter machen können. ANTLR wird aus genau diesem Grund allgemein als einfacher zu verwenden angesehen als YACC / Bison.

Daniel Spiewak
quelle
2
Der große, möglicherweise einzelne Vorteil von Antlr in Ihrer Wahrnehmung besteht also darin, dass während der Bauphase weniger Fehler wie sr und rr erzeugt werden. Ich gehe davon aus, dass ich es versuchen werde, aber wahrscheinlich am Ende bei dem bleiben werde, was ich weiß ...
Don Wakefield
1
Ja, das ist so ziemlich alles. :-) Ich stimme auch nicht wirklich der Meinung der Bevölkerung zu, dass ANTLR einfacher ist als Bison, also denke ich, dass ich Ihrer Entscheidung zustimmen würde.
Daniel Spiewak
2
Benötigt die 'tatsächliche' Regel eine zweite Regel, um anzuzeigen, dass ein einfacher 'Ausdruck' eine tatsächliche ist? Ansonsten schöne Erklärung.
Jonathan Leffler
8
Ein anderer Kommentar, den ich kürzlich gefunden habe, obwohl er ein Jahrzehnt alt ist, macht eine vernünftige Beobachtung der Ausgabe : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS sind LL, was das Schreiben der Grammatik schwieriger macht, aber die Der generierte Code ist lesbar. Yacc als LALR (das wissen Sie natürlich) erleichtert das Schreiben der Grammatik, aber der generierte Code kann genauso gut Hieroglyphen sein. "
Don Wakefield
72
Ich habe gerade die sofortige Linksrekursionsunterstützung für ANTLR Next Release v3.4 abgeschlossen. Behandelt LR-Ausdrucksregeln und ähnliche Dinge wie C-Deklaratorregeln. :)
Terence Parr
117

Der wichtigste Unterschied zwischen YACC / Bison und ANTLR ist die Art der Grammatiken, die diese Tools verarbeiten können. YACC / Bison behandeln LALR-Grammatiken, ANTLR behandelt LL-Grammatiken.

Menschen, die lange Zeit mit LALR-Grammatiken gearbeitet haben, werden es oft schwieriger finden, mit LL-Grammatiken zu arbeiten und umgekehrt. Das bedeutet nicht, dass die Grammatiken oder Werkzeuge von Natur aus schwieriger zu bearbeiten sind. Welches Tool für Sie einfacher zu verwenden ist, hängt hauptsächlich von der Art der Grammatik ab.

In Bezug auf die Vorteile gibt es Aspekte, bei denen LALR-Grammatiken Vorteile gegenüber LL-Grammatiken haben, und es gibt andere Aspekte, bei denen LL-Grammatiken Vorteile gegenüber LALR-Grammatiken haben.

YACC / Bison generieren tabellengesteuerte Parser, was bedeutet, dass die "Verarbeitungslogik" in den Daten des Parserprogramms enthalten ist, nicht so sehr im Code des Parsers. Die Auszahlung ist, dass selbst ein Parser für eine sehr komplexe Sprache einen relativ kleinen Code-Footprint hat. Dies war in den 1960er und 1970er Jahren wichtiger, als die Hardware sehr begrenzt war. Tabellengesteuerte Parser-Generatoren gehen auf diese Zeit zurück und ein geringer Code-Footprint war damals eine Hauptanforderung.

ANTLR generiert rekursive Abstiegsparser, was bedeutet, dass die "Verarbeitungslogik" im Parsercode enthalten ist, da jede Produktionsregel der Grammatik durch eine Funktion im Parsercode dargestellt wird. Die Auszahlung ist, dass es einfacher ist zu verstehen, was der Parser tut, indem er seinen Code liest. Rekursive Abstiegsparser sind normalerweise schneller als tabellengesteuerte. Bei sehr komplexen Sprachen ist der Code-Footprint jedoch größer. Dies war in den 1960er und 1970er Jahren ein Problem. Damals wurden aufgrund von Hardwareeinschränkungen nur relativ kleine Sprachen wie beispielsweise Pascal auf diese Weise implementiert.

Von ANTLR generierte Parser befinden sich normalerweise in der Nähe von 10.000 Codezeilen und mehr. Handgeschriebene Parser rekursiver Abstammung befinden sich häufig im selben Stadion. Wirths Oberon-Compiler ist mit etwa 4000 Codezeilen einschließlich Codegenerierung vielleicht der kompakteste, aber Oberon ist eine sehr kompakte Sprache mit nur etwa 40 Produktionsregeln.

Wie bereits erwähnt, ist das grafische IDE-Tool ANTLRworks ein großes Plus für ANTLR. Es ist ein komplettes Labor für Grammatik- und Sprachdesign. Es visualisiert Ihre Grammatikregeln, während Sie sie eingeben, und wenn es Konflikte findet, zeigt es Ihnen grafisch, was der Konflikt ist und was ihn verursacht. Es kann sogar Konflikte wie Linksrekursion automatisch umgestalten und lösen. Sobald Sie eine konfliktfreie Grammatik haben, können Sie ANTLRworks eine Eingabedatei Ihrer Sprache analysieren lassen, einen Analysebaum und AST für Sie erstellen und den Baum grafisch in der IDE anzeigen. Dies ist ein sehr großer Vorteil, da Sie dadurch viele Stunden Arbeit sparen können: Sie werden konzeptionelle Fehler in Ihrem Sprachdesign finden, bevor Sie mit dem Codieren beginnen! Ich habe kein solches Tool für LALR-Grammatiken gefunden, anscheinend gibt es kein solches Tool.

Selbst für Leute, die ihre Parser nicht generieren, sondern von Hand codieren möchten, ist ANTLRworks ein großartiges Werkzeug für das Design / Prototyping von Sprachen. Möglicherweise das beste verfügbare Tool. Leider hilft Ihnen das nicht, wenn Sie LALR-Parser erstellen möchten. Der Wechsel von LALR zu LL, um ANTLRworks zu nutzen, mag sich lohnen, aber für manche Menschen kann der Wechsel von Grammatiktypen eine sehr schmerzhafte Erfahrung sein. Mit anderen Worten: YMMV.

trijezdci
quelle
4
mag es, weil es die Geschichte hinter den verschiedenen Mechanismen erklärt, die die Menschen sofort verständlich machen
zinking
35

Ein paar Vorteile für ANTLR:

  • kann Parser in verschiedenen Sprachen ausgeben - Java ist für die Ausführung des generierten Parsers nicht erforderlich.
  • Eine großartige Benutzeroberfläche erleichtert das Debuggen von Grammatik (z. B. können Sie die generierten ASTs direkt in der Benutzeroberfläche anzeigen, ohne dass zusätzliche Tools erforderlich sind).
  • Generierter Code ist tatsächlich für Menschen lesbar (dies ist eines der Ziele von ANTLR), und die Tatsache, dass LL-Parser generiert werden, hilft in dieser Hinsicht sicherlich.
  • Die Definition von Terminals ist ebenfalls kontextfrei (im Gegensatz zu Regex in (f) Lex). Dies ermöglicht beispielsweise die Definition von Terminals, die ordnungsgemäß geschlossene Klammern enthalten

Meine .02 $

Cristian Diaconescu
quelle
9

Ein weiterer Vorteil von ANTRL ist, dass Sie ANTLRWORKS verwenden können , obwohl ich nicht sagen kann, dass dies ein strikter Vorteil ist, da es möglicherweise ähnliche Tools auch für andere Generatoren gibt.

John mit Waffel
quelle
9
  • Bison und Flex führen zu einem geringeren Speicherbedarf, Sie haben jedoch keine grafische IDE.
  • antlr verwendet mehr Speicher, aber Sie haben antlrworks, eine grafische IDE.

Die Bison / Flex-Speichernutzung beträgt normalerweise etwa ein MByte. Vergleichen Sie dies mit antlr - vorausgesetzt, es verwendet 512 Byte Speicher für jedes Token in der Datei, die Sie analysieren möchten. 4 Millionen Token und Sie haben auf einem 32-Bit-System nicht mehr genügend virtuellen Speicher.

Wenn die Datei, die Sie analysieren möchten, groß ist, hat antlr möglicherweise nicht genügend Arbeitsspeicher. Wenn Sie also nur eine Konfigurationsdatei analysieren möchten, ist dies eine praktikable Lösung. Andernfalls versuchen Sie Bison, wenn Sie eine Datei mit vielen Daten analysieren möchten.

nur ich
quelle
7
Ich bin neugierig. Können Sie auf eine Dokumentation verweisen, die den Verbrauch von 512 Byte Speicher pro Token beschreibt? Ich kann mich nicht erinnern, diese Diskussion gesehen zu haben. Meine Wahl der Google-Keywords gibt mir auch keine Befriedigung ...
Don Wakefield
2
Sprechen Sie über den Speicherbedarf des Parser-Generators beim Generieren eines Parsers oder über den Speicherbedarf des generierten Parsers beim Parsen der Eingabe für die Ausgangssprache? Millionen von Token in einer Grammatik wären absolut verrückt. Sie sollten in einer Nervenheilanstalt eingesperrt sein, wenn Sie ernsthaft versucht haben, eine solche Idee zu verkaufen. Bei Eingabedateien für den Parser selbst kann es Fälle geben, in denen diese eine extrem große Anzahl von Token enthalten. Die meisten Sprachen sind jedoch modular aufgebaut. Sie analysieren nicht die gesamte Eingabe in einer einzigen Datei, sondern einzelne Module sind kleiner.
Trijezdci