1ANTLR_BEGIN_NAMESPACE() 2 3template< class ImplTraits, class StreamType > 4BaseRecognizer<ImplTraits, StreamType>::BaseRecognizer(ANTLR_UINT32 sizeHint, 5 RecognizerSharedStateType* state) 6{ 7 m_debugger = NULL; 8 9 // If we have been supplied with a pre-existing recognizer state 10 // then we just install it, otherwise we must create one from scratch 11 // 12 if (state == NULL) 13 { 14 m_state = new RecognizerSharedStateType(); 15 m_state->set_sizeHint( sizeHint ); 16 } 17 else 18 { 19 // Install the one we were given, and do not reset it here 20 // as it will either already have been initialized or will 21 // be in a state that needs to be preserved. 22 // 23 m_state = state; 24 } 25} 26 27template< class ImplTraits, class StreamType > 28ANTLR_INLINE typename BaseRecognizer<ImplTraits, StreamType>::SuperType* BaseRecognizer<ImplTraits, StreamType>::get_super() 29{ 30 return static_cast<SuperType*>(this); 31} 32 33template< class ImplTraits, class StreamType > 34ANTLR_INLINE typename BaseRecognizer<ImplTraits, StreamType>::RecognizerSharedStateType* BaseRecognizer<ImplTraits, StreamType>::get_state() const 35{ 36 return m_state; 37} 38template< class ImplTraits, class StreamType > 39ANTLR_INLINE typename BaseRecognizer<ImplTraits, StreamType>::DebugEventListenerType* BaseRecognizer<ImplTraits, StreamType>::get_debugger() const 40{ 41 return m_debugger; 42} 43template< class ImplTraits, class StreamType > 44ANTLR_INLINE void BaseRecognizer<ImplTraits, StreamType>::set_state( RecognizerSharedStateType* state ) 45{ 46 m_state = state; 47} 48template< class ImplTraits, class StreamType > 49ANTLR_INLINE void BaseRecognizer<ImplTraits, StreamType>::set_debugger( DebugEventListenerType* debugger ) 50{ 51 m_debugger = debugger; 52} 53 54template< class ImplTraits, class StreamType > 55const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 56BaseRecognizer<ImplTraits, StreamType>::match(ANTLR_UINT32 ttype, BitsetListType* follow) 57{ 58 SuperType* super = static_cast<SuperType*>(this); 59 IntStreamType* is = super->get_istream(); 60 61 // Pick up the current input token/node for assignment to labels 62 // 63 const UnitType* matchedSymbol = this->getCurrentInputSymbol(is); 64 65 if (is->_LA(1) == ttype) 66 { 67 // The token was the one we were told to expect 68 // 69 is->consume(); // Consume that token from the stream 70 m_state->set_errorRecovery(false); // Not in error recovery now (if we were) 71 m_state->set_failed(false); // The match was a success 72 return matchedSymbol; // We are done 73 } 74 75 // We did not find the expected token type, if we are backtracking then 76 // we just set the failed flag and return. 77 // 78 if ( m_state->get_backtracking() > 0) 79 { 80 // Backtracking is going on 81 // 82 m_state->set_failed(true); 83 return matchedSymbol; 84 } 85 86 // We did not find the expected token and there is no backtracking 87 // going on, so we mismatch, which creates an exception in the recognizer exception 88 // stack. 89 // 90 matchedSymbol = this->recoverFromMismatchedToken(ttype, follow); 91 return matchedSymbol; 92 93} 94 95template< class ImplTraits, class StreamType > 96void BaseRecognizer<ImplTraits, StreamType>::matchAny() 97{ 98 SuperType* super = static_cast<SuperType*>(this); 99 IntStreamType* is = super->get_istream(); 100 101 is->consume(); 102 m_state->set_errorRecovery(false); 103 m_state->set_failed(false); 104 return; 105} 106 107template< class ImplTraits, class StreamType > 108bool BaseRecognizer<ImplTraits, StreamType>::mismatchIsUnwantedToken(IntStreamType* is, ANTLR_UINT32 ttype) 109{ 110 ANTLR_UINT32 nextt = is->_LA(2); 111 112 if (nextt == ttype) 113 { 114 if(m_state->get_exception() != NULL) 115 m_state->get_exception()->set_expecting(nextt); 116 return true; // This token is unknown, but the next one is the one we wanted 117 } 118 else 119 return false; // Neither this token, nor the one following is the one we wanted 120} 121 122template< class ImplTraits, class StreamType > 123bool BaseRecognizer<ImplTraits, StreamType>::mismatchIsMissingToken(IntStreamType* is, BitsetListType* follow) 124{ 125 bool retcode; 126 BitsetType* followClone; 127 BitsetType* viableTokensFollowingThisRule; 128 129 if (follow == NULL) 130 { 131 // There is no information about the tokens that can follow the last one 132 // hence we must say that the current one we found is not a member of the 133 // follow set and does not indicate a missing token. We will just consume this 134 // single token and see if the parser works it out from there. 135 // 136 return false; 137 } 138 139 followClone = NULL; 140 viableTokensFollowingThisRule = NULL; 141 142 // The C bitset maps are laid down at compile time by the 143 // C code generation. Hence we cannot remove things from them 144 // and so on. So, in order to remove EOR (if we need to) then 145 // we clone the static bitset. 146 // 147 followClone = follow->bitsetLoad(); 148 if (followClone == NULL) 149 return false; 150 151 // Compute what can follow this grammar reference 152 // 153 if (followClone->isMember( ImplTraits::CommonTokenType::EOR_TOKEN_TYPE)) 154 { 155 // EOR can follow, but if we are not the start symbol, we 156 // need to remove it. 157 // 158 followClone->remove(ImplTraits::CommonTokenType::EOR_TOKEN_TYPE); 159 160 // Now compute the visiable tokens that can follow this rule, according to context 161 // and make them part of the follow set. 162 // 163 viableTokensFollowingThisRule = this->computeCSRuleFollow(); 164 followClone->borInPlace(viableTokensFollowingThisRule); 165 } 166 167 /// if current token is consistent with what could come after set 168 /// then we know we're missing a token; error recovery is free to 169 /// "insert" the missing token 170 /// 171 /// BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR 172 /// in follow set to indicate that the fall of the start symbol is 173 /// in the set (EOF can follow). 174 /// 175 if ( followClone->isMember(is->_LA(1)) 176 || followClone->isMember(ImplTraits::CommonTokenType::EOR_TOKEN_TYPE) 177 ) 178 { 179 retcode = true; 180 } 181 else 182 { 183 retcode = false; 184 } 185 186 if (viableTokensFollowingThisRule != NULL) 187 { 188 delete viableTokensFollowingThisRule; 189 } 190 if (followClone != NULL) 191 { 192 delete followClone; 193 } 194 195 return retcode; 196} 197 198template< class ImplTraits, class StreamType > 199void BaseRecognizer<ImplTraits, StreamType>::mismatch(ANTLR_UINT32 ttype, BitsetListType* follow) 200{ 201 this->get_super()->mismatch( ttype, follow ); 202} 203 204template< class ImplTraits, class StreamType > 205void BaseRecognizer<ImplTraits, StreamType>::reportError() 206{ 207 this->reportError( ClassForwarder<SuperType>() ); 208} 209 210template< class ImplTraits, class StreamType > 211void BaseRecognizer<ImplTraits, StreamType>::reportError( ClassForwarder<LexerType> ) 212{ 213 // Indicate this recognizer had an error while processing. 214 // 215 m_state->inc_errorCount(); 216 217 this->displayRecognitionError(m_state->get_tokenNames()); 218} 219 220template< class ImplTraits, class StreamType > 221template<typename CompType> 222void BaseRecognizer<ImplTraits, StreamType>::reportError(ClassForwarder<CompType> ) 223{ 224 // Invoke the debugger event if there is a debugger listening to us 225 // 226 if ( m_debugger != NULL) 227 { 228 m_debugger->recognitionException( m_state->get_exception() ); 229 } 230 231 if ( m_state->get_errorRecovery() == true) 232 { 233 // Already in error recovery so don't display another error while doing so 234 // 235 return; 236 } 237 238 // Signal we are in error recovery now 239 // 240 m_state->set_errorRecovery(true); 241 242 // Indicate this recognizer had an error while processing. 243 // 244 m_state->inc_errorCount(); 245 246 // Call the error display routine 247 // 248 this->displayRecognitionError( m_state->get_tokenNames() ); 249} 250 251template< class ImplTraits, class StreamType > 252void BaseRecognizer<ImplTraits, StreamType>::displayRecognitionError(ANTLR_UINT8** tokenNames) 253{ 254 // Retrieve some info for easy reading. 255 // 256 ExceptionBaseType* ex = m_state->get_exception(); 257 StringType ttext; 258 259 // See if there is a 'filename' we can use 260 // 261 SuperType* super = static_cast<SuperType*>(this); 262 super->displayRecognitionError(tokenNames, ex); 263} 264 265template< class ImplTraits, class StreamType > 266ANTLR_UINT32 BaseRecognizer<ImplTraits, StreamType>::getNumberOfSyntaxErrors() 267{ 268 return m_state->get_errorCount(); 269} 270 271template< class ImplTraits, class StreamType > 272void BaseRecognizer<ImplTraits, StreamType>::recover() 273{ 274 SuperType* super = static_cast<SuperType*>(this); 275 IntStreamType* is = super->get_parser_istream(); 276 // Are we about to repeat the same error? 277 // 278 if ( m_state->get_lastErrorIndex() == is->index()) 279 { 280 // The last error was at the same token index point. This must be a case 281 // where LT(1) is in the recovery token set so nothing is 282 // consumed. Consume a single token so at least to prevent 283 // an infinite loop; this is a failsafe. 284 // 285 is->consume(); 286 } 287 288 // Record error index position 289 // 290 m_state->set_lastErrorIndex( is->index() ); 291 292 // Work out the follows set for error recovery 293 // 294 BitsetType* followSet = this->computeErrorRecoverySet(); 295 296 // Call resync hook (for debuggers and so on) 297 // 298 this->beginResync(); 299 300 // Consume tokens until we have resynced to something in the follows set 301 // 302 this->consumeUntilSet(followSet); 303 304 // End resync hook 305 // 306 this->endResync(); 307 308 // Destroy the temporary bitset we produced. 309 // 310 delete followSet; 311 312 // Reset the inError flag so we don't re-report the exception 313 // 314 m_state->set_error(false); 315 m_state->set_failed(false); 316} 317 318template< class ImplTraits, class StreamType > 319void BaseRecognizer<ImplTraits, StreamType>::beginResync() 320{ 321 if (m_debugger != NULL) 322 { 323 m_debugger->beginResync(); 324 } 325} 326 327template< class ImplTraits, class StreamType > 328void BaseRecognizer<ImplTraits, StreamType>::endResync() 329{ 330 if (m_debugger != NULL) 331 { 332 m_debugger->endResync(); 333 } 334} 335 336template< class ImplTraits, class StreamType > 337void BaseRecognizer<ImplTraits, StreamType>::beginBacktrack(ANTLR_UINT32 level) 338{ 339 if (m_debugger != NULL) 340 { 341 m_debugger->beginBacktrack(level); 342 } 343} 344 345template< class ImplTraits, class StreamType > 346void BaseRecognizer<ImplTraits, StreamType>::endBacktrack(ANTLR_UINT32 level, bool successful) 347{ 348 if (m_debugger != NULL) 349 { 350 m_debugger->endBacktrack(level); 351 } 352} 353 354template< class ImplTraits, class StreamType > 355typename BaseRecognizer<ImplTraits, StreamType>::BitsetType* BaseRecognizer<ImplTraits, StreamType>::computeErrorRecoverySet() 356{ 357 return this->combineFollows(false); 358} 359 360template< class ImplTraits, class StreamType > 361typename BaseRecognizer<ImplTraits, StreamType>::BitsetType* BaseRecognizer<ImplTraits, StreamType>::computeCSRuleFollow() 362{ 363 return this->combineFollows(false); 364} 365 366template< class ImplTraits, class StreamType > 367typename BaseRecognizer<ImplTraits, StreamType>::BitsetType* BaseRecognizer<ImplTraits, StreamType>::combineFollows(bool exact) 368{ 369 BitsetType* followSet; 370 BitsetType* localFollowSet; 371 ANTLR_UINT32 top; 372 ANTLR_UINT32 i; 373 374 top = static_cast<ANTLR_UINT32>( m_state->get_following().size() ); 375 376 followSet = new BitsetType(0); 377 localFollowSet = NULL; 378 379 for (i = top; i>0; i--) 380 { 381 localFollowSet = m_state->get_following().at(i-1).bitsetLoad(); 382 383 if (localFollowSet != NULL) 384 { 385 followSet->borInPlace(localFollowSet); 386 387 if (exact == true) 388 { 389 if (localFollowSet->isMember( ImplTraits::CommonTokenType::EOR_TOKEN_TYPE) == false) 390 { 391 // Only leave EOR in the set if at top (start rule); this lets us know 392 // if we have to include the follow(start rule); I.E., EOF 393 // 394 if (i>1) 395 { 396 followSet->remove(ImplTraits::CommonTokenType::EOR_TOKEN_TYPE); 397 } 398 } 399 else 400 { 401 break; // Cannot see End Of Rule from here, just drop out 402 } 403 } 404 delete localFollowSet; 405 localFollowSet = NULL; 406 } 407 } 408 409 if (localFollowSet != NULL) 410 { 411 delete localFollowSet; 412 } 413 return followSet; 414} 415 416template< class ImplTraits, class StreamType > 417const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 418BaseRecognizer<ImplTraits, StreamType>::recoverFromMismatchedToken( ANTLR_UINT32 ttype, BitsetListType* follow) 419{ 420 SuperType* super = static_cast<SuperType*>(this); 421 IntStreamType* is = super->get_parser_istream(); 422 const UnitType* matchedSymbol; 423 424 // If the next token after the one we are looking at in the input stream 425 // is what we are looking for then we remove the one we have discovered 426 // from the stream by consuming it, then consume this next one along too as 427 // if nothing had happened. 428 // 429 if ( this->mismatchIsUnwantedToken( is, ttype) == true) 430 { 431 // Create an exception if we need one 432 // 433 new ANTLR_Exception<ImplTraits, UNWANTED_TOKEN_EXCEPTION, StreamType>(this, ""); 434 435 // Call resync hook (for debuggers and so on) 436 // 437 if (m_debugger != NULL) 438 { 439 m_debugger->beginResync(); 440 } 441 442 // "delete" the extra token 443 // 444 this->beginResync(); 445 is->consume(); 446 this->endResync(); 447 // End resync hook 448 // 449 if (m_debugger != NULL) 450 { 451 m_debugger->endResync(); 452 } 453 454 // Print out the error after we consume so that ANTLRWorks sees the 455 // token in the exception. 456 // 457 this->reportError(); 458 459 // Return the token we are actually matching 460 // 461 matchedSymbol = this->getCurrentInputSymbol(is); 462 463 // Consume the token that the rule actually expected to get as if everything 464 // was hunky dory. 465 // 466 is->consume(); 467 468 m_state->set_error(false); // Exception is not outstanding any more 469 470 return matchedSymbol; 471 } 472 473 // Single token deletion (Unwanted above) did not work 474 // so we see if we can insert a token instead by calculating which 475 // token would be missing 476 // 477 if ( this->mismatchIsMissingToken(is, follow)) 478 { 479 // We can fake the missing token and proceed 480 // 481 new ANTLR_Exception<ImplTraits, MISSING_TOKEN_EXCEPTION, StreamType>(this, ""); 482 matchedSymbol = this->getMissingSymbol( is, m_state->get_exception(), ttype, follow); 483 m_state->get_exception()->set_token( matchedSymbol ); 484 m_state->get_exception()->set_expecting(ttype); 485 486 // Print out the error after we insert so that ANTLRWorks sees the 487 // token in the exception. 488 // 489 this->reportError(); 490 491 m_state->set_error(false); // Exception is not outstanding any more 492 493 return matchedSymbol; 494 } 495 496 // Create an exception if we need one 497 // 498 new ANTLR_Exception<ImplTraits, RECOGNITION_EXCEPTION, StreamType>(this, ""); 499 500 // Neither deleting nor inserting tokens allows recovery 501 // must just report the exception. 502 // 503 m_state->set_error(true); 504 return NULL; 505} 506 507template< class ImplTraits, class StreamType > 508const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 509BaseRecognizer<ImplTraits, StreamType>::recoverFromMismatchedSet(BitsetListType* follow) 510{ 511 SuperType* super = static_cast<SuperType*>(this); 512 IntStreamType* is = super->get_parser_istream(); 513 const UnitType* matchedSymbol; 514 515 if (this->mismatchIsMissingToken(is, follow) == true) 516 { 517 // We can fake the missing token and proceed 518 // 519 new ANTLR_Exception<ImplTraits, MISSING_TOKEN_EXCEPTION, StreamType>(this); 520 matchedSymbol = this->getMissingSymbol(is, m_state->get_exception(), follow); 521 m_state->get_exception()->set_token(matchedSymbol); 522 523 // Print out the error after we insert so that ANTLRWorks sees the 524 // token in the exception. 525 // 526 this->reportError(); 527 528 m_state->set_error(false); // Exception is not outstanding any more 529 530 return matchedSymbol; 531 } 532 533 // TODO - Single token deletion like in recoverFromMismatchedToken() 534 // 535 m_state->set_error(true); 536 m_state->set_failed(true); 537 return NULL; 538} 539 540template< class ImplTraits, class StreamType > 541bool BaseRecognizer<ImplTraits, StreamType>::recoverFromMismatchedElement(BitsetListType* followBits) 542{ 543 SuperType* super = static_cast<SuperType*>(this); 544 IntStreamType* is = super->get_parser_istream(); 545 546 BitsetType* follow = followBits->load(); 547 BitsetType* viableToksFollowingRule; 548 549 if (follow == NULL) 550 { 551 /* The follow set is NULL, which means we don't know what can come 552 * next, so we "hit and hope" by just signifying that we cannot 553 * recover, which will just cause the next token to be consumed, 554 * which might dig us out. 555 */ 556 return false; 557 } 558 559 /* We have a bitmap for the follow set, hence we can compute 560 * what can follow this grammar element reference. 561 */ 562 if (follow->isMember( ImplTraits::CommonTokenType::EOR_TOKEN_TYPE) == true) 563 { 564 /* First we need to know which of the available tokens are viable 565 * to follow this reference. 566 */ 567 viableToksFollowingRule = this->computeCSRuleFollow(); 568 569 /* Remove the EOR token, which we do not wish to compute with 570 */ 571 follow->remove( ImplTraits::CommonTokenType::EOR_TOKEN_TYPE); 572 delete viableToksFollowingRule; 573 /* We now have the computed set of what can follow the current token 574 */ 575 } 576 577 /* We can now see if the current token works with the set of tokens 578 * that could follow the current grammar reference. If it looks like it 579 * is consistent, then we can "insert" that token by not throwing 580 * an exception and assuming that we saw it. 581 */ 582 if ( follow->isMember(is->_LA(1)) == true) 583 { 584 /* report the error, but don't cause any rules to abort and stuff 585 */ 586 this->reportError(); 587 if (follow != NULL) 588 { 589 delete follow; 590 } 591 m_state->set_error(false); 592 m_state->set_failed(false); 593 return true; /* Success in recovery */ 594 } 595 596 if (follow != NULL) 597 { 598 delete follow; 599 } 600 601 /* We could not find anything viable to do, so this is going to 602 * cause an exception. 603 */ 604 return false; 605} 606 607template< class ImplTraits, class StreamType > 608void BaseRecognizer<ImplTraits, StreamType>::consumeUntil(ANTLR_UINT32 tokenType) 609{ 610 SuperType* super = static_cast<SuperType*>(this); 611 IntStreamType* is = super->get_parser_istream(); 612 613 // What do have at the moment? 614 // 615 ANTLR_UINT32 ttype = is->_LA(1); 616 617 // Start eating tokens until we get to the one we want. 618 // 619 while (ttype != ImplTraits::CommonTokenType::TOKEN_EOF && ttype != tokenType) 620 { 621 is->consume(); 622 ttype = is->_LA(1); 623 } 624} 625 626template< class ImplTraits, class StreamType > 627void BaseRecognizer<ImplTraits, StreamType>::consumeUntilSet(BitsetType* set) 628{ 629 ANTLR_UINT32 ttype; 630 SuperType* super = static_cast<SuperType*>(this); 631 IntStreamType* is = super->get_parser_istream(); 632 633 // What do have at the moment? 634 // 635 ttype = is->_LA(1); 636 637 // Start eating tokens until we get to one we want. 638 // 639 while (ttype != ImplTraits::CommonTokenType::TOKEN_EOF && set->isMember(ttype) == false) 640 { 641 is->consume(); 642 ttype = is->_LA(1); 643 } 644 645} 646 647template< class ImplTraits, class StreamType > 648ANTLR_MARKER BaseRecognizer<ImplTraits, StreamType>::getRuleMemoization( ANTLR_INTKEY ruleIndex, ANTLR_MARKER ruleParseStart) 649{ 650 /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST. 651 */ 652 typedef IntTrie<ImplTraits, ANTLR_MARKER> RuleListType; 653 typedef TrieEntry<ImplTraits, RuleListType*> EntryType; 654 typedef TrieEntry<ImplTraits, ANTLR_MARKER> SubEntryType; 655 ANTLR_MARKER stopIndex; 656 EntryType* entry; 657 658 /* See if we have a list in the ruleMemos for this rule, and if not, then create one 659 * as we will need it eventually if we are being asked for the memo here. 660 */ 661 entry = m_state->get_ruleMemo()->get(ruleIndex); 662 663 if (entry == NULL) 664 { 665 /* Did not find it, so create a new one for it, with a bit depth based on the 666 * size of the input stream. We need the bit depth to incorporate the number if 667 * bits required to represent the largest possible stop index in the input, which is the 668 * last character. An int stream is free to return the largest 64 bit offset if it has 669 * no idea of the size, but you should remember that this will cause the leftmost 670 * bit match algorithm to run to 63 bits, which will be the whole time spent in the trie ;-) 671 */ 672 m_state->get_ruleMemo()->add( ruleIndex, new RuleListType(63) ); 673 674 /* We cannot have a stopIndex in a trie we have just created of course 675 */ 676 return MEMO_RULE_UNKNOWN; 677 } 678 679 RuleListType* ruleList = entry->get_data(); 680 681 /* See if there is a stop index associated with the supplied start index. 682 */ 683 stopIndex = 0; 684 685 SubEntryType* sub_entry = ruleList->get(ruleParseStart); 686 if (sub_entry != NULL) 687 { 688 stopIndex = sub_entry->get_data(); 689 } 690 691 if (stopIndex == 0) 692 { 693 return MEMO_RULE_UNKNOWN; 694 } 695 696 return stopIndex; 697} 698 699template< class ImplTraits, class StreamType > 700bool BaseRecognizer<ImplTraits, StreamType>::alreadyParsedRule(ANTLR_MARKER ruleIndex) 701{ 702 SuperType* super = static_cast<SuperType*>(this); 703 IntStreamType* is = super->get_istream(); 704 705 /* See if we have a memo marker for this. 706 */ 707 ANTLR_MARKER stopIndex = this->getRuleMemoization( ruleIndex, is->index() ); 708 709 if (stopIndex == MEMO_RULE_UNKNOWN) 710 { 711 return false; 712 } 713 714 if (stopIndex == MEMO_RULE_FAILED) 715 { 716 m_state->set_failed(true); 717 } 718 else 719 { 720 is->seek(stopIndex+1); 721 } 722 723 /* If here then the rule was executed for this input already 724 */ 725 return true; 726} 727 728template< class ImplTraits, class StreamType > 729void BaseRecognizer<ImplTraits, StreamType>::memoize(ANTLR_MARKER ruleIndex, ANTLR_MARKER ruleParseStart) 730{ 731 /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST. 732 */ 733 typedef IntTrie<ImplTraits, ANTLR_MARKER> RuleListType; 734 typedef TrieEntry<ImplTraits, RuleListType*> EntryType; 735 EntryType* entry; 736 ANTLR_MARKER stopIndex; 737 SuperType* super = static_cast<SuperType*>(this); 738 IntStreamType* is = super->get_istream(); 739 740 stopIndex = (m_state->get_failed() == true) ? MEMO_RULE_FAILED : is->index() - 1; 741 742 entry = m_state->get_ruleMemo()->get(ruleIndex); 743 744 if (entry != NULL) 745 { 746 RuleListType* ruleList = entry->get_data(); 747 748 /* If we don't already have this entry, append it. The memoize trie does not 749 * accept duplicates so it won't add it if already there and we just ignore the 750 * return code as we don't care if it is there already. 751 */ 752 ruleList->add(ruleParseStart, stopIndex); 753 } 754} 755 756template< class ImplTraits, class StreamType > 757const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 758BaseRecognizer<ImplTraits, StreamType>::getCurrentInputSymbol( IntStreamType* istream ) 759{ 760 return this->getCurrentInputSymbol( istream, ClassForwarder<SuperType>() ); 761} 762 763template< class ImplTraits, class StreamType > 764const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 765BaseRecognizer<ImplTraits, StreamType>::getCurrentInputSymbol(IntStreamType* istream, ClassForwarder<LexerType>) 766{ 767 return NULL; 768} 769 770template< class ImplTraits, class StreamType > 771const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 772BaseRecognizer<ImplTraits, StreamType>::getCurrentInputSymbol(IntStreamType* istream, ClassForwarder<ParserType>) 773{ 774 typedef typename ImplTraits::TokenStreamType TokenStreamType; 775 TokenStreamType* token_stream = static_cast<TokenStreamType*>(istream); 776 return token_stream->_LT(1); 777} 778 779template< class ImplTraits, class StreamType > 780const typename BaseRecognizer<ImplTraits, StreamType>::UnitType* 781BaseRecognizer<ImplTraits, StreamType>::getCurrentInputSymbol(IntStreamType* istream, ClassForwarder<TreeParserType>) 782{ 783 typedef typename ImplTraits::TreeNodeStreamType TreeNodeStreamType; 784 TreeNodeStreamType* ctns = static_cast<TreeNodeStreamType*>(istream); 785 return ctns->_LT(1); 786} 787 788 789template< class ImplTraits, class StreamType > 790typename BaseRecognizer<ImplTraits, StreamType>::UnitType* BaseRecognizer<ImplTraits, StreamType>::getMissingSymbol( IntStreamType* istream, 791 ExceptionBaseType* e, 792 ANTLR_UINT32 expectedTokenType, 793 BitsetListType* follow) 794{ 795 return this->get_super()->getMissingSymbol( istream, e, expectedTokenType, follow ); 796} 797 798 799template< class ImplTraits, class StreamType > 800 template<typename Predicate> 801bool BaseRecognizer<ImplTraits, StreamType>::synpred(ClassForwarder<Predicate> pred) 802{ 803 ANTLR_MARKER start; 804 SuperType* super = static_cast<SuperType*>(this); 805 IntStreamType* is = super->get_istream(); 806 807 /* Begin backtracking so we can get back to where we started after trying out 808 * the syntactic predicate. 809 */ 810 start = is->mark(); 811 m_state->inc_backtracking(); 812 813 /* Try the syntactical predicate 814 */ 815 this->get_super()->synpred( pred ); 816 817 /* Reset 818 */ 819 is->rewind(start); 820 m_state->dec_backtracking(); 821 822 if ( m_state->get_failed() == true) 823 { 824 /* Predicate failed 825 */ 826 m_state->set_failed(false); 827 return false; 828 } 829 else 830 { 831 /* Predicate was successful 832 */ 833 m_state->set_failed(false); 834 return true; 835 } 836} 837 838template< class ImplTraits, class StreamType > 839void BaseRecognizer<ImplTraits, StreamType>::exConstruct() 840{ 841 this->get_super()->exConstruct(); 842} 843 844template< class ImplTraits, class StreamType > 845void BaseRecognizer<ImplTraits, StreamType>::reset() 846{ 847 this->reset( ClassForwarder<SuperType>() ); 848} 849 850template< class ImplTraits, class StreamType > 851template< typename CompType > 852void BaseRecognizer<ImplTraits, StreamType>::reset( ClassForwarder<CompType> ) 853{ 854 typedef typename RecognizerSharedStateType::RuleMemoType RuleMemoType; 855 m_state->get_following().clear(); 856 857 // Reset the state flags 858 // 859 m_state->set_errorRecovery(false); 860 m_state->set_lastErrorIndex(-1); 861 m_state->set_failed(false); 862 m_state->set_errorCount(0); 863 m_state->set_backtracking(0); 864 865 if (m_state->get_ruleMemo() != NULL) 866 { 867 delete m_state->get_ruleMemo(); 868 m_state->set_ruleMemo( new RuleMemoType(15) ); /* 16 bit depth is enough for 32768 rules! */ 869 } 870} 871 872template< class ImplTraits, class StreamType > 873void BaseRecognizer<ImplTraits, StreamType>::reset( ClassForwarder<LexerType> ) 874{ 875 m_state->set_token_present( false ); 876 m_state->set_type( ImplTraits::CommonTokenType::TOKEN_INVALID ); 877 m_state->set_channel( TOKEN_DEFAULT_CHANNEL ); 878 m_state->set_tokenStartCharIndex( -1 ); 879 m_state->set_tokenStartCharPositionInLine(-1); 880 m_state->set_tokenStartLine( -1 ); 881 m_state->set_text(""); 882} 883 884template< class ImplTraits, class StreamType > 885BaseRecognizer<ImplTraits, StreamType>::~BaseRecognizer() 886{ 887 // Did we have a state allocated? 888 // 889 if (m_state != NULL) 890 { 891 // Free any rule memoization we set up 892 // 893 if (m_state->get_ruleMemo() != NULL) 894 { 895 delete m_state->get_ruleMemo(); 896 m_state->set_ruleMemo(NULL); 897 } 898 899 900 // Free any exception space we have left around 901 // 902 ExceptionBaseType* thisE = m_state->get_exception(); 903 if (thisE != NULL) 904 { 905 delete thisE; 906 } 907 908 // Free the shared state memory 909 // 910 delete m_state; 911 } 912 913 // Free the actual recognizer space 914 // 915} 916 917 918 919ANTLR_END_NAMESPACE() 920