2012-09-20 4 views
15

Gibt es einen Parser-Generator, der auch die umgekehrte Richtung implementiert, d. H. Nicht-holende Domain-Objekte (a.k.a. pretty-printing) aus derselben Grammatikspezifikation? Soweit ich weiß, unterstützt ANTLR dies nicht.Kombinierter Unparser/Parser-Generator

+0

Scheint ziemlich hart, wenn Sie willkürliche Aktionen haben, aber mit einer Attributgrammatik scheint es * einfach genug ... Ich kann es kaum erwarten, durch eine kluge Antwort gedemütigt zu werden: D – delnan

+0

@delnan: Und tatsächlich, mit einem Attribut Grammatik es "ist einfach genug". Siehe meine Antwort; Die Prettyprinter-Spezifikation ist eine Attribut-Grammatur mit witziger Syntax. –

Antwort

0

Es ist generell nicht möglich.

Was macht einen Druck hübsch? Ein Ausdruck ist schön, wenn an diesen Stellen Leerzeichen, Tabulatoren oder Zeilenumbrüche vorhanden sind, die den Druck gut aussehen lassen.

Aber die meisten Grammatiken ignorieren weiße Leerzeichen, weil in den meisten Sprachen weiße Leerzeichen nicht signifikant sind. Es gibt Ausnahmen wie Python, aber im Allgemeinen ist die Frage, ob es eine gute Idee ist, Leerräume als Syntax zu verwenden, immer noch umstritten. Daher verwenden die meisten Grammatiken keine Leerzeichen als Syntax.

Und wenn der abstrakte Syntaxbaum keine Leerzeichen enthält, weil der Parser sie weggeworfen hat, kann kein Generator sie verwenden, um einen AST hübsch auszudrucken.

+0

Ich dachte das. Einige Grammatiken (wie die für C) erlauben eine Menge Flexibilität in Sachen Leerraum. Aber einige Grammatiken nicht, also wäre jeder Drucker automatisch ein hübscher Drucker. Aber es scheint, als ob Sie die Grammatik wahrscheinlich mit Informationen versehen könnten, welche der Optionen "hübsch" ist, und dann könnten Sie daraus einen hübschen Drucker erzeugen. –

1

Unsere DMS Software Reengineering Toolkit macht genau dies (und bietet eine Menge zusätzliche Unterstützung für die Analyse/Umwandlung von Code).

Es hilft zu wissen, dass DMS einen Baum direkt auf der Grammatik basiert.

Jede DMS-Grammatikregel wird mit sogenannten "prettyprinting" -Regeln kombiniert. Jede Prettyprinting-Regel beschreibt, wie das syntaktische Element, das von der entsprechenden Regel erkannt wird, "hübsch gedruckt" wird. Der Prettyprinting-Prozess kombiniert im Wesentlichen rechteckige Textrahmen horizontal oder vertikal (mit optionalem Einzug), wobei Blätter Unit-Height-Boxen erzeugen, die den Literalwert des Blatts enthalten (Schlüsselwort, Operator, Bezeichner, Konstante, etc.)

Als Beispiel , könnte man die folgende DMS Grammatik und Regel pretty schreiben:

statement = 'for' '(' assignment ';' assignment ';' conditional_expression ')' 
      '{' sequence_of_statements '}' ; 
<<PrettyPrinter>>: 
    { V(H('for','(',assignment[1],';','assignment[2],';',conditional_expression,')'), 
     H('{', I(sequence_of_statements)), 
     '}'); 

Dies wird die folgende analysieren:

for (i=x*2; 
     i--; i>-2*x) { a[x]+=3; 
     b[x]=a[x]-1; } 

und Schön es wie folgt:

for (i=x*2;i--;i>-2*x) 
    { a[x]+=3; 
     b[x]=a[x]-1; 
    } 

DMS erfasst auch Kommentare, fügt sie an AST-Knoten an und regeneriert sie bei der Ausgabe. Die Implementierung ist exotisch, da die meisten Parser nicht mit Kommentaren umgehen, aber die Verwendung ist einfach, sogar "frei"; Kommentare werden automatisch in das prettyprinted Ergebnis an ihren ursprünglichen Stellen eingefügt.

DMS kann auch im "Fidelity" -Modus drucken. In diesem Formular versucht es, den Spaltenoffset in der Zeile eines geparsten Tokens zu erhalten. Dies würde dazu führen, dass der Originaltext neu generiert wird.

Weitere Details über was PrettyPrinters tun müssen, sind in meiner SO-Antwort auf Compiling an AST back to source code zur Verfügung gestellt. DMS adressiert alle diese Themen sauber.

Diese Fähigkeit wurde von DMS für mehr als 40 echte Sprachen verwendet, einschließlich vollständiger IBM COBOL, PL/SQL, Java 1.8, C# 5.0, C (viele Dialekte) und C++ 14.

1

Es gibt mehrere Parser-Generatoren, die eine Implementierung eines Unparsers enthalten. Einer davon ist der nearley Parsergenerator für kontextfreie Grammatiken.