View Javadoc

1   package net.obsearch.example.ted;
2   
3   import java.util.BitSet;
4   import java.util.HashSet;
5   import java.util.LinkedList;
6   import java.util.List;
7   
8   
9   import antlr.BaseAST;
10  import antlr.CommonAST;
11  import antlr.Token;
12  import antlr.collections.AST;
13  
14  /*
15   Furia-chan: An Open Source software license violation detector.    
16   Copyright (C) 2008 Kyushu Institute of Technology
17  
18   This program is free software: you can redistribute it and/or modify
19   it under the terms of the GNU General Public License as published by
20   the Free Software Foundation, either version 3 of the License, or
21   (at your option) any later version.
22  
23   This program is distributed in the hope that it will be useful,
24   but WITHOUT ANY WARRANTY; without even the implied warranty of
25   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26   GNU General Public License for more details.
27  
28   You should have received a copy of the GNU General Public License
29   along with this program.  If not, see <http://www.gnu.org/licenses/>.
30   */
31  
32  /**
33   * SliceAST This class provides extra functionality required by tree edit
34   * distance algorithms and the like
35   * @author Arnoldo Jose Muller Molina
36   */
37  
38  public class SliceAST
39          extends BaseAST {
40  
41      protected int decendants = -1;
42  
43      protected String text;
44  
45      public int updateDecendantInformation() {
46          decendants = 0;
47          SliceAST n = (SliceAST) this.getLeftmostChild();
48          while (n != null) {
49              decendants += n.updateDecendantInformation();
50              n = (SliceAST) n.getNextSibling();
51          }
52          return decendants + 1;
53      }
54  
55      /*
56       * public int getDescendants(){ int decendants = 0; SliceAST n =
57       * this.getLeftmostChild(); while(n != null){ decendants +=
58       * n.getDescendants(); decendants++; n = (SliceAST)n.getNextSibling(); }
59       * return decendants; }
60       */
61  
62      public int getDescendants() {
63          if (decendants == -1) {
64              this.updateDecendantInformation();
65          }
66          return decendants;
67      }
68  
69      public int getSize() {
70          return getDescendants() + 1;
71      }
72  
73      public SliceAST findFirstNodeThatMatches(String label) {
74          SliceAST result = null;
75          if (this.text.equals(label)) {
76              result = this;
77          } else {
78              SliceAST n = this.getLeftmostChild();
79              while (n != null && result == null) {
80                  result = n.findFirstNodeThatMatches(label);
81                  n = (SliceAST) n.getNextSibling();
82              }
83          }
84          return result;
85      }
86  
87      /** Get the token text for this node */
88      public String getText() {
89          return text;
90      }
91  
92      /** Get the token type for this node */
93      public int getType() {
94          return -1;
95      }
96  
97      public void initialize(int t, String txt) {
98          setType(t);
99          setText(txt);
100     }
101 
102     public void initialize(AST t) {
103         setText(t.getText());
104         setType(t.getType());
105     }
106 
107     public SliceAST() {
108     }
109 
110     public SliceAST(int t, String txt) {
111         initialize(t, txt);
112     }
113 
114     public SliceAST(Token tok) {
115         initialize(tok);
116     }
117 
118     public SliceAST(SliceAST t) {
119         initialize(-1, t.text);
120     }
121 
122     public void initialize(Token tok) {
123         setText(tok.getText());
124         setType(tok.getType());
125     }
126 
127     /** Set the token text for this node */
128     public void setText(String text_) {
129         text = text_;
130     }
131 
132     /** Set the token type for this node */
133     public void setType(int ttype_) {
134 
135     }
136 
137     public SliceAST getLeftmostChild() {
138         return (SliceAST) super.getFirstChild();
139     }
140 
141     /** Print out a child-sibling tree in LISP notation */
142     public String prettyPrint() {
143         SliceAST t = this;
144         String ts = "";
145         if (t.getFirstChild() != null)
146             ts += " (";
147         ts += " " + this.toString();
148         if (t.getFirstChild() != null) {
149             ts += ((SliceAST) t.getFirstChild()).prettyPrint();
150         }
151         if (t.getFirstChild() != null)
152             ts += " )";
153         if (t.getNextSibling() != null) {
154             ts += ((SliceAST) t.getNextSibling()).prettyPrint();
155         }
156         return ts;
157     }
158 
159     /** Print out a child-sibling tree in Q notation */
160     public String toQ() {
161         SliceAST t = this;
162         String ts = "";
163         ts += this.toString();
164         if (t.getFirstChild() != null) {
165             ts += "(";
166             ts += ((SliceAST) t.getFirstChild()).toQ();
167             ts += ")";
168         }
169 
170         if (t.getNextSibling() != null) {
171             ts += ",";
172             ts += ((SliceAST) t.getNextSibling()).toQ();
173         }
174 
175         return ts;
176     }
177 
178     /*
179      * little speed up to the normal equalsTree method
180      * @see antlr.BaseAST#equalsTree(antlr.collections.AST)
181      */
182     public boolean equalsTree(AST t) {
183         SliceAST j = (SliceAST) t;
184         if (j.getSize() != this.getSize()) { // little speed up! ;)
185             return false;
186         } else {
187             return super.equalsTree(t);
188         }
189     }
190 
191     /*
192      * 1 = equal 0 = not equal 2 = equal if we rename the root 3 = children not
193      * equal but the same root
194      * @see antlr.BaseAST#equalsTree(antlr.collections.AST)
195      */
196     public int detailedTreeComparison(AST t) {
197         SliceAST j = (SliceAST) t;
198         if (j.getSize() != this.getSize()) { // little speed up! ;)
199             if (this.equals(t)) {
200                 return 3;
201             } else {
202                 return 0;
203             }
204         } else {
205             return detailedTreeAux(t);
206         }
207     }
208 
209     /**
210      * Is tree rooted at 'this' equal to 't'? The siblings of 'this' are
211      * ignored.
212      */
213     protected int detailedTreeAux(AST t) {
214         int res = -1;
215         // check roots first.
216 
217         // if roots match, do full list match test on children.
218         if (this.getFirstChild() != null) {
219             if (this.getFirstChild().equalsList(t.getFirstChild())) {
220                 res = 2;
221             } else {
222                 res = 0;
223             }
224         }
225         // sibling has no kids, make sure t doesn't either
226         else if (t.getFirstChild() != null) {
227             res = 0;
228         }
229 
230         if (this.equals(t) && (res == 2 || res == -1)) {
231             res = 1;
232         }
233         if (res == -1) {
234             res = 0;
235         }
236         if (this.equals(t) && res == 0) {
237             res = 3;
238         }
239 
240         return res;
241     }
242 
243     /*
244      * get a list of the nodes in depth first order
245      */
246     public synchronized List < SliceAST > depthFirst() {
247         LinkedList < SliceAST > res = new LinkedList < SliceAST >();
248         depthFirstAux(res);
249         return res;
250     }
251 
252     protected void depthFirstAux(LinkedList < SliceAST > res) {
253         res.add(this);
254         SliceAST down = (SliceAST) this.getFirstChild();
255         if (down != null) {
256             down.depthFirstAux(res);
257         }
258         SliceAST right = (SliceAST) this.getNextSibling();
259         if (right != null) {
260             right.depthFirstAux(res);
261         }
262     }
263 
264     // TODO refactor all these things. hack to keep the unit tests working
265     // dummy
266     /**
267      * public int updateDecendantInformation(){ assert false; return -1; }
268      */
269     // dummy
270     public void updateIdInfo() {
271         assert false;
272     }
273 
274     // dummy
275     public void updateContains() {
276         assert false;
277     }
278 
279     // dummy
280     public int getId() {
281         assert false;
282         return -1;
283     }
284 
285     // dummy
286     public boolean containsNode(int i) {
287         assert false;
288         return false;
289     }
290 
291     public final void toFuriaChanTreeAux(StringBuilder ts) {
292         
293         AST t = this;
294         ts.append(this.toString());
295         if (t.getFirstChild() != null) {
296             ts.append("(");
297 
298             ((SliceAST) t.getFirstChild()).toFuriaChanTreeAux(ts);
299 
300             ts.append(")");
301         }
302         if(t.getNextSibling() != null){
303             ts.append(",");
304             ((SliceAST)t.getNextSibling()).toFuriaChanTreeAux(ts);
305         }
306     }
307 }