2010-05-18 3 views
9

Für ein Haustier-Projekt begann ich mit ANTLR zu spielen. Nach einigen Tutorials versuche ich nun die Grammatik für meine eigene Sprache zu erstellen und einen AST zu generieren.Visualisierung eines mit ANTLR erstellten ASTs (in einer .Net-Umgebung)

Momentan bin ich meistens mit ANTLRWorks beschäftigt, aber jetzt, wo ich bestätigt habe, dass der Parse-Baum in Ordnung zu sein scheint würde ich (iterativ, weil ich immer noch lerne und noch einige Entscheidungen treffen muss) in Bezug auf die endgültige Struktur des Baumes) erstellen Sie die AST. Es scheint, dass antlrworks es nicht visualisiert (oder zumindest nicht mit der "Interpreter" -Funktion, Debug funktioniert nicht auf einer meiner Maschinen).

Bottom line: Ist die einzige Möglichkeit, die AST den manuellen Weg zu visualisieren, zu überqueren/zeigen oder den Baum in String-Darstellung zu einer Konsole drucken?

Was ich suche ist eine einfache Möglichkeit, von Eingabe, Grammatik -> visuelle AST-Darstellung über die "Interpreter" -Funktion von ANTLRWorks zu gehen. Irgendwelche Ideen?

Antwort

16

Korrekt, der Interpreter zeigt nur an, welche Regeln im Parsing-Prozess verwendet werden, und ignoriert alle AST-Neuschreibungsregeln.

Sie können StringTemplate verwenden, um eine GraphvizDOT-file zu erstellen. Nachdem Sie einen solchen DOT-file erstellt haben, verwenden Sie einen Drittanbieter-Viewer, um diesen Baum (Graph) anzuzeigen.

Hier ist eine kurze Demo in Java (ich weiß wenig C#, sorry).

Nehmen Sie die folgende (stark vereinfacht) Ausdruck Grammatik, die eine AST produziert:

grammar ASTDemo; 

options { 
    output=AST; 
} 

tokens { 
    ROOT; 
    EXPRESSION; 
} 

parse 
    : (expression ';')+ -> ^(ROOT expression+) // omit the semi-colon 
    ; 

expression 
    : addExp -> ^(EXPRESSION addExp) 
    ; 

addExp 
    : multExp 
    ('+'^ multExp 
    | '-'^ multExp 
    )* 
    ; 

multExp 
    : powerExp 
    ('*'^ powerExp 
    | '/'^ powerExp 
    )* 
    ; 

powerExp 
    : atom ('^'^ atom)* 
    ; 

atom 
    : Number 
    | '(' expression ')' -> expression // omit the parenthesis 
    ; 

Number 
    : Digit+ ('.' Digit+)? 
    ; 

fragment 
Digit 
    : '0'..'9' 
    ; 

Space 
    : (' ' | '\t' | '\r' | '\n') {skip();} 
    ; 

Zuerst lassen ANTLR erzeugen Lexer und Parser Dateien aus: Gurtzeug

java -cp antlr-3.2.jar org.antlr.Tool ASTDemo.g 

erstellen Sie dann einen kleinen Test, dass analysiert die Ausdrücke "12 * (5 - 6); 2^3^(4 + 1);" und gibt einen DOT-file aus:

import org.antlr.runtime.*; 
import org.antlr.runtime.tree.*; 
import org.antlr.stringtemplate.*; 

public class MainASTDemo { 
    public static void main(String[] args) throws Exception { 
     ANTLRStringStream in = new ANTLRStringStream("12 * (5 - 6); 2^3^(4 + 1);"); 
     ASTDemoLexer lexer = new ASTDemoLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     ASTDemoParser parser = new ASTDemoParser(tokens); 
     ASTDemoParser.parse_return returnValue = parser.parse(); 
     CommonTree tree = (CommonTree)returnValue.getTree(); 
     DOTTreeGenerator gen = new DOTTreeGenerator(); 
     StringTemplate st = gen.toDOT(tree); 
     System.out.println(st); 
    } 
} 

Compile alle .java Dateien:

// *nix & MacOS 
javac -cp .:antlr-3.2.jar *.java 

// Windows 
javac -cp .;antlr-3.2.jar *.java 

und dann die Hauptklasse und Rohr seine Ausgabe in eine ast-tree.dot benannte Datei auszuführen:

// *nix & MacOS 
java -cp .:antlr-3.2.jar MainASTDemo > ast-tree.dot 

// Windows 
java -cp .;antlr-3.2.jar MainASTDemo > ast-tree.dot 

Die Datei ast-tree.dot jetzt enthält:

digraph { 

    ordering=out; 
    ranksep=.4; 
    bgcolor="lightgrey"; node [shape=box, fixedsize=false, fontsize=12, fontname="Helvetica-bold", fontcolor="blue" 
     width=.25, height=.25, color="black", fillcolor="white", style="filled, solid, bold"]; 
    edge [arrowsize=.5, color="black", style="bold"] 

    n0 [label="ROOT"]; 
    n1 [label="EXPRESSION"]; 
    n1 [label="EXPRESSION"]; 
    n2 [label="*"]; 
    n2 [label="*"]; 
    n3 [label="12"]; 
    n4 [label="EXPRESSION"]; 
    n4 [label="EXPRESSION"]; 
    n5 [label="-"]; 
    n5 [label="-"]; 
    n6 [label="5"]; 
    n7 [label="6"]; 
    n8 [label="EXPRESSION"]; 
    n8 [label="EXPRESSION"]; 
    n9 [label="^"]; 
    n9 [label="^"]; 
    n10 [label="^"]; 
    n10 [label="^"]; 
    n11 [label="2"]; 
    n12 [label="3"]; 
    n13 [label="EXPRESSION"]; 
    n13 [label="EXPRESSION"]; 
    n14 [label="+"]; 
    n14 [label="+"]; 
    n15 [label="4"]; 
    n16 [label="1"]; 

    n0 -> n1 // "ROOT" -> "EXPRESSION" 
    n1 -> n2 // "EXPRESSION" -> "*" 
    n2 -> n3 // "*" -> "12" 
    n2 -> n4 // "*" -> "EXPRESSION" 
    n4 -> n5 // "EXPRESSION" -> "-" 
    n5 -> n6 // "-" -> "5" 
    n5 -> n7 // "-" -> "6" 
    n0 -> n8 // "ROOT" -> "EXPRESSION" 
    n8 -> n9 // "EXPRESSION" -> "^" 
    n9 -> n10 // "^" -> "^" 
    n10 -> n11 // "^" -> "2" 
    n10 -> n12 // "^" -> "3" 
    n9 -> n13 // "^" -> "EXPRESSION" 
    n13 -> n14 // "EXPRESSION" -> "+" 
    n14 -> n15 // "+" -> "4" 
    n14 -> n16 // "+" -> "1" 

} 

welches mit einem der many viewers umgesehen werden kann. Es gibt sogar Online-Zuschauer. Nehmen Sie diese ein Beispiel: http://graph.gafol.net/

Wenn es um den Inhalt der ast-tree.dot Fütterung wird das folgende Bild erzeugt:

alt text http://img19.imageshack.us/img19/4836/expression.png

+1

Whoa, danke für die ausführliche Antwort. +1 dafür (scheint zu tun, was ich will). Ich werde es tagsüber versuchen und werde es wahrscheinlich später akzeptieren. Es scheint ein schneller (d. H. Keine Kompilation für jede Änderung beteiligt, "live" Vorschau gegen eine Probe Eingabe/Stream) Weg existiert leider nicht. –

+1

Gern geschehen @Benjamin. Wenn Sie Eclipse verwenden, möchten Sie vielleicht das Plugin 'ANTLR IDE' ausprobieren: http://antlrv3ide.sourceforge.net/ Ich glaube, es hat die Möglichkeit, das Bild eines AST im laufenden Betrieb zu erstellen. Aber ich habe keine persönlichen Erfahrungen damit. –

0

Sie müssen die Zielsprache in Java ändern, damit der ANTLRWorks-Interpreter funktioniert, zumindest habe ich das beobachtet.

+0

Der Dolmetscher arbeitet für mich in Ordnung - aber es zeigt den Parsing-Baum. Selbst wenn ich Optionen habe {output = AST; ...} Ich bekomme den gleichen Baum. _Token_^und _Token_! werden nicht respektiert. Nicht was ich will .. –

+0

Nein, der Interpreter in ANTLRWorks ignoriert den 'language = XYZ' Teil des' options {...} 'Headers einer Grammatik. Zumindest ignorieren ANTLRWorks 1.3, 1.3.1 und 1.4 es. –