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