1 package org.kit.furia.fragment;
2
3 import java.util.LinkedList;
4 import java.util.List;
5
6 import antlr.BaseAST;
7 import antlr.Token;
8 import antlr.collections.AST;
9
10 /*
11 Furia-chan: An Open Source software license violation detector.
12 Copyright (C) 2007 Kyushu Institute of Technology
13
14 This program is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /**
29 * This class provides extra functionality required by tree edit distance
30 * algorithms and the like.
31 * @author Arnoldo Jose Muller Molina
32 * @since 0
33 */
34
35 public class FragmentAST
36 extends BaseAST {
37
38
39
40 /**
41 * Number of children this node has.
42 */
43 public int decendants = -1;
44
45 /**
46 * The text of this node.
47 */
48 public String text;
49
50 /**
51 * Updates descendants information.
52 * @return An integer that represents the number of children of this node.
53 */
54 public final int updateDecendantInformationAux() {
55 decendants = 0;
56 FragmentAST n = getLeftmostChild();
57 while (n != null) {
58 decendants += n.updateDecendantInformationAux();
59 n = (FragmentAST) n.getNextSibling();
60 }
61 return decendants + 1;
62 }
63
64 /**
65 * Updates descendants information.
66 */
67 public final void updateDecendantInformation() {
68 decendants = updateDecendantInformationAux();
69 }
70
71 /**
72 * Returns the number of decendants of this node.
73 * @return The number of children of this node.
74 */
75 public final int getDescendants() {
76 return decendants;
77 }
78
79 /**
80 * @return The size of the Tree (includes the root node)
81 */
82 public final int getSize() {
83 return this.decendants;
84 }
85
86 /**
87 * Get the token text for this node.
88 * @return The text of the node.
89 */
90 @Override
91 public final String getText() {
92 return text;
93 }
94
95 /**
96 * Get the token type for this node.
97 * @return The type of node
98 */
99 @Override
100 public final int getType() {
101 return -1;
102 }
103
104 /**
105 * Initialize the node.
106 * @param t
107 * Node type
108 * @param txt
109 * Node tag
110 */
111 public final void initialize(final int t, final String txt) {
112 setType(t);
113 setText(txt);
114 }
115
116 /**
117 * Initialize the node from another node.
118 * @param t
119 * Another node.
120 */
121 public final void initialize(final AST t) {
122 setText(t.getText());
123 setType(t.getType());
124 }
125
126 /**
127 * Default constructor.
128 */
129 public FragmentAST() {
130 }
131
132 /**
133 * Initialize the node.
134 * @param t
135 * Node type
136 * @param txt
137 * Node text
138 */
139 public FragmentAST(final int t, final String txt) {
140 text = txt;
141 }
142
143 /**
144 * Initialize the node from a token.
145 * @param tok
146 * The token to use as initializer.
147 */
148 public FragmentAST(final Token tok) {
149 text = tok.getText();
150 }
151
152 /**
153 * Clone the node with this constructor.
154 * @param t
155 * Another SliceAST
156 */
157 public FragmentAST(final FragmentAST t) {
158 text = t.text;
159 }
160
161 /**
162 * Initialize from the given token.
163 * @param tok
164 * A token.
165 */
166 @Override
167 public final void initialize(final Token tok) {
168 setText(tok.getText());
169 setType(tok.getType());
170 }
171
172 /**
173 * Set the token text for this node.
174 * @param text_
175 * The text to use.
176 */
177 @Override
178 public final void setText(final String text_) {
179 text = text_;
180 }
181
182 /**
183 * Set the token type for this node. Currently ignored.
184 * @param ttype_
185 * Type to use
186 */
187 @Override
188 public final void setType(final int ttype_) {
189
190 }
191
192 /**
193 * Get the leftmost child of this node.
194 * @return The leftmost child of this node.
195 */
196 public final FragmentAST getLeftmostChild() {
197 return (FragmentAST) super.getFirstChild();
198 }
199
200 /**
201 * Print out a child-sibling tree in LISP notation.
202 * @return A child-sibling tree in LISP notation
203 */
204 public final String prettyPrint() {
205 final FragmentAST t = this;
206 String ts = "";
207 if (t.getFirstChild() != null)
208 ts += " (";
209 ts += " " + toString();
210 if (t.getFirstChild() != null) {
211 ts += ((FragmentAST) t.getFirstChild()).prettyPrint();
212 }
213 if (t.getFirstChild() != null)
214 ts += " )";
215 if (t.getNextSibling() != null) {
216 ts += ((FragmentAST) t.getNextSibling()).prettyPrint();
217 }
218 return ts;
219 }
220
221
222
223
224
225
226
227 /** Get the first child of this node; null if not children */
228 public final AST getFirstChild() {
229 return down;
230 }
231
232 /** Get the next sibling in line after this one */
233 public final AST getNextSibling() {
234 return right;
235 }
236
237
238 /**
239 * @return A list of the nodes in depth first order
240 */
241 public final synchronized List < FragmentAST > depthFirst() {
242 final LinkedList < FragmentAST > res = new LinkedList < FragmentAST >();
243 depthFirstAux(res);
244 return res;
245 }
246
247 /**
248 * Auxiliary function for {@link #depthFirst()}.
249 * @param res
250 * Where the result will be stored.
251 */
252 protected final void depthFirstAux(final LinkedList < FragmentAST > res) {
253 res.add(this);
254 final FragmentAST down = (FragmentAST) getFirstChild();
255 if (down != null) {
256 down.depthFirstAux(res);
257 }
258 final FragmentAST right = (FragmentAST) getNextSibling();
259 if (right != null) {
260 right.depthFirstAux(res);
261 }
262 }
263
264 public final String toFuriaChanTree() {
265 StringBuilder sb = new StringBuilder();
266 toFuriaChanTreeAux(sb);
267 return sb.toString();
268 }
269
270 private final void toFuriaChanTreeAux(StringBuilder ts) {
271 AST t = this;
272 ts.append(this.toString());
273 if (t.getFirstChild() != null) {
274 ts.append("(");
275
276 ((FragmentAST) t.getFirstChild()).toFuriaChanTreeAux(ts);
277
278 ts.append(")");
279 }
280 if (t.getNextSibling() != null) {
281 ts.append(",");
282 ((FragmentAST) t.getNextSibling()).toFuriaChanTreeAux(ts);
283 }
284 }
285
286 }