View Javadoc

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 }