KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chaperon > model > grammar > test3


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.grammar;
10
11 import java.io.Serializable JavaDoc;
12 import java.util.Hashtable JavaDoc;
13 import java.util.Enumeration JavaDoc;
14 import java.util.Vector JavaDoc;
15
16 import net.sourceforge.chaperon.common.IntegerList;
17 import net.sourceforge.chaperon.model.Violations;
18 import net.sourceforge.chaperon.model.symbol.Symbol;
19 import net.sourceforge.chaperon.model.symbol.SymbolList;
20 import net.sourceforge.chaperon.model.symbol.SymbolSet;
21 import net.sourceforge.chaperon.model.symbol.Nonterminal;
22 import net.sourceforge.chaperon.model.symbol.Terminal;
23
24 /**
25  * This class contains a grammar for building a parser table
26  *
27  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels</a>
28  * @version CVS $Id: test3.java,v 1.3 2003/01/21 22:37:19 benedikta Exp $
29  */

30 public class Grammar implements Serializable JavaDoc, Cloneable JavaDoc
31 {
32     // Start symbol
33
private Nonterminal startsymbol = null;
34
35     // Productions
36
private Vector JavaDoc productions = new Vector JavaDoc();
37
38   private Hashtable JavaDoc priorities = new Hashtable JavaDoc();
39   private Hashtable JavaDoc associativities = new Hashtable JavaDoc();
40
41   private String JavaDoc location = null;
42
43     /**
44      * Creates a empty grammar
45      */

46     public Grammar()
47     {
48     }
49
50   /**
51    * Add a production to this list
52    *
53    * @param production Production, which should added
54    *
55    * @return Index of the production in this list
56    */

57   public int addProduction(Production production)
58   {
59     if (production==null)
60       throw new NullPointerException JavaDoc();
61
62     productions.addElement(production);
63     return productions.size() - 1;
64   }
65   
66   /**
67    * Add a list of productions
68    *
69    * @param list Array of productions
70    */

71   public void addProduction(Production[] list)
72   {
73     for (int i = 0; i < list.length; i++)
74     {
75       try
76       {
77         addProduction((Production)list[i].clone());
78       } catch (CloneNotSupportedException JavaDoc cnse)
79       {
80         throw new IllegalArgumentException JavaDoc("Could not clone token:"+cnse.getMessage());
81       }
82     }
83   }
84
85   /**
86    * Removes a production by an index from this list
87    *
88    * @param index Index of the production, which should be removed
89    */

90   public void removeProduction(int index)
91   {
92     productions.removeElementAt(index);
93   }
94   
95   /**
96    * Set a production by an index
97    *
98    * @param index The index, at which the production be inserted
99    * @param production Production
100    */

101   public void setProduction(int index,
102                             Production production)
103                               throws IndexOutOfBoundsException JavaDoc
104   {
105     if ((index < 0) || (index > productions.size()))
106       throw new IndexOutOfBoundsException JavaDoc();
107     productions.setElementAt(production, index);
108   }
109   
110   /**
111    * Return a production giving by an index
112    *
113    * @param index Index of the Production
114    *
115    * @return Production
116    */

117   public Production getProduction(int index) throws IndexOutOfBoundsException JavaDoc
118   {
119     if ((index < 0) || (index > productions.size()))
120       throw new IndexOutOfBoundsException JavaDoc();
121
122     return (Production) productions.elementAt(index);
123   }
124
125   /**
126    * Returns all production for given non terminal symbol
127    *
128    * @param ntsymbol Non terminal symbol
129    *
130    * @return List of indices from found productions
131    */

132   public IntegerList getProductionList(Symbol ntsymbol)
133   {
134     IntegerList list = new IntegerList();
135     int i;
136     
137     for (i = 0; i < getProductionCount(); i++)
138     {
139       if (getProduction(i).getSymbol().equals(ntsymbol))
140         list.add(i);
141     }
142     return list;
143   }
144   
145   /**
146    * Returns the count of productions in the list
147    *
148    * @return Count of productions
149    */

150   public int getProductionCount()
151   {
152     return productions.size();
153   }
154   
155   /**
156    * Return the index of a production
157    *
158    * @param production Production
159    *
160    * @return Index of the Production
161    */

162   public int indexOf(Production production)
163   {
164     for (int i = 0; i < productions.size(); i++)
165       if (((Production) productions.elementAt(i)).equals(production))
166         return i;
167     return -1;
168   }
169
170   /**
171    * Return the index of the next production, which found
172    * by a non terminal symbol
173    *
174    * @param ntsymbol Non terminal symbol
175    *
176    * @return Production, which found
177    */

178   public int indexOf(Symbol ntsymbol)
179   {
180     for (int i = 0; i < productions.size(); i++)
181       if (((Production) productions.elementAt(i)).getSymbol().equals(ntsymbol))
182         return i;
183     return -1;
184   }
185
186   /**
187    * If the list contains a production
188    *
189    * @param production Production
190    *
191    * @return True, if the list contains the production
192    */

193   public boolean contains(Production production)
194   {
195     return (indexOf(production) != -1);
196   }
197
198   /**
199    * If the list contains a production with a special symbol
200    *
201    * @param ntsymbol Non terminal symbol
202    *
203    * @return True, if the list contains a production with the symbol
204    */

205   public boolean contains(Symbol ntsymbol)
206   {
207     return (indexOf(ntsymbol) != -1);
208   }
209
210   /**
211    * Removes all productions from this list
212    */

213   public void removeAllProduction()
214   {
215     productions.removeAllElements();
216   }
217
218   /**
219    * Returns a enumeration of the productions
220    * in this list.
221    *
222    * @return Enumeration of the productions
223    */

224   public Enumeration JavaDoc enumerateProduction()
225   {
226     return productions.elements();
227   }
228
229   /**
230    * Returns the content of this list
231    *
232    * @return Array of the tokens
233    */

234   public Production[] getProduction()
235   {
236     int size = productions.size();
237     Production[] mArray = new Production[size];
238
239     for (int index = 0; index < size; index++)
240       mArray[index] = (Production) productions.elementAt(index);
241     return mArray;
242   }
243
244   /**
245    * Replace the content of this list by the content of an array
246    *
247    *
248    * @param productionArray
249    */

250   public void setProduction(Production[] productionArray)
251   {
252     productions.removeAllElements();
253     for (int i = 0; i < productionArray.length; i++)
254       productions.addElement(productionArray[i]);
255   }
256
257   public void setPriority(Terminal terminal, int priority)
258   {
259     if (terminal==null)
260       throw new NullPointerException JavaDoc();
261
262     priorities.put(terminal, new Integer JavaDoc(priority));
263   }
264
265   public int getPriority(Terminal terminal)
266   {
267     Integer JavaDoc priority = (Integer JavaDoc)priorities.get(terminal);
268     if (priority==null)
269       return 0;
270     return priority.intValue();
271   }
272
273   public int getPriority(Production production)
274   {
275     if (!contains(production))
276       return 0;
277
278     if (production.getPrecedence() != null)
279       return getPriority(production.getPrecedence());
280
281     SymbolList definition = production.getDefinition();
282     for (int i = definition.getSymbolCount() - 1; i >= 0; i--)
283       if (definition.getSymbol(i) instanceof Terminal)
284       {
285         int priority = getPriority((Terminal)definition.getSymbol(i));
286         if (priority==0)
287           return getProductionCount()-indexOf(production);
288         return priority;
289       }
290
291     return getProductionCount()-indexOf(production);
292   }
293
294   public void setAssociativity(Terminal terminal, Associativity assoc)
295   {
296     if (terminal==null)
297       throw new NullPointerException JavaDoc();
298
299     associativities.put(terminal, assoc);
300   }
301
302   public Associativity getAssociativity(Terminal terminal)
303   {
304     Associativity assoc = (Associativity)associativities.get(terminal);
305     if (assoc==null)
306       return Associativity.NONASSOC;
307     return assoc;
308   }
309
310   public Associativity getAssociativity(Production production)
311   {
312     if (!contains(production))
313       return Associativity.NONASSOC;
314
315     if (production.getPrecedence() != null)
316       return getAssociativity(production.getPrecedence());
317
318     SymbolList definition = production.getDefinition();
319     for (int i = definition.getSymbolCount() - 1; i >= 0; i--)
320       if (definition.getSymbol(i) instanceof Terminal)
321         return getAssociativity((Terminal)definition.getSymbol(i));
322
323     return Associativity.NONASSOC;
324   }
325
326   /**
327    * Return all used symbols in this grammar
328    *
329    * @return Set of symbols
330    */

331   public SymbolSet getSymbols()
332   {
333     SymbolSet set = new SymbolSet();
334
335     for (int i = 0; i < getProductionCount(); i++)
336       set.addSymbol(getProduction(i).getSymbols());
337     return set;
338   }
339
340     /**
341      * Set the a symbol a start symbol
342      *
343      * @param startsymbol
344      */

345     public void setStartSymbol(Nonterminal startsymbol)
346     {
347         this.startsymbol = startsymbol;
348     }
349
350     /**
351      * Returns the start symbol
352      *
353      * @return Start symbol
354      */

355     public Nonterminal getStartSymbol()
356     {
357         return startsymbol;
358     }
359
360   /**
361    * Set the location from the input source.
362    *
363    * @param location Location in the input source.
364    */

365   public void setLocation(String JavaDoc location)
366   {
367     this.location = location;
368   }
369
370   /**
371    * Returns the location from the input source.
372    *
373    * @return Location in the input source.
374    */

375   public String JavaDoc getLocation()
376   {
377     return location;
378   }
379
380   /**
381    * This method validates the grammer
382    *
383    * @return Return a list of violations, if this
384    * object isn't correct
385    */

386   public Violations validate()
387   {
388     Violations violations = new Violations();
389     if (startsymbol==null)
390       violations.addViolation("Start symbol is not defined", location);
391
392     if (getProductionCount() <= 0)
393       violations.addViolation("No productions are defined", location);
394
395     for (Enumeration JavaDoc e = productions.elements(); e.hasMoreElements() ;)
396       violations.addViolations(((Production)e.nextElement()).validate());
397
398     SymbolSet ntsymbols = getSymbols().getNonterminals();
399     for (int i = 0; i < ntsymbols.getSymbolCount(); i++)
400       if (!contains(ntsymbols.getSymbol(i)))
401         violations.addViolation("Nonterminal symbol \"" + ntsymbols.getSymbol(i) + "\"" +
402                                 "is not defined through a production", location);
403
404     return violations;
405   }
406
407     /*
408      *
409      *
410      * @return
411      */

412     public String JavaDoc toString()
413     {
414     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
415
416     buffer.append(super.toString());
417     buffer.append("\n");
418
419     buffer.append("Terminal symbols:\n");
420     SymbolSet tsymbols = getSymbols().getTerminals();
421     for (int i = 0; i < tsymbols.getSymbolCount(); i++)
422     {
423       buffer.append(String.valueOf(i));
424       buffer.append(".Terminal: ");
425       buffer.append(tsymbols.getSymbol(i));
426       buffer.append(" Priority=");
427       buffer.append(String.valueOf(getPriority((Terminal)tsymbols.getSymbol(i))));
428       buffer.append(" Associativity=");
429       buffer.append(String.valueOf(getAssociativity((Terminal)tsymbols.getSymbol(i))));
430       buffer.append("\n");
431     }
432
433     buffer.append("Produktions:\n");
434     for (int i = 0; i < getProductionCount(); i++)
435     {
436       buffer.append(String.valueOf(i));
437       buffer.append(".Production: ");
438       buffer.append(getProduction(i).toString());
439       buffer.append("\n");
440     }
441
442     buffer.append("\n");
443
444         return buffer.toString();
445     }
446
447     /**
448      * Creates a clone of a grammar.
449      *
450      * @return
451      *
452      * @throws CloneNotSupportedException
453      */

454     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
455     {
456         Grammar clone = new Grammar();
457
458         clone.startsymbol = startsymbol;
459     for (int i = 0; i < productions.size(); i++)
460       clone.addProduction((Production) ((Production) productions.elementAt(i)).clone());
461
462     clone.location = location;
463
464         return clone;
465     }
466 }
467
Popular Tags