2010-05-18 22 views
9

Para un proyecto de mascota comencé a juguetear con ANTLR. Después de seguir algunos tutoriales, ahora intento crear la gramática para mi propio idioma y generar un AST.Visualizar un AST creado con ANTLR (en un entorno .Net)

Por ahora estoy jugando en ANTLRWorks principalmente, pero ahora que he validado que el árbol de análisis sintáctico parece estar bien, me gustaría (iterativamente, porque todavía estoy aprendiendo y aún necesito tomar algunas decisiones con respecto a la estructura final del árbol) crea el AST. Parece que antlrworks no lo visualizará (o al menos no usará la función "Interpreter", Debug no funciona en ninguna de mis máquinas).

En pocas palabras: ¿Es la única manera de visualizar el AST de forma manual, atravesando/mostrándolo o imprimiendo el árbol en representación de cadena en una consola?

Lo que estoy buscando es una manera simple de pasar de entrada, gramática -> representación visual AST a la característica "Intérprete" de ANTLRWorks. ¿Algunas ideas?

Respuesta

16

Correcto, el intérprete solo muestra qué reglas se utilizan en el proceso de análisis e ignora las reglas de reescritura de AST.

Lo que puedes hacer es usar StringTemplate para crear un GraphvizDOT-file. Después de crear dicho DOT-file, utiliza un visor de terceros para mostrar este árbol (gráfico).

Aquí hay una demostración rápida en Java (sé poco C#, lo siento).

tomar las siguientes (demasiado simplista) gramática de expresión que produce 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();} 
    ; 

En primer lugar vamos antlr generar archivos analizadoras y analizador de ella:

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

continuación, crear un pequeño instrumento de prueba que analiza las expresiones "12 * (5 - 6); 2^3^(4 + 1);" y dará salida a 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); 
    } 
} 

compilar todos .java archivos:

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

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

y luego ejecutar la clase principal y el tubo de su salida a un archivo llamado 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 

El archivo ast-tree.dot ahora contiene:

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" 

} 

que se puede ver con uno de los many viewers alrededor. Incluso hay visores en línea. Tome éste por ejemplo: http://graph.gafol.net/

Cuando la alimentación es el contenido de ast-tree.dot, la siguiente imagen se produce:

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

+1

Whoa, gracias por la respuesta detallada. +1 para eso (parece hacer lo que quiero). Lo probaré durante el día y probablemente lo acepte después. Parece que no existe una manera más rápida (es decir, no compilación para cada cambio involucrado, vista previa "en vivo" contra una entrada/secuencia de muestra), lamentablemente. –

+1

De nada @Benjamin. Si está utilizando Eclipse, puede probar el complemento 'ANTLR IDE': http://antlrv3ide.sourceforge.net/ Creo que tiene la opción de crear la imagen de un AST sobre la marcha. Pero no tengo experiencia personal con eso. –

0

Debe cambiar el idioma de destino a Java para que el intérprete ANTLRWorks funcione, o al menos eso es lo que observé.

+0

El intérprete funciona bien para mí - pero muestra el árbol de análisis sintáctico. Incluso si tengo opciones {salida = AST; ...} Obtengo el mismo árbol. _Token_^y _Token_! no son respetados No es lo que quiero .. –

+0

No, el intérprete en ANTLRWorks ignora la parte 'language = XYZ' del encabezado' options {...} 'de una gramática. Al menos, ANTLRWorks 1.3, 1.3.1 y 1.4 lo ignoran. –

Cuestiones relacionadas