-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathGraphVisitor.java
124 lines (116 loc) · 4.26 KB
/
GraphVisitor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import analysis.DepthFirstAdapter;
import node.*;
import java.util.HashMap;
import java.util.LinkedList;
public class GraphVisitor extends DepthFirstAdapter{
private LinkedList<Block> blocks = new LinkedList<Block>();
private Block lastBlock;
private Block currentBlock;
private int blockID = 1;
private HashMap<Integer, Integer> addSuccessors = new HashMap<Integer, Integer>();
private LinkedList<Integer> removeSuccessors = new LinkedList<Integer>();
/**
* Define Def and Use in the current block
*/
@Override
public void caseAAssignmentExpr(AAssignmentExpr node) {
String identifier = node.getIdentifier().toString().toLowerCase().replaceAll(" ","");
currentBlock = new Block(identifier, blockID++);
node.getExpr().apply(this); // evaluate the expression
setNextSuccessor();
}
/**
* For writeln(). Nearly same as Assignment
*/
@Override
public void caseAPrintExpr(APrintExpr node) {
currentBlock = new Block(blockID++);
node.getExpr().apply(this); // evaluate the expression
setNextSuccessor();
}
/**
* If then
*/
@Override
public void caseAIfThenExpr(AIfThenExpr node) {
int temp = blockID;
currentBlock = new Block(blockID++);
node.getLeft().apply(this); // evaluate the expression
setNextSuccessor();
node.getRight().apply(this);
addSuccessors.put(temp, blockID);
}
/**
* If then else
*/
@Override
public void caseAIfThenElseExpr(AIfThenElseExpr node) {
int thenPointer, flow; // flow = next step after ifthenelse
int ifPointer = blockID;
currentBlock = new Block(blockID++);
node.getIf().apply(this); // evaluate the expression
setNextSuccessor();
node.getThen().apply(this);
thenPointer = blockID-1; // last element of then
addSuccessors.put(ifPointer, blockID);
node.getElse().apply(this);
flow = blockID;
// because of the normal algorithm according to setStartAndSuccessor() I need to remove the
// first successor, because this one points to else, which is simply wrong at this point.
removeSuccessors.add(thenPointer-1);
addSuccessors.put(thenPointer, flow); // Add normal program flow after the then block
}
/**
* While
*/
@Override
public void caseAWhileExpr(AWhileExpr node) {
int temp = blockID;
currentBlock = new Block(blockID++);
node.getLeft().apply(this); // evaluate the expression
setNextSuccessor();
node.getRight().apply(this);
addSuccessors.put(temp, blockID); // Add second successor for while loop
addSuccessors.put(blockID - 1, temp);
removeSuccessors.add(blockID - 1); // Remove later the first successor
}
/**
* Add to the current visited block a new item to the Use list
*/
@Override
public void caseAIdentifierExpr(AIdentifierExpr node) {
String identifier = node.getIdentifier().toString().toLowerCase().replaceAll(" ","");
if (currentBlock != null) {
if (!currentBlock.hasUse()) {
currentBlock.addUse(identifier);
} else {
if (!currentBlock.getUse().contains(identifier)) {
currentBlock.addUse(identifier);
}
}
}
}
public void exitNode() {
currentBlock = new Block(blockID++);
setNextSuccessor();
}
/**
* Method to set the standard successor for one node
*/
private void setNextSuccessor() {
if (lastBlock != null) // if it is the first block, do nothing
lastBlock.addSuccessor(currentBlock);
blocks.add(currentBlock); // Add currentBlock to the global list of blocks
lastBlock = currentBlock;
}
/************************************************************************************************/
public HashMap<Integer, Integer> getAddSuccessors() {
return addSuccessors;
}
public LinkedList<Integer> getRemoveSuccessors() {
return removeSuccessors;
}
public LinkedList<Block> getBlocks() {
return blocks;
}
}