2010-12-19 8 views
6

Estoy tratando de descubrir cómo implementar mi clase LEParserCfgVisitor para construir un gráfico de flujo de control a partir de un árbol de sintaxis abstracto ya generado con JavaCC . Sé que hay herramientas que ya existen, pero estoy tratando de hacerlo en preparación para la final de mi compilador.Construyendo un gráfico de control de flujo desde un AST con un patrón de visitante usando Java

Sé que necesito tener una estructura de datos que mantenga el gráfico en la memoria, y quiero poder mantener atributos como IN, OUT, GEN, KILL en cada nodo para poder hacer un flujo de control análisis más adelante.

Mi problema principal es que no he descubierto cómo conectar los diferentes bloques entre sí, ya que tengo el borde derecho entre cada bloque dependiendo de su naturaleza: rama, bucles, etc. En otras palabras, no lo he hecho Encontré un algoritmo explícito que podría ayudarme a construir mi visitante.

Aquí está mi visitante vacío. Se puede ver que funciona en expresiones básicas langage, como si, al tiempo y las operaciones básicas (+, -, x, ^, ...)

public class LEParserCfgVisitor implements LEParserVisitor 
{ 
    public Object visit(SimpleNode node, Object data) { return data; } 

    public Object visit(ASTProgram node, Object data) { 
    data = node.childrenAccept(this, data); 
    return data; 
    } 

    public Object visit(ASTBlock node, Object data) { 
    } 

    public Object visit(ASTStmt node, Object data) { 
    } 

    public Object visit(ASTAssignStmt node, Object data) { 
    } 

    public Object visit(ASTIOStmt node, Object data) { 
    } 

    public Object visit(ASTIfStmt node, Object data) { 
    } 

    public Object visit(ASTWhileStmt node, Object data) { 
    } 

    public Object visit(ASTExpr node, Object data) { 
    } 

    public Object visit(ASTAddExpr node, Object data) { 
    } 

    public Object visit(ASTFactExpr node, Object data) { 
    } 

    public Object visit(ASTMultExpr node, Object data) { 
    } 

    public Object visit(ASTPowerExpr node, Object data) { 
    } 

    public Object visit(ASTUnaryExpr node, Object data) { 
    } 

    public Object visit(ASTBasicExpr node, Object data) { 
    } 

    public Object visit(ASTFctExpr node, Object data) { 
    } 

    public Object visit(ASTRealValue node, Object data) { 
    } 

    public Object visit(ASTIntValue node, Object data) { 
    } 

    public Object visit(ASTIdentifier node, Object data) { 
    } 
} 

¿alguien puede darme una mano?

Gracias!

Respuesta

11

Para hacer un razonamiento sobre los flujos de datos (gen/kill/use/def) primero necesita un diagrama de flujo de control.

Para construir uno, en cada nodo de árbol (por ejemplo, dentro de cada visitante de nodos específico), construya la parte del gráfico que representa el nodo; pase el arco del punto de entrada y el arco de salida para ese gráfico al "visitante" principal. Los visitantes puramente independientes no funcionarán porque necesita pasar información a los padres. [Puede agregar ranuras de arcos de entrada/salida a cada nodo establecido por el visitante, e inspeccionado por el padre.]

Algunos nodos (por ejemplo, "assignmentstmt") fabricarán un nodo de acción que se refiere al AST para la asignación (piense en "rectángulo" en un diagrama de flujo); no hay ningún arco subgráfico de qué preocuparse. Algunos nodos (p. Ej., Para "si") fabricarán un nodo de bifurcación condicional (que hace referencia al nodo AST para la expresión de condición), (piense en "diamante" en un diagrama de flujo), un nodo de flujo-unión y compondrán una estructura (if- then-else) combinando ese nodo de rama condicional con los subgrafos para las cláusulas then y else (representadas solo por los arcos de entrada y salida), con el flujo join-node. Luego pasa los arcos de entrada y salida a este subgráfico compuesto al padre.

Este esquema funciona con flujo de control estructurado. El flujo de control no estructurado (por ejemplo, "GOTO x") requiere algunos ajustes divertidos, por ejemplo, primero construir la parte estructurada del gráfico, asociar el flujo de control generado con etiquetas, y luego retroceder y marcar las acciones GOTO para tener un arco al asociado etiqueta.

Recuerde preocuparse por las excepciones; también son GOTO, pero generalmente hasta un punto más alto en el gráfico de flujo de control estructurado. Estos a menudo se manejan pasando el nodo controlador de excepciones más interno hacia abajo el árbol; ahora sus visitantes deben mirar hasta el árbol para ver el controlador de excepción más reciente.

Un esquema más sofisticado que usa vistors generados se llama una http://en.wikipedia.org/wiki/Attribute_grammar">granofia de atributos, que esencialmente administra todos los flujos de información, pasando los valores de interés (en este caso, el flujo de entrada/salida/excepción arcos) arriba y abajo del árbol como parámetros y resultados. Necesitará una herramienta de gramática de atributos para hacer esto, y aún debe especificar la lógica de creación de nodos.Usamos las gramáticas de atributos y esencialmente la construcción del gráfico de flujo de control anterior por piezas con nuestro DMS Software Reengineering Toolkit para proporcionar instalaciones de análisis de flujo de control genérico para muchos idiomas.

Una vez que tenga el flujograma de control, puede implementar un solucionador de flujo de datos del tipo que describe caminando sobre el gráfico de flujo de control. Tendrá que volver a visitar los AST a los que apuntan los nodos de CF para recopilar la información de uso sin procesar/definición sin procesar.

Si su idioma tiene solo flujo de control estructurado, puede utilizar los nodos de AST para representar los nodos de flujo de control y calcular el flujo de datos directamente.

Más detalles sobre el proceso general se pueden encontrar here.

Cuestiones relacionadas