1 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 ; 16 import org.xml.sax.ContentHandler ; 17 import org.xml.sax.Locator ; 18 import org.xml.sax.SAXException ; 19 import org.xml.sax.ext.LexicalHandler ; 20 import org.xml.sax.helpers.AttributesImpl ; 21 import org.xml.sax.helpers.LocatorImpl ; 22 23 29 public class ExtendedGeneralParserProcessor implements ContentHandler , LexicalHandler 30 { 31 public static final String NS = "http://chaperon.sourceforge.net/schema/text/1.0"; 32 public static final String TEXT = "text"; 33 34 35 public static final String NS_OUTPUT = "http://chaperon.sourceforge.net/schema/syntaxtree/2.0"; 36 public static final String OUTPUT = "output"; 37 public static final String ERROR = "error"; 38 private ContentHandler contentHandler = null; 39 private LexicalHandler lexicalHandler = null; 40 private Locator locator = null; 41 private LocatorImpl 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 56 public ExtendedGeneralParserProcessor() {} 57 58 65 public ExtendedGeneralParserProcessor(ExtendedParserAutomaton automaton, Log log) 66 { 67 this.automaton = automaton; 68 this.log = log; 69 } 70 71 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 87 public void setContentHandler(ContentHandler handler) 88 { 89 this.contentHandler = handler; 90 } 91 92 95 public void setLexicalHandler(LexicalHandler handler) 96 { 97 this.lexicalHandler = handler; 98 } 99 100 105 public void setLog(Log log) 106 { 107 this.log = log; 108 } 109 110 116 public void setFlatten(boolean flatten) 117 { 118 this.flatten = flatten; 119 } 120 121 124 public void setDocumentLocator(Locator locator) 125 { 126 this.locator = locator; 127 if (locator!=null) 128 { 129 this.locatorImpl = new LocatorImpl (locator); 130 contentHandler.setDocumentLocator(locatorImpl); 131 } 132 } 133 134 137 public void startDocument() throws SAXException 138 { 139 locatorImpl.setLineNumber(locator.getLineNumber()); 140 locatorImpl.setColumnNumber(locator.getColumnNumber()); 141 contentHandler.startDocument(); 142 state = STATE_OUTER; 143 } 144 145 148 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) 149 throws SAXException 150 { 151 locatorImpl.setLineNumber(locator.getLineNumber()); 152 locatorImpl.setColumnNumber(locator.getColumnNumber()); 153 154 if (state==STATE_INNER) 155 throw new SAXException ("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 ("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 current.clear(); 177 current.push(new TerminalStackNode('\u0000', automaton.first, null)); 178 next.clear(); 179 } 180 181 184 public void characters(char[] text, int textstart, int textlength) 185 throws SAXException 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 (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 ("Parsing process is aborted"); 204 205 printStates(); 206 207 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 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 284 285 if ((log!=null) && (log.isDebugEnabled())) 287 log.debug("------- check shift actions ---------"); 288 289 while (!current.isEmpty()) 290 { 291 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( 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 ("Character '"+text[position]+"' is not expected"); 308 309 swapStacks(); 310 311 System.out.println("------- finished check actions ---------"); 312 313 printStates(); 314 } 315 } 316 317 320 public void endElement(String namespaceURI, String localName, String qName) 321 throws SAXException 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 ("Unknown element "+qName); 335 } 336 else 337 throw new SAXException ("Unexpected element "+qName); 338 } 339 340 System.out.println("end processing"); 341 342 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 for (int j = 0; j<second.ancestors.length; j++) 387 { 388 StackNode first = second.ancestors[j]; 389 390 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 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 } 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 ()); 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 454 public void ignorableWhitespace(char[] ch, int start, int length) 455 throws SAXException 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 467 public void startPrefixMapping(String prefix, String uri) 468 throws SAXException 469 { 470 locatorImpl.setLineNumber(locator.getLineNumber()); 471 locatorImpl.setColumnNumber(locator.getColumnNumber()); 472 473 contentHandler.startPrefixMapping(prefix, uri); 474 } 475 476 479 public void endPrefixMapping(String prefix) throws SAXException 480 { 481 locatorImpl.setLineNumber(locator.getLineNumber()); 482 locatorImpl.setColumnNumber(locator.getColumnNumber()); 483 484 contentHandler.endPrefixMapping(prefix); 485 } 486 487 490 public void processingInstruction(String target, String data) 491 throws SAXException 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 503 public void skippedEntity(String name) throws SAXException 504 { 505 locatorImpl.setLineNumber(locator.getLineNumber()); 506 locatorImpl.setColumnNumber(locator.getColumnNumber()); 507 508 if (state==STATE_OUTER) 509 contentHandler.skippedEntity(name); 510 } 511 512 515 public void endDocument() throws SAXException 516 { 517 locatorImpl.setLineNumber(locator.getLineNumber()); 518 locatorImpl.setColumnNumber(locator.getColumnNumber()); 519 520 if (state==STATE_OUTER) 521 contentHandler.endDocument(); 522 } 523 524 527 public void startDTD(String name, String publicId, String systemId) 528 throws SAXException 529 { 530 if (lexicalHandler!=null) 531 lexicalHandler.startDTD(name, publicId, systemId); 532 } 533 534 537 public void endDTD() throws SAXException 538 { 539 if (lexicalHandler!=null) 540 lexicalHandler.endDTD(); 541 } 542 543 546 public void startEntity(String name) throws SAXException 547 { 548 if (lexicalHandler!=null) 549 lexicalHandler.startEntity(name); 550 } 551 552 555 public void endEntity(String name) throws SAXException 556 { 557 if (lexicalHandler!=null) 558 lexicalHandler.endEntity(name); 559 } 560 561 564 public void startCDATA() throws SAXException 565 { 566 if (lexicalHandler!=null) 567 lexicalHandler.startCDATA(); 568 } 569 570 573 public void endCDATA() throws SAXException 574 { 575 if (lexicalHandler!=null) 576 lexicalHandler.endCDATA(); 577 } 578 579 582 public void comment(char[] ch, int start, int len) throws SAXException 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 |