KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > percederberg > grammatica > parser > ProductionPattern


1 /*
2  * ProductionPattern.java
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1
7  * of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307, USA.
18  *
19  * Copyright (c) 2003-2005 Per Cederberg. All rights reserved.
20  */

21
22 package net.percederberg.grammatica.parser;
23
24 import java.util.ArrayList JavaDoc;
25
26 /**
27  * A production pattern. This class represents a set of production
28  * alternatives that together forms a single production. A production
29  * pattern is identified by an integer id and a name, both provided
30  * upon creation. The pattern id is used for referencing the
31  * production pattern from production pattern elements.
32  *
33  * @author Per Cederberg, <per at percederberg dot net>
34  * @version 1.0
35  */

36 public class ProductionPattern {
37
38     /**
39      * The production pattern identity.
40      */

41     private int id;
42
43     /**
44      * The production pattern name.
45      */

46     private String JavaDoc name;
47
48     /**
49      * The synthectic production flag. If this flag is set, the
50      * production identified by this pattern has been artificially
51      * inserted into the grammar.
52      */

53     private boolean synthetic;
54
55     /**
56      * The list of production pattern alternatives.
57      */

58     private ArrayList JavaDoc alternatives;
59
60     /**
61      * The default production pattern alternative. This alternative
62      * is used when no other alternatives match. It may be set to
63      * -1, meaning that there is no default (or fallback) alternative.
64      */

65     private int defaultAlt;
66
67     /**
68      * The look-ahead set associated with this pattern.
69      */

70     private LookAheadSet lookAhead;
71
72     /**
73      * Creates a new production pattern.
74      *
75      * @param id the production pattern id
76      * @param name the production pattern name
77      */

78     public ProductionPattern(int id, String JavaDoc name) {
79         this.id = id;
80         this.name = name;
81         this.synthetic = false;
82         this.alternatives = new ArrayList JavaDoc();
83         this.defaultAlt = -1;
84         this.lookAhead = null;
85     }
86
87     /**
88      * Checks if the synthetic production flag is set. If this flag is
89      * set, the production identified by this pattern has been
90      * artificially inserted into the grammar. No parse tree nodes
91      * will be created for such nodes, instead the child nodes will
92      * be added directly to the parent node.
93      *
94      * @return true if this production pattern is synthetic, or
95      * false otherwise
96      *
97      * @since 1.5
98      */

99     public boolean isSynthetic() {
100         return synthetic;
101     }
102
103     /**
104      * Checks if the synthetic production flag is set. If this flag is
105      * set, the production identified by this pattern has been
106      * artificially inserted into the grammar. No parse tree nodes
107      * will be created for such nodes, instead the child nodes will
108      * be added directly to the parent node.
109      *
110      * @return true if this production pattern is synthetic, or
111      * false otherwise
112      *
113      * @deprecated Use the isSynthetic() method instead. This method
114      * name contained a spelling error.
115      */

116     public boolean isSyntetic() {
117         return isSynthetic();
118     }
119
120     /**
121      * Checks if this pattern is recursive on the left-hand side. This
122      * method checks if any of the production pattern alternatives is
123      * left-recursive.
124      *
125      * @return true if at least one alternative is left recursive, or
126      * false otherwise
127      */

128     public boolean isLeftRecursive() {
129         ProductionPatternAlternative alt;
130
131         for (int i = 0; i < alternatives.size(); i++) {
132             alt = (ProductionPatternAlternative) alternatives.get(i);
133             if (alt.isLeftRecursive()) {
134                 return true;
135             }
136         }
137         return false;
138     }
139
140     /**
141      * Checks if this pattern is recursive on the right-hand side.
142      * This method checks if any of the production pattern
143      * alternatives is right-recursive.
144      *
145      * @return true if at least one alternative is right recursive, or
146      * false otherwise
147      */

148     public boolean isRightRecursive() {
149         ProductionPatternAlternative alt;
150
151         for (int i = 0; i < alternatives.size(); i++) {
152             alt = (ProductionPatternAlternative) alternatives.get(i);
153             if (alt.isRightRecursive()) {
154                 return true;
155             }
156         }
157         return false;
158     }
159
160     /**
161      * Checks if this pattern would match an empty stream of tokens.
162      * This method checks if any one of the production pattern
163      * alternatives would match the empty token stream.
164      *
165      * @return true if at least one alternative match no tokens, or
166      * false otherwise
167      */

168     public boolean isMatchingEmpty() {
169         ProductionPatternAlternative alt;
170
171         for (int i = 0; i < alternatives.size(); i++) {
172             alt = (ProductionPatternAlternative) alternatives.get(i);
173             if (alt.isMatchingEmpty()) {
174                 return true;
175             }
176         }
177         return false;
178     }
179
180     /**
181      * Returns the unique production pattern identity value.
182      *
183      * @return the production pattern id
184      */

185     public int getId() {
186         return id;
187     }
188
189     /**
190      * Returns the production pattern name.
191      *
192      * @return the production pattern name
193      */

194     public String JavaDoc getName() {
195         return name;
196     }
197
198     /**
199      * Sets the synthetic production pattern flag. If this flag is set,
200      * the production identified by this pattern has been artificially
201      * inserted into the grammar. By default this flag is set to
202      * false.
203      *
204      * @param synthetic the new value of the synthetic flag
205      *
206      * @since 1.5
207      */

208     public void setSynthetic(boolean synthetic) {
209         this.synthetic = synthetic;
210     }
211
212     /**
213      * Sets the synthetic production pattern flag. If this flag is set,
214      * the production identified by this pattern has been artificially
215      * inserted into the grammar. By default this flag is set to
216      * false.
217      *
218      * @param synthetic the new value of the synthetic flag
219      *
220      * @deprecated Use the setSynthetic() method instead. This method
221      * name contained a spelling error.
222      */

223     public void setSyntetic(boolean synthetic) {
224         setSynthetic(synthetic);
225     }
226
227     /**
228      * Returns the number of alternatives in this pattern.
229      *
230      * @return the number of alternatives in this pattern
231      */

232     public int getAlternativeCount() {
233         return alternatives.size();
234     }
235
236     /**
237      * Returns an alternative in this pattern.
238      *
239      * @param pos the alternative position, 0 <= pos < count
240      *
241      * @return the alternative found
242      */

243     public ProductionPatternAlternative getAlternative(int pos) {
244         return (ProductionPatternAlternative) alternatives.get(pos);
245     }
246
247     /**
248      * Adds a production pattern alternative.
249      *
250      * @param alt the production pattern alternative to add
251      *
252      * @throws ParserCreationException if an identical alternative has
253      * already been added
254      */

255     public void addAlternative(ProductionPatternAlternative alt)
256         throws ParserCreationException {
257
258         if (alternatives.contains(alt)) {
259             throw new ParserCreationException(
260                 ParserCreationException.INVALID_PRODUCTION_ERROR,
261                 name,
262                 "two identical alternatives exist");
263         }
264         alt.setPattern(this);
265         alternatives.add(alt);
266     }
267
268     /**
269      * Returns a string representation of this object.
270      *
271      * @return a token string representation
272      */

273     public String JavaDoc toString() {
274         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
275         StringBuffer JavaDoc indent = new StringBuffer JavaDoc();
276         int i;
277
278         buffer.append(name);
279         buffer.append("(");
280         buffer.append(id);
281         buffer.append(") ");
282         for (i = 0; i < buffer.length(); i++) {
283             indent.append(" ");
284         }
285         for (i = 0; i < alternatives.size(); i++) {
286             if (i == 0) {
287                 buffer.append("= ");
288             } else {
289                 buffer.append("\n");
290                 buffer.append(indent);
291                 buffer.append("| ");
292             }
293             buffer.append(alternatives.get(i));
294         }
295         return buffer.toString();
296     }
297
298     /**
299      * Returns the look-ahead set associated with this alternative.
300      *
301      * @return the look-ahead set associated with this alternative
302      */

303     LookAheadSet getLookAhead() {
304         return lookAhead;
305     }
306
307     /**
308      * Sets the look-ahead set for this alternative.
309      *
310      * @param lookAhead the new look-ahead set
311      */

312     void setLookAhead(LookAheadSet lookAhead) {
313         this.lookAhead = lookAhead;
314     }
315
316     /**
317      * Returns the default pattern alternative. The default
318      * alternative is used when no other alternative matches.
319      *
320      * @return the default pattern alternative, or
321      * null if none has been set
322      */

323     ProductionPatternAlternative getDefaultAlternative() {
324         if (defaultAlt >= 0) {
325             Object JavaDoc obj = alternatives.get(defaultAlt);
326             return (ProductionPatternAlternative) obj;
327         } else {
328             return null;
329         }
330     }
331
332     /**
333      * Sets the default pattern alternative. The default alternative
334      * is used when no other alternative matches.
335      *
336      * @param pos the position of the default alternative
337      */

338     void setDefaultAlternative(int pos) {
339         if (pos >= 0 && pos < alternatives.size()) {
340             this.defaultAlt = pos;
341         }
342     }
343 }
344
Popular Tags