diff --git a/src/main/java/grafos/CFG.java b/src/main/java/grafos/CFG.java index ac8297a..f3d1a5a 100644 --- a/src/main/java/grafos/CFG.java +++ b/src/main/java/grafos/CFG.java @@ -24,8 +24,14 @@ public class CFG { System.out.println("NODO: " + node2str(stmt)); } - public void beginBlock(Node node) { - Block b = new Block(node, this); + public void beginBlock(Node node, Node condition) { + beginBlock(node, condition, true); + } + + public void beginBlock(Node node, Node condition, boolean addNow) { + Block b = new Block(node, condition, this); + if (condition != null && addNow) + addNode(condition); if (blockStack.isEmpty()) blocks.addFirst(b); else @@ -98,12 +104,13 @@ public class CFG { static class Block extends LinkedList { private static int clusterId = 0; - private final Node container; + private final Node container, condition; private final CFG cfg; private final List inners = new LinkedList<>(); - Block(Node container, CFG cfg) { + Block(Node container, Node condition, CFG cfg) { this.container = container; + this.condition = condition; this.cfg = cfg; } @@ -115,6 +122,10 @@ public class CFG { List res = new LinkedList<>(); res.add(gv.start_subgraph(clusterId++)); res.add("label = \"" + getTitle() + "\""); + if (condition != null) { + res.add("node [ shape = rectangle ]; " + cfg.node2str(condition)); + res.add("node [ shape = ellipse ]"); + } for (Block b : inners) { res.addAll(b.toStringList(gv)); } diff --git a/src/main/java/grafos/Visitador.java b/src/main/java/grafos/Visitador.java index 1e1e8d0..1012461 100755 --- a/src/main/java/grafos/Visitador.java +++ b/src/main/java/grafos/Visitador.java @@ -52,14 +52,14 @@ public class Visitador extends VoidVisitorAdapter { @Override public void visit(IfStmt n, CFG graph) { - graph.beginBlock(n); Node ifStart = n.getCondition(); - graph.addNode(ifStart); + graph.beginBlock(n, ifStart); graph.connect(prevNode, ifStart); // TODO: shortcut conditions (||, &&) prevNode = Collections.singletonList(ifStart); + graph.setNextLabel(true); List prevNodeBegin = prevNode; n.getThenStmt().accept(this, graph); List newPrev = new LinkedList<>(); @@ -67,6 +67,7 @@ public class Visitador extends VoidVisitorAdapter { newPrev.add(ifStart); else newPrev.addAll(prevNode); prevNode = Collections.singletonList(ifStart); + graph.setNextLabel(false); if (n.getElseStmt().isPresent()) { n.getElseStmt().get().accept(this, graph); if (prevNode == prevNodeBegin) @@ -81,36 +82,38 @@ public class Visitador extends VoidVisitorAdapter { @Override public void visit(WhileStmt n, CFG graph) { - graph.beginBlock(n); Node whileStart = n.getCondition(); - graph.addNode(whileStart); + graph.beginBlock(n, whileStart); graph.connect(prevNode, whileStart); // TODO: shortcut conditions (||, &&) prevNode = Collections.singletonList(whileStart); + graph.setNextLabel(true); n.getBody().accept(this, graph); graph.connect(prevNode, whileStart); prevNode = Collections.singletonList(whileStart); + graph.setNextLabel(false); graph.endBlock(); } @Override public void visit(DoStmt n, CFG graph) { - graph.beginBlock(n); Node condition = n.getCondition(); + graph.beginBlock(n, condition, false); prevNode = new LinkedList<>(prevNode); prevNode.add(condition); n.getBody().accept(this, graph); graph.addNode(condition); graph.connect(prevNode, condition); prevNode = Collections.singletonList(condition); + graph.setNextLabel(false); graph.endBlock(); } @Override public void visit(ForStmt n, CFG graph) { - graph.beginBlock(n); + graph.beginBlock(n, n.getCompare().orElse(null)); // Initialization expressions if (n.getInitialization() != null) { for (Expression e : n.getInitialization()) { @@ -125,6 +128,7 @@ public class Visitador extends VoidVisitorAdapter { graph.addNode(n.getCompare().get()); graph.connect(prevNode, n.getCompare().get()); prevNode = Collections.singletonList(n.getCompare().get()); + graph.setNextLabel(true); } // Loop body n.getBody().accept(this, graph); @@ -143,18 +147,18 @@ public class Visitador extends VoidVisitorAdapter { // TODO: connect last update / end of loop with first element of loop body } // Set comparison as last possible statement - if (n.getCompare().isPresent()) + if (n.getCompare().isPresent()) { prevNode = Collections.singletonList(n.getCompare().get()); - else // There is no comparison, can't exit the loop TODO implement break and continue as way to exit + graph.setNextLabel(false); + } else // There is no comparison, can't exit the loop TODO implement break and continue as way to exit prevNode = Collections.emptyList(); graph.endBlock(); } @Override public void visit(ForeachStmt n, CFG graph) { - graph.beginBlock(n); ForeachStmt copy = new ForeachStmt(n.getTokenRange().orElse(null), n.getVariable(), n.getIterable(), new EmptyStmt()); - graph.addNode(copy); + graph.beginBlock(n, copy); graph.connect(prevNode, copy); prevNode = Collections.singletonList(copy); n.getBody().accept(this, graph); @@ -176,10 +180,9 @@ public class Visitador extends VoidVisitorAdapter { @Override public void visit(SwitchStmt n, CFG graph) { - graph.beginBlock(n); // Link previous statement to the switch's selector Node selectorNode = n.getSelector(); - graph.addNode(selectorNode); + graph.beginBlock(n, selectorNode); graph.connect(prevNode, selectorNode); // Analyze switch's cases prevNode = Collections.singletonList(selectorNode);