KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chaperon > process > extended > ExtendedGeneralParserProcessor


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.process.extended;
10
11 import net.sourceforge.chaperon.model.extended.ExtendedGrammar;
12
13 import org.apache.commons.logging.Log;
14
15 import org.xml.sax.Attributes JavaDoc;
16 import org.xml.sax.ContentHandler JavaDoc;
17 import org.xml.sax.Locator JavaDoc;
18 import org.xml.sax.SAXException JavaDoc;
19 import org.xml.sax.ext.LexicalHandler JavaDoc;
20 import org.xml.sax.helpers.AttributesImpl JavaDoc;
21 import org.xml.sax.helpers.LocatorImpl JavaDoc;
22
23 /**
24  * This class represents a simulation of a pushdown automata using the parser automaton class.
25  *
26  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels</a>
27  * @version CVS $Id: ExtendedGeneralParserProcessor.java,v 1.1 2004/01/04 16:49:12 benedikta Exp $
28  */

29 public class ExtendedGeneralParserProcessor implements ContentHandler JavaDoc, LexicalHandler JavaDoc
30 {
31   public static final String JavaDoc NS = "http://chaperon.sourceforge.net/schema/text/1.0";
32   public static final String JavaDoc TEXT = "text";
33
34   /** Namespace for the generated SAX events. */
35   public static final String JavaDoc NS_OUTPUT = "http://chaperon.sourceforge.net/schema/syntaxtree/2.0";
36   public static final String JavaDoc OUTPUT = "output";
37   public static final String JavaDoc ERROR = "error";
38   private ContentHandler JavaDoc contentHandler = null;
39   private LexicalHandler JavaDoc lexicalHandler = null;
40   private Locator JavaDoc locator = null;
41   private LocatorImpl JavaDoc locatorImpl = null;
42   private static final int STATE_OUTER = 0;
43   private static final int STATE_INNER = 1;
44   private int state = STATE_OUTER;
45   private ExtendedParserAutomaton automaton;
46   private ExtendedGrammar grammar;
47   private boolean flatten = false;
48   private StackNodeSet current = new StackNodeSet();
49   private StackNodeSet next = new StackNodeSet();
50   private Log log;
51   private int maxActiveStates = 50;
52
53   /**
54    * Create a new parser processor.
55    */

56   public ExtendedGeneralParserProcessor() {}
57
58   /**
59    * Create a new parser processor.
60    *
61    * @param automaton Parser automaton, which the processor should ues.
62    * @param handler Handler, which should receives the parser events.
63    * @param log Log, which should used.
64    */

65   public ExtendedGeneralParserProcessor(ExtendedParserAutomaton automaton, Log log)
66   {
67     this.automaton = automaton;
68     this.log = log;
69   }
70
71   /**
72    * Set the parser automaton for the processor.
73    *
74    * @param automaton Parser automaton.
75    */

76   public void setExtendedParserAutomaton(ExtendedParserAutomaton automaton)
77   {
78     this.automaton = automaton;
79     this.grammar = automaton.getExtendedGrammar();
80     current.setExtendedParserAutomaton(automaton);
81     next.setExtendedParserAutomaton(automaton);
82   }
83
84   /**
85    * Set the <code>ContentHandler</code> that will receive XML data.
86    */

87   public void setContentHandler(ContentHandler JavaDoc handler)
88   {
89     this.contentHandler = handler;
90   }
91
92   /**
93    * Set the <code>LexicalHandler</code> that will receive XML data.
94    */

95   public void setLexicalHandler(LexicalHandler JavaDoc handler)
96   {
97     this.lexicalHandler = handler;
98   }
99
100   /**
101    * Provide processor with a log.
102    *
103    * @param log The log.
104    */

105   public void setLog(Log log)
106   {
107     this.log = log;
108   }
109
110   /**
111    * If the adapter should produce a more flatten XML hirachy, which means elements which the same
112    * name will be collapsed
113    *
114    * @param flatten True, if a more flatten hirachy should be produced.
115    */

116   public void setFlatten(boolean flatten)
117   {
118     this.flatten = flatten;
119   }
120
121   /**
122    * Receive an object for locating the origin of SAX document events.
123    */

124   public void setDocumentLocator(Locator JavaDoc locator)
125   {
126     this.locator = locator;
127     if (locator!=null)
128     {
129       this.locatorImpl = new LocatorImpl JavaDoc(locator);
130       contentHandler.setDocumentLocator(locatorImpl);
131     }
132   }
133
134   /**
135    * Receive notification of the beginning of a document.
136    */

137   public void startDocument() throws SAXException JavaDoc
138   {
139     locatorImpl.setLineNumber(locator.getLineNumber());
140     locatorImpl.setColumnNumber(locator.getColumnNumber());
141     contentHandler.startDocument();
142     state = STATE_OUTER;
143   }
144
145   /**
146    * Receive notification of the beginning of an element.
147    */

148   public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts)
149     throws SAXException JavaDoc
150   {
151     locatorImpl.setLineNumber(locator.getLineNumber());
152     locatorImpl.setColumnNumber(locator.getColumnNumber());
153
154     if (state==STATE_INNER)
155       throw new SAXException JavaDoc("Unexpected element "+qName);
156
157     if (state==STATE_OUTER)
158     {
159       if ((namespaceURI!=null) && (namespaceURI.equals(NS)))
160       {
161         if (!localName.equals(TEXT))
162           throw new SAXException JavaDoc("Unknown element "+qName);
163       }
164       else
165       {
166         contentHandler.startElement(namespaceURI, localName, qName, atts);
167         return;
168       }
169     }
170
171     state = STATE_INNER;
172
173     System.out.println("start processing");
174
175     // ======================= Start Text Document =======================
176
current.clear();
177     current.push(new TerminalStackNode('\u0000', automaton.first, null));
178     next.clear();
179   }
180
181   /**
182    * Receive notification of character data.
183    */

184   public void characters(char[] text, int textstart, int textlength)
185     throws SAXException JavaDoc
186   {
187     locatorImpl.setLineNumber(locator.getLineNumber());
188     locatorImpl.setColumnNumber(locator.getColumnNumber());
189
190     if (state==STATE_OUTER)
191     {
192       contentHandler.characters(text, textstart, textlength);
193       return;
194     }
195
196     System.out.println("process text \""+(new String JavaDoc(text, textstart, textlength))+"\"");
197
198     for (int position = textstart; position<(textstart+textlength); position++)
199     {
200       System.out.println("\n===================================\nProcess "+text[position]);
201
202       if (current.isEmpty())
203         throw new IllegalStateException JavaDoc("Parsing process is aborted");
204
205       printStates();
206
207       //if (current.size()>maxActiveStates)
208
// throw new IllegalStateException("Processor occupied too many states");
209
/* ============================ Reduce =================================== */
210       System.out.println("Count of states : "+current.size());
211
212       if ((log!=null) && (log.isDebugEnabled()))
213         log.debug("------- check reduce actions ---------");
214
215       int watchdog = 0;
216       while (!current.isEmpty())
217       {
218         printStates();
219
220         //if (watchdog++ > 220)
221
// throw new IllegalStateException("overflow");
222
//printStates();
223
StackNode stackNode = current.pop();
224
225         if (stackNode.state.getShiftAction(text[position])!=null)
226           ;
227
228         next.push(stackNode);
229
230         LookaheadReduceAction[] reduceActions = stackNode.state.getLookaheadReduceActions();
231
232         for (int i = 0; i<reduceActions.length; i++)
233           if (reduceActions[i].contains(text[position]))
234           {
235             LookaheadReduceAction reduceAction = reduceActions[i];
236
237             if (reduceAction.length==0)
238             {
239               GotoAction gotoAction = stackNode.state.getGotoAction(reduceAction);
240
241               if (gotoAction!=null)
242               {
243                 if ((log!=null) && (log.isDebugEnabled()))
244                   log.debug("State "+automaton.indexOf(stackNode.state)+" "+reduceAction);
245
246                 if (gotoAction.state==stackNode.state)
247                   System.out.println("node rejected because states are equal");
248                 else
249                   current.push(new DefinitionStackNode(reduceAction, 0, null, null,
250                                                        gotoAction.state, stackNode));
251               }
252             }
253             else
254             {
255               StackNode second = stackNode;
256               for (int j = 0; j<second.ancestors.length; j++)
257               {
258                 StackNode first = second.ancestors[j];
259                 for (int k = 0; k<first.ancestors.length; k++)
260                 {
261                   StackNode previousStackNode = first.ancestors[k];
262
263                   GotoAction gotoAction = previousStackNode.state.getGotoAction(reduceAction);
264
265                   if (gotoAction!=null)
266                   {
267                     if ((log!=null) && (log.isDebugEnabled()))
268                       log.debug("State "+automaton.indexOf(stackNode.state)+" "+reduceAction);
269
270                     current.push(new DefinitionStackNode(reduceAction, 0, first, second,
271                                                          gotoAction.state, previousStackNode));
272                   }
273                 }
274               }
275             }
276           }
277       }
278
279       swapStacks();
280
281       printStates();
282
283       /* ==================================== Shift =================================== */
284
285       //System.out.println("Count of states : "+current.size());
286
if ((log!=null) && (log.isDebugEnabled()))
287         log.debug("------- check shift actions ---------");
288
289       while (!current.isEmpty())
290       {
291         //printStates();
292
StackNode stackNode = current.pop();
293
294         ShiftAction shiftAction = stackNode.state.getShiftAction(text[position]);
295
296         if (shiftAction!=null)
297         {
298           if ((log!=null) && (log.isDebugEnabled()))
299             log.debug( /*"State "+state+*/
300             " shift character '"+text[position]+"'");
301
302           next.push(new TerminalStackNode(text[position], shiftAction.state, stackNode));
303         }
304       }
305
306       if (next.isEmpty())
307         throw new IllegalArgumentException JavaDoc("Character '"+text[position]+"' is not expected");
308
309       swapStacks();
310
311       System.out.println("------- finished check actions ---------");
312
313       printStates();
314     }
315   }
316
317   /**
318    * Receive notification of the end of an element.
319    */

320   public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
321     throws SAXException JavaDoc
322   {
323     locatorImpl.setLineNumber(locator.getLineNumber());
324     locatorImpl.setColumnNumber(locator.getColumnNumber());
325
326     if (state==STATE_OUTER)
327       contentHandler.endElement(namespaceURI, localName, qName);
328
329     if (state==STATE_INNER)
330     {
331       if ((namespaceURI!=null) && (namespaceURI.equals(NS)))
332       {
333         if (!localName.equals(TEXT))
334           throw new SAXException JavaDoc("Unknown element "+qName);
335       }
336       else
337         throw new SAXException JavaDoc("Unexpected element "+qName);
338     }
339
340     System.out.println("end processing");
341
342     // ======================= End Text Document =======================
343
System.out.println("\n===================================\nProcess EOF");
344
345     while (!current.isEmpty())
346     {
347       printStates();
348
349       StackNode stackNode = current.pop();
350
351       ReduceAction[] reduceActions = stackNode.state.getReduceActions();
352
353       for (int i = 0; i<reduceActions.length; i++)
354       {
355         ReduceAction reduceAction = reduceActions[i];
356
357         if (reduceAction.length==0)
358         {
359           GotoAction gotoAction = stackNode.state.getGotoAction(reduceAction);
360
361           if ((automaton.first==stackNode.state) &&
362               (grammar.getStartSymbol().equals(reduceAction.symbol)))
363           {
364             if ((log!=null) && (log.isDebugEnabled()))
365               log.debug("State "+automaton.indexOf(stackNode.state)+" accept");
366
367             next.push(new DefinitionStackNode(reduceAction, 0, null, null, null, stackNode));
368           }
369           else
370           {
371             if ((log!=null) && (log.isDebugEnabled()))
372               log.debug("State "+automaton.indexOf(stackNode.state)+" "+reduceAction);
373
374             if (gotoAction.state==stackNode.state)
375               System.out.println("node rejected because states are equal");
376             else
377               current.push(new DefinitionStackNode(reduceAction, 0, null, null, gotoAction.state,
378                                                    stackNode));
379           }
380         }
381         else
382         {
383           StackNode second = stackNode;
384
385           //System.out.println("second="+automaton.indexOf(second.state));
386
for (int j = 0; j<second.ancestors.length; j++)
387           {
388             StackNode first = second.ancestors[j];
389
390             //System.out.println("first="+automaton.indexOf(first.state));
391
//if (second.ancestors.length>1)
392
// System.out.println("nodes="+second.toCanonicalString(automaton));
393
for (int k = 0; k<first.ancestors.length; k++)
394             {
395               StackNode previousStackNode = first.ancestors[k];
396
397               GotoAction gotoAction = previousStackNode.state.getGotoAction(reduceAction);
398
399               //System.out.println("j="+j+" k="+k);
400
if ((automaton.first==previousStackNode.state) &&
401                   (grammar.getStartSymbol().equals(reduceAction.symbol)))
402               {
403                 if ((log!=null) && (log.isDebugEnabled()))
404                   log.debug("State "+automaton.indexOf(stackNode.state)+" accept");
405
406                 next.push(new DefinitionStackNode(reduceAction, 0, first, second, null,
407                                                   previousStackNode));
408               }
409               else
410               {
411                 if ((log!=null) && (log.isDebugEnabled()))
412                   log.debug("State "+automaton.indexOf(stackNode.state)+" "+reduceAction);
413
414                 current.push(new DefinitionStackNode(reduceAction, 0, first, second,
415                                                      gotoAction.state, previousStackNode));
416
417                 //System.out.println("origin="+automaton.indexOf(previousStackNode.state));
418
}
419             }
420           }
421         }
422       }
423     }
424
425     if (log.isDebugEnabled())
426       log.debug("Parser found "+next.size()+" alternatives");
427
428     System.out.println();
429
430     contentHandler.startPrefixMapping("", NS_OUTPUT);
431     contentHandler.startElement(NS_OUTPUT, OUTPUT, OUTPUT, new AttributesImpl JavaDoc());
432
433     int index = 1;
434     while (!next.isEmpty())
435     {
436       StackNode node = next.pop();
437
438       node.toXML(contentHandler);
439       index++;
440     }
441
442     if (next.size()>1)
443       log.warn("ExtendedGrammar is ambig, found "+next.size()+" alternative trees");
444
445     contentHandler.endElement(NS_OUTPUT, OUTPUT, OUTPUT);
446     contentHandler.endPrefixMapping("");
447
448     state = STATE_OUTER;
449   }
450
451   /**
452    * Receive notification of ignorable whitespace in element content.
453    */

454   public void ignorableWhitespace(char[] ch, int start, int length)
455     throws SAXException JavaDoc
456   {
457     locatorImpl.setLineNumber(locator.getLineNumber());
458     locatorImpl.setColumnNumber(locator.getColumnNumber());
459
460     if (state==STATE_OUTER)
461       contentHandler.ignorableWhitespace(ch, start, length);
462   }
463
464   /**
465    * Begin the scope of a prefix-URI Namespace mapping.
466    */

467   public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
468     throws SAXException JavaDoc
469   {
470     locatorImpl.setLineNumber(locator.getLineNumber());
471     locatorImpl.setColumnNumber(locator.getColumnNumber());
472
473     contentHandler.startPrefixMapping(prefix, uri);
474   }
475
476   /**
477    * End the scope of a prefix-URI mapping.
478    */

479   public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc
480   {
481     locatorImpl.setLineNumber(locator.getLineNumber());
482     locatorImpl.setColumnNumber(locator.getColumnNumber());
483
484     contentHandler.endPrefixMapping(prefix);
485   }
486
487   /**
488    * Receive notification of a processing instruction.
489    */

490   public void processingInstruction(String JavaDoc target, String JavaDoc data)
491     throws SAXException JavaDoc
492   {
493     locatorImpl.setLineNumber(locator.getLineNumber());
494     locatorImpl.setColumnNumber(locator.getColumnNumber());
495
496     if (state==STATE_OUTER)
497       contentHandler.processingInstruction(target, data);
498   }
499
500   /**
501    * Receive notification of a skipped entity.
502    */

503   public void skippedEntity(String JavaDoc name) throws SAXException JavaDoc
504   {
505     locatorImpl.setLineNumber(locator.getLineNumber());
506     locatorImpl.setColumnNumber(locator.getColumnNumber());
507
508     if (state==STATE_OUTER)
509       contentHandler.skippedEntity(name);
510   }
511
512   /**
513    * Receive notification of the end of a document.
514    */

515   public void endDocument() throws SAXException JavaDoc
516   {
517     locatorImpl.setLineNumber(locator.getLineNumber());
518     locatorImpl.setColumnNumber(locator.getColumnNumber());
519
520     if (state==STATE_OUTER)
521       contentHandler.endDocument();
522   }
523
524   /**
525    * Report the start of DTD declarations, if any.
526    */

527   public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
528     throws SAXException JavaDoc
529   {
530     if (lexicalHandler!=null)
531       lexicalHandler.startDTD(name, publicId, systemId);
532   }
533
534   /**
535    * Report the end of DTD declarations.
536    */

537   public void endDTD() throws SAXException JavaDoc
538   {
539     if (lexicalHandler!=null)
540       lexicalHandler.endDTD();
541   }
542
543   /**
544    * Report the beginning of an entity.
545    */

546   public void startEntity(String JavaDoc name) throws SAXException JavaDoc
547   {
548     if (lexicalHandler!=null)
549       lexicalHandler.startEntity(name);
550   }
551
552   /**
553    * Report the end of an entity.
554    */

555   public void endEntity(String JavaDoc name) throws SAXException JavaDoc
556   {
557     if (lexicalHandler!=null)
558       lexicalHandler.endEntity(name);
559   }
560
561   /**
562    * Report the start of a CDATA section.
563    */

564   public void startCDATA() throws SAXException JavaDoc
565   {
566     if (lexicalHandler!=null)
567       lexicalHandler.startCDATA();
568   }
569
570   /**
571    * Report the end of a CDATA section.
572    */

573   public void endCDATA() throws SAXException JavaDoc
574   {
575     if (lexicalHandler!=null)
576       lexicalHandler.endCDATA();
577   }
578
579   /**
580    * Report an XML comment anywhere in the document.
581    */

582   public void comment(char[] ch, int start, int len) throws SAXException JavaDoc
583   {
584     if (lexicalHandler!=null)
585       lexicalHandler.comment(ch, start, len);
586   }
587
588   private void printStates()
589   {
590     System.out.println("Current states:");
591     System.out.println(current.toCanonicalString());
592     System.out.println("Next states:");
593     System.out.println(next.toCanonicalString());
594   }
595
596   private void swapStacks()
597   {
598     StackNodeSet dummy = next;
599     next = current;
600     current = dummy;
601     next.clear();
602   }
603 }
604
Popular Tags