KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chaperon > model > extended > ExtendedGrammar


1 /*
2  * Copyright (C) Chaperon. All rights reserved.
3  * -------------------------------------------------------------------------
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE file.
7  */

8
9 package net.sourceforge.chaperon.model.extended;
10
11 import net.sourceforge.chaperon.model.Violations;
12
13 import java.io.Serializable JavaDoc;
14
15 /**
16  * This class represents a model for a grammar. The content of the grammar includes the
17  * definitions, start symbol, associativities and priorities.
18  *
19  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels </a>
20  * @version CVS $Id: ExtendedGrammar.java,v 1.19 2004/01/08 11:30:52 benedikta Exp $
21  */

22 public class ExtendedGrammar implements Serializable JavaDoc, Cloneable JavaDoc
23 {
24   // Start symbol
25
private String JavaDoc startSymbol = null;
26
27   // Definitions
28
private Definition[] definitions = new Definition[0];
29   private String JavaDoc location = null;
30   private BeginOfText BOT = new BeginOfText();
31   private EndOfText EOT = new EndOfText();
32
33   /**
34    * Creates an empty grammar.
35    */

36   public ExtendedGrammar() {}
37
38   /**
39    * Add a definition to this grammar.
40    *
41    * @param definition Definition, which should be added.
42    *
43    * @return Index of the definition in this grammar.
44    */

45   public void addDefinition(Definition definition)
46   {
47     if (definition==null)
48       throw new NullPointerException JavaDoc();
49
50     for (PatternIterator i = definition.getAllPattern().getPattern(); i.hasNext();)
51     {
52       Pattern pattern = i.next();
53       pattern.setDefinition(definition);
54     }
55
56     Definition[] newDefinitions = new Definition[definitions.length+1];
57     System.arraycopy(definitions, 0, newDefinitions, 0, definitions.length);
58     newDefinitions[definitions.length] = definition;
59     definitions = newDefinitions;
60   }
61
62   /**
63    * Return a definition giving by an index.
64    *
65    * @param index Index of the Definition.
66    *
67    * @return The definition.
68    */

69   public Definition getDefinition(int index)
70   {
71     return definitions[index];
72   }
73
74   /**
75    * Returns all definition for given nonterminal symbol as a list of indices.
76    *
77    * @param ntsymbol Nonterminal symbol
78    *
79    * @return List of indices from the definitions
80    */

81   public Definition getDefinition(String JavaDoc symbol)
82   {
83     for (int i = 0; i<definitions.length; i++)
84       if (definitions[i].getSymbol().equals(symbol))
85         return definitions[i];
86
87     return null;
88   }
89
90   public Definition[] getDefinitions()
91   {
92     return definitions;
93   }
94
95   /**
96    * Returns the count of definitions in this grammar.
97    *
98    * @return Count of definitions.
99    */

100   public int getDefinitionCount()
101   {
102     return definitions.length;
103   }
104
105   public PatternSet getAllPattern()
106   {
107     PatternSet set = new PatternSet();
108
109     for (int i = 0; i<definitions.length; i++)
110       set.addPattern(definitions[i].getAllPattern());
111
112     set.addPattern(BOT);
113     set.addPattern(EOT);
114
115     return set;
116   }
117
118   public void update()
119   {
120     for (int i = 0; i<definitions.length; i++)
121       definitions[i].update();
122
123     updateAscendingSuccessors();
124     updateDescendingSuccessors();
125   }
126
127   public void updateAscendingSuccessors()
128   {
129     for (PatternIterator successors = getFirstSet(getStartSymbol()).getPattern();
130          successors.hasNext();)
131     {
132       Pattern succesor = successors.next();
133       BOT.addAscendingSuccessor(succesor);
134     }
135
136     boolean modified;
137     do
138     {
139       modified = false;
140       for (PatternIterator successors = getAllPattern().getPattern(); successors.hasNext();)
141       {
142         Pattern successor = successors.next();
143
144         if (successor.getSymbol()!=null)
145         {
146           PatternSet firstSet = getFirstSet(successor.getSymbol());
147
148           for (PatternIterator ancestors = successor.getAncestors(); ancestors.hasNext();)
149           {
150             Pattern ancestor = ancestors.next();
151
152             for (PatternIterator i = firstSet.getPattern(); i.hasNext();)
153             {
154               Pattern firstPattern = i.next();
155               modified |= ancestor.addAscendingSuccessor(firstPattern);
156             }
157           }
158
159           for (PatternIterator ancestors = successor.getAscendingAncestors(); ancestors.hasNext();)
160           {
161             Pattern ancestor = ancestors.next();
162
163             for (PatternIterator i = firstSet.getPattern(); i.hasNext();)
164             {
165               Pattern firstPattern = i.next();
166               modified |= ancestor.addAscendingSuccessor(firstPattern);
167             }
168           }
169         }
170       }
171     }
172     while (modified);
173   }
174
175   public boolean isNullable(String JavaDoc symbol)
176   {
177     for (int i = 0; i<definitions.length; i++)
178       if (definitions[i].getSymbol().equals(symbol))
179         return definitions[i].isNullable();
180
181     return true;
182   }
183
184   public PatternSet getFirstSet(String JavaDoc symbol)
185   {
186     PatternSet firstSet = new PatternSet();
187
188     for (int i = 0; i<definitions.length; i++)
189       if (definitions[i].getSymbol().equals(symbol))
190         firstSet.addPattern(definitions[i].getFirstSet());
191
192     return firstSet;
193   }
194
195   public PatternSet getFirstSet()
196   {
197     return getFirstSet(getStartSymbol());
198   }
199
200   public PatternSet getLastSet(String JavaDoc symbol)
201   {
202     PatternSet lastSet = new PatternSet();
203
204     for (int i = 0; i<definitions.length; i++)
205       if (definitions[i].getSymbol().equals(symbol))
206         lastSet.addPattern(definitions[i].getLastSet());
207
208     return lastSet;
209   }
210
211   public PatternSet getLastSet()
212   {
213     return getLastSet(getStartSymbol());
214   }
215
216   public void updateDescendingSuccessors()
217   {
218     for (PatternIterator ancestors = getLastSet(getStartSymbol()).getPattern();
219          ancestors.hasNext();)
220     {
221       Pattern ancestor = ancestors.next();
222       ancestor.addDescendingSuccessor(EOT);
223     }
224
225     boolean modified;
226     do
227     {
228       modified = false;
229
230       for (PatternIterator ancestors = getAllPattern().getPattern(); ancestors.hasNext();)
231       {
232         Pattern ancestor = ancestors.next();
233
234         if (ancestor.getSymbol()!=null)
235         {
236           for (PatternIterator pattern = getLastSet(ancestor.getSymbol()).getPattern();
237                pattern.hasNext();)
238           {
239             Pattern lastPattern = pattern.next();
240
241             for (PatternIterator successors = ancestor.getSuccessors(); successors.hasNext();)
242             {
243               Pattern successor = successors.next();
244
245               if ((lastPattern!=successor) || (!lastPattern.hasSuccessor(successor)))
246                 modified |= lastPattern.addDescendingSuccessor(successor);
247             }
248
249             for (PatternIterator successors = ancestor.getAscendingSuccessors();
250                  successors.hasNext();)
251             {
252               Pattern successor = successors.next();
253
254               if ((lastPattern!=successor) || (!lastPattern.hasDescendingSuccessor(successor)))
255                 modified |= lastPattern.addDescendingSuccessor(successor);
256             }
257
258             for (PatternIterator successors = ancestor.getDescendingSuccessors();
259                  successors.hasNext();)
260             {
261               Pattern successor = successors.next();
262
263               if ((lastPattern!=successor) || (!lastPattern.hasDescendingSuccessor(successor)))
264                 modified |= lastPattern.addDescendingSuccessor(successor);
265             }
266           }
267         }
268
269         for (PatternIterator successors = ancestor.getDescendingSuccessors(); successors.hasNext();)
270         {
271           Pattern successor = successors.next();
272
273           if ((successor.getSymbol()!=null) && (isNullable(successor.getSymbol())))
274           {
275             for (PatternIterator i = successor.getSuccessors(); i.hasNext();)
276             {
277               Pattern follow = i.next();
278               modified |= ancestor.addDescendingSuccessor(follow);
279             }
280
281             for (PatternIterator i = successor.getAscendingSuccessors(); i.hasNext();)
282             {
283               Pattern follow = i.next();
284               modified |= ancestor.addDescendingSuccessor(follow);
285             }
286
287             for (PatternIterator i = successor.getDescendingSuccessors(); i.hasNext();)
288             {
289               Pattern follow = i.next();
290               modified |= ancestor.addDescendingSuccessor(follow);
291             }
292           }
293         }
294       }
295     }
296     while (modified);
297   }
298
299   /**
300    * Set the start symbol for this grammar.
301    *
302    * @param startSymbol Start symbol.
303    */

304   public void setStartSymbol(String JavaDoc symbol)
305   {
306     this.startSymbol = symbol;
307   }
308
309   /**
310    * Return the start symbol.
311    *
312    * @return Start symbol.
313    */

314   public String JavaDoc getStartSymbol()
315   {
316     return startSymbol;
317   }
318
319   public Pattern getStartPattern()
320   {
321     return BOT;
322   }
323
324   public Pattern getEndPattern()
325   {
326     return EOT;
327   }
328
329   /**
330    * Set the location from the input source.
331    *
332    * @param location Location in the input source.
333    */

334   public void setLocation(String JavaDoc location)
335   {
336     this.location = location;
337   }
338
339   /**
340    * Returns the location from the input source.
341    *
342    * @return Location in the input source.
343    */

344   public String JavaDoc getLocation()
345   {
346     return location;
347   }
348
349   /**
350    * Validated the grammar.
351    *
352    * @return Return a list of violations, if this object isn't valid.
353    */

354   public Violations validate()
355   {
356     Violations violations = new Violations();
357
358     if (startSymbol==null)
359       violations.addViolation("Start symbol is not defined", location);
360
361     /*for (int i = 0; i<definitions.length; i++)
362       for (int j = 0; j<definitions.length; j++)
363         if ((i!=j) && (definitions[i].getSymbol().equals(definitions[j].getSymbol())))
364           violations.addViolation("Element '"+definitions[i].getSymbol()+"' is already defined",
365                                   definitions[i].getLocation());*/

366     if (getDefinition(startSymbol)==null)
367       violations.addViolation("Start symbol \""+startSymbol+"\""+
368                               "is not defined through a definition", location);
369
370     if (getDefinitionCount()<=0)
371       violations.addViolation("No definitions are defined", location);
372
373     for (int i = 0; i<definitions.length; i++)
374       violations.addViolations(definitions[i].validate());
375
376     /*SymbolSet ntdefinitions = getSymbols().getNonterminals();
377
378     for (int i = 0; i<ntdefinitions.getSymbolCount(); i++)
379       if ( !contains(ntdefinitions.getSymbol(i)))
380         violations.addViolation("Nonterminal symbol \""+
381                                 ntdefinitions.getSymbol(i)+"\""+
382                                 "is not defined through a definition", location);*/

383     return violations;
384   }
385
386   /**
387    * Return a string representation of the grammar.
388    *
389    * @return String representation.
390    */

391   public String JavaDoc toString()
392   {
393     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
394
395     buffer.append("Definitions:\n");
396     for (int i = 0; i<getDefinitionCount(); i++)
397     {
398       buffer.append(String.valueOf(i));
399       buffer.append(".Definition: ");
400
401       buffer.append(definitions[i]);
402       buffer.append(" ");
403
404       buffer.append("\n");
405     }
406
407     buffer.append("\n");
408
409     return buffer.toString();
410   }
411
412   public String JavaDoc toString(PatternSet previous, PatternSet next)
413   {
414     boolean first = true;
415     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
416     for (int i = 0; i<getDefinitionCount(); i++)
417     {
418       PatternSet pattern = definitions[i].getAllPattern();
419       boolean found = false;
420       for (PatternIterator previousPattern = previous.getPattern();
421            previousPattern.hasNext() && !found;)
422         found |= pattern.contains(previousPattern.next());
423
424       for (PatternIterator nextPattern = next.getPattern(); nextPattern.hasNext() && !found;)
425         found |= pattern.contains(nextPattern.next());
426
427       if (found)
428       {
429         if (!first)
430           buffer.append("\n");
431
432         buffer.append(definitions[i].toString(previous, next));
433         first = false;
434       }
435     }
436
437     return buffer.toString();
438   }
439
440   /**
441    * Creates a clone of this grammar.
442    *
443    * @return Clone of this grammar.
444    *
445    * @throws CloneNotSupportedException If an exception occurs during the cloning.
446    */

447   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
448   {
449     ExtendedGrammar clone = new ExtendedGrammar();
450
451     clone.startSymbol = startSymbol;
452     for (int i = 0; i<definitions.length; i++)
453       clone.addDefinition((Definition)definitions[i].clone());
454
455     clone.location = location;
456
457     return clone;
458   }
459 }
460
Popular Tags