2010-05-18 26 views
9

Pour un projet d'animal de compagnie, j'ai commencé à jouer avec ANTLR. Après avoir suivi quelques tutoriels, j'essaie maintenant de créer la grammaire pour mon propre langage et de générer un AST. Pour l'instant, je suis surtout dans ANTLRWorks, mais maintenant que j'ai validé que l'arbre d'analyse semble aller bien je voudrais (itérativement, parce que je suis encore en train d'apprendre et encore besoin de prendre des décisions en ce qui concerne la structure finale de l'arbre) créer l'AST. Il semble que Antlrworks ne le visualise pas (ou du moins n'utilise pas la fonction "Interpreter", Debug ne fonctionne sur aucune de mes machines).Visualisation d'un AST créé avec ANTLR (dans un environnement .Net)

Ligne de fond: La seule façon de visualiser l'AST manuellement, de le traverser/de l'afficher ou d'imprimer l'arbre sous forme de chaîne sur une console? Ce que je cherche est un moyen simple d'aller d'entrée, grammaire -> représentation AST visuelle dans la fonction "Interprète" de ANTLRWorks. Des idées?

Répondre

16

Correct, l'interpréteur affiche uniquement les règles utilisées dans le processus d'analyse et ignore les règles de réécriture AST. Vous pouvez utiliser StringTemplate pour créer un GraphvizDOT-file. Après avoir créé un tel DOT-file, vous utilisez une visionneuse tierce pour afficher cet arbre (graphique).

Voici une démo rapide en Java (je connais peu de C#, désolé).

Prenez la grammaire d'expression suivante (trop simpliste) qui produit un AST:

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();} 
    ; 

Tout d'abord laissez-ANTLR générer des fichiers analyseurs lexicaux et syntaxiques de celui-ci:

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

puis créez un harnais petit test analyse les expressions "12 * (5 - 6); 2^3^(4 + 1);" et génère un DOT-file:

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 tous .java fichiers:

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

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

puis exécutez la classe principale et conduit sa sortie vers un fichier nommé ast-tree.dot:

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

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

Le fichier ast-tree.dot contient maintenant:

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" 

} 

qui peut être consulté avec l'un des many viewers autour. Il y a même des téléspectateurs en ligne. Prenez celui-ci par exemple: http://graph.gafol.net/

Lorsque nourrir le contenu de ast-tree.dot, l'image suivante est produite:

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

+1

Whoa, merci pour la réponse détaillée. +1 pour ça (semble faire ce que je veux). Je vais essayer pendant la journée et je l'accepterai probablement après. Il semble que ce soit plus rapide (c'est-à-dire qu'il n'y ait pas de compilation pour chaque changement impliqué, "prévisualisation" en direct "contre un exemple d'entrée/de flux). –

+1

Vous êtes les bienvenus @Benjamin. Si vous utilisez Eclipse, vous pouvez essayer le plugin 'ANTLR IDE': http://antlrv3ide.sourceforge.net/ Je crois qu'il a la possibilité de créer l'image d'un AST à la volée. Mais je n'ai aucune expérience personnelle avec cela. –

0

Vous devez changer la langue cible en Java pour que l'interpréteur ANTLRWorks fonctionne, ou du moins c'est ce que j'ai observé.

+0

L'interprète fonctionne bien pour moi - mais il montre l'arbre d'analyse syntaxique. Même si j'ai des options {output = AST; ...} Je reçois le même arbre. _Token_^et _Token_! ne sont pas respectés. Non ce que je veux .. –

+0

Non, l'interpréteur dans ANTLRWorks ignore la partie 'language = XYZ' de l'en-tête' options {...} 'd'une grammaire. Au moins, ANTLRWorks 1.3, 1.3.1 et 1.4 l'ignorent. –