KickJava   Java API By Example, From Geeks To Geeks.

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


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 net.sourceforge.chaperon.model.symbol.Nonterminal;
12 import net.sourceforge.chaperon.model.symbol.Symbol;
13 import net.sourceforge.chaperon.model.symbol.Terminal;
14
15 import org.xml.sax.Attributes JavaDoc;
16 import org.xml.sax.Locator JavaDoc;
17 import org.xml.sax.SAXException JavaDoc;
18 import org.xml.sax.helpers.DefaultHandler JavaDoc;
19
20 import java.util.Hashtable JavaDoc;
21 import java.util.Stack JavaDoc;
22
23 /**
24  * This class should generate a grammar from a SAX stream
25  *
26  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels </a>
27  * @version CVS $Id: GrammarFactory.java,v 1.5 2003/12/14 09:48:34 benedikta Exp $
28  */

29 public class GrammarFactory extends DefaultHandler JavaDoc
30 {
31   /** The namspace of the grammar configuration */
32   public static final String JavaDoc NS = "http://chaperon.sourceforge.net/schema/grammar/1.0";
33
34   /** Element name */
35   public static final String JavaDoc GRAMMAR_ELEMENT = "grammar";
36
37   /** Attribute name of the associativity property */
38
39   // public final static String TOKEN_ASSOCIATIVE_ATTRIBUTE = "assoc";
40

41   /** Element name */
42   public static final String JavaDoc PRODUCTION_ELEMENT = "production";
43
44   /** Attribute name of the Precedence property */
45   public static final String JavaDoc PRECEDENCE_ATTRIBUTE = "precedence";
46
47   /** Element name */
48   public static final String JavaDoc NONTERMINALSYMBOL_ELEMENT = "nonterminal";
49
50   /** Element name */
51   public static final String JavaDoc TERMINALSYMBOL_ELEMENT = "terminal";
52
53   /** Element name */
54   public static final String JavaDoc ERRORSYMBOL_ELEMENT = "error";
55
56   /** Element name */
57   public static final String JavaDoc STARTSYMBOL_ELEMENT = "start";
58
59   /** Element name */
60   public static final String JavaDoc PRIORITY_ELEMENT = "priority";
61
62   /** Element name */
63   public static final String JavaDoc ASSOCIATIVITY_ELEMENT = "associativity";
64
65   /** Attribute name of the associativity property */
66   public static final String JavaDoc TYPE_ATTRIBUTE = "type";
67
68   /** Attribute name */
69   public static final String JavaDoc SYMBOL_ATTRIBUTE = "symbol";
70   private static final int STATE_OUTER = 0;
71   private static final int STATE_GRAMMAR = 1;
72   private static final int STATE_PRODUCTION = 2;
73   private static final int STATE_START = 3;
74   private static final int STATE_NONTERMINAL = 4;
75   private static final int STATE_TERMINAL = 5;
76   private static final int STATE_ASSOCIATIVITY = 6;
77   private static final int STATE_PRIORITY = 7;
78   private static final int STATE_PRIORITYTERMINAL = 8;
79   private static final int STATE_ERROR = 9;
80   private int state = STATE_OUTER;
81   private Grammar grammar;
82   private Hashtable JavaDoc terminals = new Hashtable JavaDoc();
83   private Hashtable JavaDoc nonterminals = new Hashtable JavaDoc();
84   private Stack JavaDoc stack;
85   private Locator JavaDoc locator = null;
86   private int priorities = 0;
87
88   /**
89    * Returns the generated Grammar
90    *
91    * @return Grammar
92    */

93   public Grammar getGrammar()
94   {
95     return grammar;
96   }
97
98   private String JavaDoc getLocation()
99   {
100     if (locator==null)
101       return "unknown";
102
103     return locator.getSystemId()+":"+locator.getLineNumber()+":"+locator.getColumnNumber();
104   }
105
106   /**
107    * Receive an object for locating the origin of SAX document events.
108    */

109   public void setDocumentLocator(Locator JavaDoc locator)
110   {
111     this.locator = locator;
112   }
113
114   /**
115    * Receive notification of the beginning of a document.
116    */

117   public void startDocument()
118   {
119     stack = new Stack JavaDoc();
120
121     state = STATE_OUTER;
122   }
123
124   /**
125    * Return the content of the associatve attribute
126    *
127    * @param namespaceURI
128    * @param localName
129    * @param qName
130    * @param atts Attributes of an element
131    *
132    * @throws SAXException
133    */

134
135   /*private Associativity getAssociativityFromAttributes(Attributes atts)
136   {
137     String attribute = atts.getValue(TOKEN_ASSOCIATIVE_ATTRIBUTE);
138
139     if ((attribute != null) && (attribute.length() > 0))
140       return Associativity.valueOf(attribute);
141     return Associativity.NONASSOC;
142   }*/

143
144   /**
145    * Return the content of the reducetype attribute
146    *
147    * @param atts Attributes of an element
148    *
149    * @return Reducetype attribute
150    */

151
152   /*private ReduceType getReduceTypeFromAttributes(Attributes atts)
153   {
154     String attribute = atts.getValue(PRODUCTION_REDUCETYPE_ATTRIBUTE);
155
156     if ((attribute != null) && (attribute.length() > 0))
157       return ReduceType.valueOf(attribute);
158     return ReduceType.NORMAL;
159   }*/

160
161   /**
162    * Receive notification of the beginning of an element.
163    *
164    * @param namespaceURI The Namespace URI, or the empty string if the element has no Namespace URI
165    * or if Namespace processing is not being performed.
166    * @param localName The local name (without prefix), or the empty string if Namespace processing
167    * is not being performed.
168    * @param qName The raw XML 1.0 name (with prefix), or the empty string if raw names are not
169    * available.
170    * @param atts The attributes attached to the element. If there are no attributes, it shall be an
171    * empty Attributes object.
172    */

173   public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts)
174     throws SAXException JavaDoc
175   {
176     if (namespaceURI.equals(NS))
177     {
178       if ((localName.equals(GRAMMAR_ELEMENT)) && (state==STATE_OUTER))
179       {
180         grammar = new Grammar();
181         grammar.setLocation(getLocation());
182         stack.push(grammar);
183
184         state = STATE_GRAMMAR;
185       }
186       else if ((localName.equals(PRODUCTION_ELEMENT)) && (state==STATE_GRAMMAR))
187       {
188         Production production =
189           new Production(getNonterminal(nonterminals, atts.getValue(SYMBOL_ATTRIBUTE)));
190         production.setLocation(getLocation());
191
192         String JavaDoc precedencesymbol = atts.getValue(PRECEDENCE_ATTRIBUTE);
193         if ((precedencesymbol!=null) && (precedencesymbol.length()>0))
194           production.setPrecedence(new Terminal(precedencesymbol));
195
196         stack.push(production);
197
198         state = STATE_PRODUCTION;
199       }
200       else if ((localName.equals(NONTERMINALSYMBOL_ELEMENT)) && (state==STATE_PRODUCTION))
201       {
202         stack.push(getNonterminal(nonterminals, atts.getValue(SYMBOL_ATTRIBUTE)));
203
204         state = STATE_NONTERMINAL;
205       }
206       else if ((localName.equals(TERMINALSYMBOL_ELEMENT)) && (state==STATE_PRODUCTION))
207       {
208         stack.push(new Terminal(atts.getValue(SYMBOL_ATTRIBUTE)));
209
210         state = STATE_TERMINAL;
211       }
212       else if ((localName.equals(ERRORSYMBOL_ELEMENT)) && (state==STATE_PRODUCTION))
213       {
214         stack.push(new Error JavaDoc());
215
216         state = STATE_ERROR;
217       }
218       else if ((localName.equals(STARTSYMBOL_ELEMENT)) && (state==STATE_GRAMMAR))
219       {
220         stack.push(new Nonterminal(atts.getValue(SYMBOL_ATTRIBUTE)));
221
222         state = STATE_START;
223       }
224       else if ((localName.equals(ASSOCIATIVITY_ELEMENT)) && (state==STATE_GRAMMAR))
225       {
226         grammar.setAssociativity(getTerminal(terminals, atts.getValue(SYMBOL_ATTRIBUTE)),
227                                  new Associativity(atts.getValue(TYPE_ATTRIBUTE)));
228
229         state = STATE_ASSOCIATIVITY;
230       }
231       else if ((localName.equals(PRIORITY_ELEMENT)) && (state==STATE_GRAMMAR))
232       {
233         priorities = 0;
234
235         state = STATE_PRIORITY;
236       }
237       else if ((localName.equals(TERMINALSYMBOL_ELEMENT)) && (state==STATE_PRIORITY))
238       {
239         stack.push(getTerminal(terminals, atts.getValue(SYMBOL_ATTRIBUTE)));
240
241         priorities++;
242
243         state = STATE_PRIORITYTERMINAL;
244       }
245       else
246         throw new SAXException JavaDoc("Unexpected element "+qName+" at "+getLocation());
247     }
248     else
249       throw new SAXException JavaDoc("Unexpected element "+qName+" at "+getLocation());
250   }
251
252   /**
253    * Receive notification of the end of an element.
254    *
255    * @param namespaceURI The Namespace URI, or the empty string if the element has no Namespace URI
256    * or if Namespace processing is not being performed.
257    * @param localName The local name (without prefix), or the empty string if Namespace processing
258    * is not being performed.
259    * @param qName The raw XML 1.0 name (with prefix), or the empty string if raw names are not
260    * available.
261    *
262    * @throws SAXException
263    */

264   public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
265     throws SAXException JavaDoc
266   {
267     if (namespaceURI.equals(NS))
268     {
269       if ((localName.equals(GRAMMAR_ELEMENT)) && (state==STATE_GRAMMAR))
270       {
271         grammar = (Grammar)stack.pop();
272
273         state = STATE_OUTER;
274       }
275       else if ((localName.equals(PRODUCTION_ELEMENT)) && (state==STATE_PRODUCTION))
276       {
277         Production production = (Production)stack.pop();
278         Grammar grammar = (Grammar)stack.peek();
279
280         grammar.addProduction(production);
281
282         state = STATE_GRAMMAR;
283       }
284       else if ((localName.equals(NONTERMINALSYMBOL_ELEMENT)) && (state==STATE_NONTERMINAL))
285       {
286         Symbol ntsymbol = (Symbol)stack.pop();
287         Production production = (Production)stack.peek();
288
289         production.getDefinition().addSymbol(ntsymbol);
290
291         state = STATE_PRODUCTION;
292       }
293       else if ((localName.equals(TERMINALSYMBOL_ELEMENT)) && (state==STATE_TERMINAL))
294       {
295         Symbol tsymbol = (Symbol)stack.pop();
296         Production production = (Production)stack.peek();
297
298         production.getDefinition().addSymbol(tsymbol);
299
300         state = STATE_PRODUCTION;
301       }
302       else if ((localName.equals(ERRORSYMBOL_ELEMENT)) && (state==STATE_ERROR))
303       {
304         Symbol error = (Symbol)stack.pop();
305         Production production = (Production)stack.peek();
306
307         production.getDefinition().addSymbol(error);
308
309         state = STATE_PRODUCTION;
310       }
311       else if ((localName.equals(STARTSYMBOL_ELEMENT)) && (state==STATE_START))
312       {
313         Nonterminal ssymbol = (Nonterminal)stack.pop();
314         Grammar grammar = (Grammar)stack.peek();
315
316         grammar.setStartSymbol(ssymbol);
317
318         state = STATE_GRAMMAR;
319       }
320       else if ((localName.equals(ASSOCIATIVITY_ELEMENT)) && (state==STATE_ASSOCIATIVITY))
321         state = STATE_GRAMMAR;
322       else if ((localName.equals(PRIORITY_ELEMENT)) && (state==STATE_PRIORITY))
323       {
324         int i = 0;
325         while (stack.peek() instanceof Terminal)
326         {
327           grammar.setPriority((Terminal)stack.pop(), i+1);
328           i++;
329         }
330
331         state = STATE_GRAMMAR;
332       }
333       else if ((localName.equals(TERMINALSYMBOL_ELEMENT)) && (state==STATE_PRIORITYTERMINAL))
334         state = STATE_PRIORITY;
335       else
336         throw new SAXException JavaDoc("Unexpected element "+qName+" at "+getLocation());
337     }
338     else
339       throw new SAXException JavaDoc("Unexpected element "+qName+" at "+getLocation());
340   }
341
342   private Terminal getTerminal(Hashtable JavaDoc terminals, String JavaDoc name)
343   {
344     Terminal terminal = (Terminal)terminals.get(name);
345     if (terminal==null)
346     {
347       terminal = new Terminal(name);
348       terminals.put(name, terminal);
349     }
350
351     return terminal;
352   }
353
354   private Nonterminal getNonterminal(Hashtable JavaDoc nonterminals, String JavaDoc name)
355   {
356     Nonterminal nonterminal = (Nonterminal)nonterminals.get(name);
357     if (nonterminal==null)
358     {
359       nonterminal = new Nonterminal(name);
360       nonterminals.put(name, nonterminal);
361     }
362
363     return nonterminal;
364   }
365 }
366
Popular Tags