KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > groovy > syntax > Reduction


1 /*
2  $Id: Reduction.java,v 1.2 2004/04/30 09:57:46 cpoirier Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11     statements and notices. Redistributions must also contain a
12     copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15     above copyright notice, this list of conditions and the
16     following disclaimer in the documentation and/or other
17     materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20     products derived from this Software without prior written
21     permission of The Codehaus. For written permission,
22     please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25     nor may "groovy" appear in their names without prior written
26     permission of The Codehaus. "groovy" is a registered
27     trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30     http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46
47 package org.codehaus.groovy.syntax;
48
49 import org.codehaus.groovy.GroovyBugError;
50 import org.codehaus.groovy.syntax.CSTNode;
51 import org.codehaus.groovy.syntax.Token;
52
53 import java.util.List JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.Collections JavaDoc;
56
57
58 /**
59  * A syntax reduction, produced by the <code>Parser</code>.
60  *
61  * @see Parser
62  * @see Token
63  * @see CSTNode
64  * @see Types
65  *
66  * @author <a HREF="mailto:bob@werken.com">bob mcwhirter</a>
67  * @author <a HREF="mailto:cpoirier@dreaming.org">Chris Poirier</a>
68  *
69  * @version $Id: Reduction.java,v 1.2 2004/04/30 09:57:46 cpoirier Exp $
70  */

71
72 public class Reduction extends CSTNode
73 {
74     public static final Reduction EMPTY = new Reduction();
75
76
77   //---------------------------------------------------------------------------
78
// INITIALIZATION AND SUCH
79

80     private List JavaDoc elements = null; // The set of child nodes
81
private boolean marked = false; // Used for completion marking by some parts of the parser
82

83
84    /**
85     * Initializes the <code>Reduction</code> with the specified root.
86     */

87
88     public Reduction( Token root )
89     {
90         elements = new ArrayList JavaDoc();
91         set( 0, root );
92     }
93
94
95    /**
96     * Initializes the <code>Reduction</code> to empty.
97     */

98
99     private Reduction()
100     {
101         elements = Collections.EMPTY_LIST;
102     }
103
104
105    /**
106     * Creates a new <code>Reduction</code> with <code>Token.NULL</code>
107     * as it's root.
108     */

109
110     public static Reduction newContainer()
111     {
112         return new Reduction( Token.NULL );
113     }
114
115
116
117
118   //---------------------------------------------------------------------------
119
// MEMBER ACCESS
120

121
122    /**
123     * Returns true if the node is completely empty (no root, even).
124     */

125
126     public boolean isEmpty()
127     {
128         return size() == 0;
129     }
130
131
132
133    /**
134     * Returns the number of elements in the node.
135     */

136
137     public int size()
138     {
139         return elements.size();
140     }
141
142
143
144    /**
145     * Returns the specified element, or null.
146     */

147
148     public CSTNode get( int index )
149     {
150         CSTNode element = null;
151
152         if( index < size() )
153         {
154             element = (CSTNode)elements.get( index );
155         }
156
157         return element;
158     }
159
160
161
162    /**
163     * Returns the root of the node, the Token that indicates it's
164     * type. Returns null if there is no root (usually only if the
165     * node is a placeholder of some kind -- see isEmpty()).
166     */

167
168     public Token getRoot()
169     {
170         if( size() > 0 )
171         {
172             return (Token)elements.get(0);
173         }
174         else
175         {
176             return null;
177         }
178     }
179
180
181
182    /**
183     * Marks the node a complete expression.
184     */

185
186     public void markAsExpression()
187     {
188         marked = true;
189     }
190
191
192
193    /**
194     * Returns true if the node is a complete expression.
195     */

196
197     public boolean isAnExpression()
198     {
199         if( isA(Types.COMPLEX_EXPRESSION) )
200         {
201             return true;
202         }
203
204         return marked;
205     }
206
207
208
209
210   //---------------------------------------------------------------------------
211
// OPERATIONS
212

213
214    /**
215     * Adds an element to the node.
216     */

217
218     public CSTNode add( CSTNode element )
219     {
220         return set( size(), element );
221     }
222
223
224
225    /**
226     * Sets an element in at the specified index.
227     */

228
229     public CSTNode set( int index, CSTNode element )
230     {
231         
232         if( elements == null )
233         {
234             throw new GroovyBugError( "attempt to set() on a EMPTY Reduction" );
235         }
236
237         if( index == 0 && !(element instanceof Token) )
238         {
239
240             //
241
// It's not the greatest of design that the interface allows this, but it
242
// is a tradeoff with convenience, and the convenience is more important.
243

244             throw new GroovyBugError( "attempt to set() a non-Token as root of a Reduction" );
245         }
246
247
248         //
249
// Fill slots with nulls, if necessary.
250

251         int count = elements.size();
252         if( index >= count )
253         {
254             for( int i = count; i <= index; i++ )
255             {
256                 elements.add( null );
257             }
258         }
259
260         //
261
// Then set in the element.
262

263         elements.set( index, element );
264
265         return element;
266     }
267
268
269
270    /**
271     * Removes a node from the <code>Reduction</code>. You cannot remove
272     * the root node (index 0).
273     */

274
275     public CSTNode remove( int index )
276     {
277         if( index < 1 )
278         {
279             throw new GroovyBugError( "attempt to remove() root node of Reduction" );
280         }
281
282         return (CSTNode)elements.remove( index );
283     }
284
285
286
287    /**
288     * Creates a <code>Reduction</code> from this node. Returns self if the
289     * node is already a <code>Reduction</code>.
290     */

291
292     public Reduction asReduction()
293     {
294         return this;
295     }
296
297 }
298
299
Popular Tags