Moved from List<String> to CFG object
This commit is contained in:
parent
0e5667582b
commit
221c9e6b23
3 changed files with 95 additions and 82 deletions
70
src/main/java/grafos/CFG.java
Normal file
70
src/main/java/grafos/CFG.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package grafos;
|
||||||
|
|
||||||
|
import com.github.javaparser.ast.stmt.EmptyStmt;
|
||||||
|
import com.github.javaparser.ast.stmt.Statement;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class CFG {
|
||||||
|
private final List<Statement> nodes = new ArrayList<Statement>();
|
||||||
|
private final Map<Statement, List<Statement>> edges = new HashMap<Statement, List<Statement>>();
|
||||||
|
private Statement beginNode, endNode;
|
||||||
|
|
||||||
|
public void addNode(Statement stmt) {
|
||||||
|
nodes.add(stmt);
|
||||||
|
System.out.println("NODO: " + stmt2str(stmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect(int begin, int end) {
|
||||||
|
connect(nodes.get(begin), nodes.get(end));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect(Statement begin, Statement end) {
|
||||||
|
if (edges.containsKey(begin) && !edges.get(begin).contains(end)) {
|
||||||
|
edges.get(begin).add(end);
|
||||||
|
} else {
|
||||||
|
List<Statement> dest = new ArrayList<Statement>();
|
||||||
|
dest.add(end);
|
||||||
|
edges.put(begin, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement beginNode() {
|
||||||
|
if (beginNode == null) {
|
||||||
|
beginNode = new EmptyStmt();
|
||||||
|
nodes.add(beginNode);
|
||||||
|
}
|
||||||
|
return beginNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement endNode() {
|
||||||
|
if (endNode == null) {
|
||||||
|
endNode = new EmptyStmt();
|
||||||
|
nodes.add(endNode);
|
||||||
|
}
|
||||||
|
return endNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> toStringList() {
|
||||||
|
List<String> res = new LinkedList<String>();
|
||||||
|
for (Map.Entry<Statement, List<Statement>> e : edges.entrySet()) {
|
||||||
|
for (Statement dest : e.getValue()) {
|
||||||
|
res.add(edge2str(e.getKey(), dest));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String edge2str(Statement a, Statement b) {
|
||||||
|
return stmt2str(a) + "->" + stmt2str(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stmt2str(Statement s) {
|
||||||
|
if (s == beginNode)
|
||||||
|
return "Start";
|
||||||
|
if (s == endNode)
|
||||||
|
return "Stop";
|
||||||
|
int index = nodes.indexOf(s);
|
||||||
|
return "\"(" + index + ") " + s.toString().replace("\"", "\\\"") + "\"";
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,8 +7,6 @@ import com.github.javaparser.ast.comments.Comment;
|
||||||
import com.github.javaparser.ast.visitor.VoidVisitor;
|
import com.github.javaparser.ast.visitor.VoidVisitor;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Transformador {
|
public class Transformador {
|
||||||
|
|
||||||
|
@ -25,12 +23,18 @@ public class Transformador {
|
||||||
quitarComentarios(cu);
|
quitarComentarios(cu);
|
||||||
|
|
||||||
// Recorremos el AST
|
// Recorremos el AST
|
||||||
List<String> arcos = new ArrayList<String>();
|
CFG graph = new CFG();
|
||||||
VoidVisitor<List<String>> visitador = new Visitador();
|
VoidVisitor<CFG> visitador = new Visitador();
|
||||||
visitador.visit(cu, arcos);
|
visitador.visit(cu, graph);
|
||||||
|
|
||||||
// Imprimimos el CFG del programa
|
// Imprimimos el CFG del program
|
||||||
String dotInfo = imprimirGrafo(arcos);
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (String s : graph.toStringList()) {
|
||||||
|
builder.append(s);
|
||||||
|
builder.append(";");
|
||||||
|
System.out.println("ARCO: " + s);
|
||||||
|
}
|
||||||
|
String dotInfo = builder.toString();
|
||||||
|
|
||||||
// Generamos un PDF con el CFG del programa
|
// Generamos un PDF con el CFG del programa
|
||||||
System.out.print("\nGenerando PDF...");
|
System.out.print("\nGenerando PDF...");
|
||||||
|
@ -49,19 +53,6 @@ public class Transformador {
|
||||||
System.out.println(" PDF generado!");
|
System.out.println(" PDF generado!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imprime el grafo en la pantalla
|
|
||||||
private static String imprimirGrafo(List<String> arcos) {
|
|
||||||
StringBuilder dotInfo = new StringBuilder();
|
|
||||||
for (String arco : arcos) {
|
|
||||||
dotInfo.append(arco);
|
|
||||||
System.out.println("ARCO: " + arco);
|
|
||||||
}
|
|
||||||
System.out.println("\nCFG:");
|
|
||||||
System.out.println(dotInfo);
|
|
||||||
|
|
||||||
return dotInfo.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elimina todos los comentarios de un nodo y sus hijos
|
// Elimina todos los comentarios de un nodo y sus hijos
|
||||||
private static void quitarComentarios(Node node) {
|
private static void quitarComentarios(Node node) {
|
||||||
node.removeComment();
|
node.removeComment();
|
||||||
|
|
|
@ -1,24 +1,16 @@
|
||||||
package grafos;
|
package grafos;
|
||||||
|
|
||||||
import com.github.javaparser.ast.NodeList;
|
|
||||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||||
import com.github.javaparser.ast.stmt.BlockStmt;
|
|
||||||
import com.github.javaparser.ast.stmt.ExpressionStmt;
|
import com.github.javaparser.ast.stmt.ExpressionStmt;
|
||||||
import com.github.javaparser.ast.stmt.Statement;
|
import com.github.javaparser.ast.stmt.Statement;
|
||||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||||
|
|
||||||
import java.util.List;
|
public class Visitador extends VoidVisitorAdapter<CFG> {
|
||||||
|
|
||||||
|
|
||||||
public class Visitador extends VoidVisitorAdapter<List<String>> {
|
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
//********************** Atributos ***********************/
|
//********************** Atributos ***********************/
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
|
|
||||||
// Usamos un contador para numerar las instrucciones
|
private Statement prevNode;
|
||||||
private int contador = 1;
|
|
||||||
private String nodoAnterior = "Start";
|
|
||||||
private String nodoActual = "";
|
|
||||||
|
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
//*********************** Metodos ************************/
|
//*********************** Metodos ************************/
|
||||||
|
@ -27,67 +19,27 @@ public class Visitador extends VoidVisitorAdapter<List<String>> {
|
||||||
// Visitador de métodos
|
// Visitador de métodos
|
||||||
// Este visitador añade el nodo final al CFG
|
// Este visitador añade el nodo final al CFG
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodDeclaration methodDeclaration, List<String> collector) {
|
public void visit(MethodDeclaration methodDeclaration, CFG graph) {
|
||||||
|
prevNode = graph.beginNode();
|
||||||
|
|
||||||
// Visitamos el método
|
// Visitamos el método
|
||||||
super.visit(methodDeclaration, collector);
|
super.visit(methodDeclaration, graph);
|
||||||
|
|
||||||
// Añadimos el nodo final al CFG
|
// Añadimos el nodo final al CFG
|
||||||
collector.add(nodoAnterior + "-> Stop;");
|
Statement end = graph.endNode();
|
||||||
|
if (prevNode != end)
|
||||||
|
graph.connect(prevNode, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visitador de expresiones
|
// Visitador de expresiones
|
||||||
// Cada expresión encontrada genera un nodo en el CFG
|
// Cada expresión encontrada genera un nodo en el CFG
|
||||||
@Override
|
@Override
|
||||||
public void visit(ExpressionStmt es, List<String> collector) {
|
public void visit(ExpressionStmt es, CFG graph) {
|
||||||
// Creamos el nodo actual
|
graph.addNode(es);
|
||||||
nodoActual = crearNodo(es);
|
graph.connect(prevNode, es);
|
||||||
|
prevNode = es;
|
||||||
crearArcos(collector);
|
|
||||||
|
|
||||||
nodoAnterior = nodoActual;
|
|
||||||
|
|
||||||
// Seguimos visitando...
|
// Seguimos visitando...
|
||||||
super.visit(es, collector);
|
super.visit(es, graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Añade un arco desde el último nodo hasta el nodo actual (se le pasa como parametro)
|
|
||||||
private void añadirArcoSecuencialCFG(List<String> collector) {
|
|
||||||
System.out.println("NODO: " + nodoActual);
|
|
||||||
|
|
||||||
String arco = nodoAnterior + "->" + nodoActual + ";";
|
|
||||||
collector.add(arco);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear arcos
|
|
||||||
private void crearArcos(List<String> collector) {
|
|
||||||
añadirArcoSecuencialCFG(collector);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear nodo
|
|
||||||
// Añade un arco desde el nodo actual hasta el último control
|
|
||||||
private String crearNodo(Object objeto) {
|
|
||||||
return "\"(" + contador++ + ") " + quitarComillas(objeto.toString()) + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sustituye " por \" en un string: Sirve para eliminar comillas.
|
|
||||||
private static String quitarComillas(String texto) {
|
|
||||||
return texto.replace("\"", "\\\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dada una sentencia,
|
|
||||||
// Si es una <EFBFBD>nica instrucci<EFBFBD>n, devuelve un bloque equivalente
|
|
||||||
// Si es un bloque, lo devuelve
|
|
||||||
private BlockStmt convertirEnBloque(Statement statement) {
|
|
||||||
if (statement instanceof BlockStmt)
|
|
||||||
return (BlockStmt) statement;
|
|
||||||
|
|
||||||
BlockStmt block = new BlockStmt();
|
|
||||||
NodeList<Statement> blockStmts = new NodeList<Statement>();
|
|
||||||
blockStmts.add(statement);
|
|
||||||
|
|
||||||
block.setStatements(blockStmts);
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue