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
package cfg;
import cfg.CFG.Symbol;
import java.util.Objects;
public class ASTNode {
private final boolean isTerminal;
private final ASTNode[] children;
private final Symbol symbol;
public ASTNode(Symbol symbol, ASTNode[] children, boolean isTerminal) {
this.symbol = symbol;
this.children = children;
this.isTerminal = isTerminal;
}
public ASTNode(Symbol symbol, ASTNode[] children) {
this(symbol, children, false);
}
public ASTNode(Symbol symbol) {
this(symbol, null, true);
}
public String toString() {
if (this.isTerminal) {
return this.symbol.toString();
} else {
StringBuilder s = new StringBuilder();
for (ASTNode child : this.getChildren()) {
s.append(child.toString());
}
return s.toString();
}
}
public boolean isTerminal() {
return this.isTerminal;
}
public ASTNode[] getChildren() {
return this.children;
}
public String getValue() {
return this.symbol.toString();
}
public int numChildren() {
return this.children == null ? 0 : this.children.length;
}
public ASTNode getLeftChild() {
return this.children[0];
}
public ASTNode getRightChild() {
return this.children[this.children.length - 1];
}
/**
* Collapse the parse tree.
*
* @return a tree where no nonterminal node has a single child
*/
public ASTNode collapse() {
if (this.children == null || this.isTerminal)
return this;
// Collapse nodes with a single child
if (children.length == 1)
return children[0].collapse();
for (int i = 0; i < children.length; i++) {
children[i] = children[i].collapse();
}
return this;
}
}