Moved from List<String> to CFG object

This commit is contained in:
Carlos Galindo 2019-03-26 22:25:52 +01:00
parent 0e5667582b
commit 221c9e6b23
Signed by untrusted user who does not match committer: kauron
GPG Key ID: 83E68706DEE119A3
3 changed files with 95 additions and 82 deletions

View 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("\"", "\\\"") + "\"";
}
}

View File

@ -7,8 +7,6 @@ import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.visitor.VoidVisitor;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Transformador {
@ -25,12 +23,18 @@ public class Transformador {
quitarComentarios(cu);
// Recorremos el AST
List<String> arcos = new ArrayList<String>();
VoidVisitor<List<String>> visitador = new Visitador();
visitador.visit(cu, arcos);
CFG graph = new CFG();
VoidVisitor<CFG> visitador = new Visitador();
visitador.visit(cu, graph);
// Imprimimos el CFG del programa
String dotInfo = imprimirGrafo(arcos);
// Imprimimos el CFG del program
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
System.out.print("\nGenerando PDF...");
@ -49,19 +53,6 @@ public class Transformador {
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
private static void quitarComentarios(Node node) {
node.removeComment();

View File

@ -1,24 +1,16 @@
package grafos;
import com.github.javaparser.ast.NodeList;
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.Statement;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import java.util.List;
public class Visitador extends VoidVisitorAdapter<List<String>> {
public class Visitador extends VoidVisitorAdapter<CFG> {
//********************************************************/
//********************** Atributos ***********************/
//********************************************************/
// Usamos un contador para numerar las instrucciones
private int contador = 1;
private String nodoAnterior = "Start";
private String nodoActual = "";
private Statement prevNode;
//********************************************************/
//*********************** Metodos ************************/
@ -27,67 +19,27 @@ public class Visitador extends VoidVisitorAdapter<List<String>> {
// Visitador de métodos
// Este visitador añade el nodo final al CFG
@Override
public void visit(MethodDeclaration methodDeclaration, List<String> collector) {
public void visit(MethodDeclaration methodDeclaration, CFG graph) {
prevNode = graph.beginNode();
// Visitamos el método
super.visit(methodDeclaration, collector);
super.visit(methodDeclaration, graph);
// 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
// Cada expresión encontrada genera un nodo en el CFG
@Override
public void visit(ExpressionStmt es, List<String> collector) {
// Creamos el nodo actual
nodoActual = crearNodo(es);
crearArcos(collector);
nodoAnterior = nodoActual;
public void visit(ExpressionStmt es, CFG graph) {
graph.addNode(es);
graph.connect(prevNode, es);
prevNode = es;
// 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;
}
}