1*16467b97STreehugger RobotANTLR_BEGIN_NAMESPACE() 2*16467b97STreehugger Robot 3*16467b97STreehugger Robottemplate<class ImplTraits> 4*16467b97STreehugger RobotTokenSource<ImplTraits>::TokenSource() 5*16467b97STreehugger Robot :m_eofToken( ImplTraits::CommonTokenType::TOKEN_EOF), 6*16467b97STreehugger Robot m_skipToken( ImplTraits::CommonTokenType::TOKEN_INVALID) 7*16467b97STreehugger Robot{ 8*16467b97STreehugger Robot} 9*16467b97STreehugger Robot 10*16467b97STreehugger Robottemplate<class ImplTraits> 11*16467b97STreehugger RobotANTLR_INLINE typename TokenSource<ImplTraits>::CommonTokenType& TokenSource<ImplTraits>::get_eofToken() 12*16467b97STreehugger Robot{ 13*16467b97STreehugger Robot return m_eofToken; 14*16467b97STreehugger Robot} 15*16467b97STreehugger Robot 16*16467b97STreehugger Robottemplate<class ImplTraits> 17*16467b97STreehugger RobotANTLR_INLINE const typename TokenSource<ImplTraits>::TokenType& TokenSource<ImplTraits>::get_eofToken() const 18*16467b97STreehugger Robot{ 19*16467b97STreehugger Robot return m_eofToken; 20*16467b97STreehugger Robot} 21*16467b97STreehugger Robot 22*16467b97STreehugger Robottemplate<class ImplTraits> 23*16467b97STreehugger RobotANTLR_INLINE typename TokenSource<ImplTraits>::CommonTokenType& TokenSource<ImplTraits>::get_skipToken() 24*16467b97STreehugger Robot{ 25*16467b97STreehugger Robot return m_skipToken; 26*16467b97STreehugger Robot} 27*16467b97STreehugger Robot 28*16467b97STreehugger Robottemplate<class ImplTraits> 29*16467b97STreehugger RobotANTLR_INLINE typename TokenSource<ImplTraits>::StringType& TokenSource<ImplTraits>::get_fileName() 30*16467b97STreehugger Robot{ 31*16467b97STreehugger Robot return m_fileName; 32*16467b97STreehugger Robot} 33*16467b97STreehugger Robot 34*16467b97STreehugger Robottemplate<class ImplTraits> 35*16467b97STreehugger RobotANTLR_INLINE void TokenSource<ImplTraits>::set_fileName( const StringType& fileName ) 36*16467b97STreehugger Robot{ 37*16467b97STreehugger Robot m_fileName = fileName; 38*16467b97STreehugger Robot} 39*16467b97STreehugger Robot 40*16467b97STreehugger Robottemplate<class ImplTraits> 41*16467b97STreehugger Robottypename TokenSource<ImplTraits>::LexerType* TokenSource<ImplTraits>::get_super() 42*16467b97STreehugger Robot{ 43*16467b97STreehugger Robot return static_cast<LexerType*>(this); 44*16467b97STreehugger Robot} 45*16467b97STreehugger Robot 46*16467b97STreehugger Robottemplate<class ImplTraits> 47*16467b97STreehugger Robottypename TokenSource<ImplTraits>::TokenType* TokenSource<ImplTraits>::nextTokenStr() 48*16467b97STreehugger Robot{ 49*16467b97STreehugger Robot typedef typename LexerType::RecognizerSharedStateType RecognizerSharedStateType; 50*16467b97STreehugger Robot typedef typename LexerType::InputStreamType InputStreamType; 51*16467b97STreehugger Robot typedef typename LexerType::IntStreamType IntStreamType; 52*16467b97STreehugger Robot LexerType* lexer; 53*16467b97STreehugger Robot RecognizerSharedStateType* state; 54*16467b97STreehugger Robot InputStreamType* input; 55*16467b97STreehugger Robot IntStreamType* istream; 56*16467b97STreehugger Robot 57*16467b97STreehugger Robot lexer = this->get_super(); 58*16467b97STreehugger Robot state = lexer->get_rec()->get_state(); 59*16467b97STreehugger Robot input = lexer->get_input(); 60*16467b97STreehugger Robot istream = input->get_istream(); 61*16467b97STreehugger Robot 62*16467b97STreehugger Robot /// Loop until we get a non skipped token or EOF 63*16467b97STreehugger Robot /// 64*16467b97STreehugger Robot for (;;) 65*16467b97STreehugger Robot { 66*16467b97STreehugger Robot // Get rid of any previous token (token factory takes care of 67*16467b97STreehugger Robot // any de-allocation when this token is finally used up. 68*16467b97STreehugger Robot // 69*16467b97STreehugger Robot state->set_token_present(false); 70*16467b97STreehugger Robot state->set_error(false); // Start out without an exception 71*16467b97STreehugger Robot state->set_failed(false); 72*16467b97STreehugger Robot 73*16467b97STreehugger Robot // Now call the matching rules and see if we can generate a new token 74*16467b97STreehugger Robot // 75*16467b97STreehugger Robot for (;;) 76*16467b97STreehugger Robot { 77*16467b97STreehugger Robot // Record the start of the token in our input stream. 78*16467b97STreehugger Robot // 79*16467b97STreehugger Robot state->set_channel( TOKEN_DEFAULT_CHANNEL ); 80*16467b97STreehugger Robot state->set_tokenStartCharIndex( (ANTLR_MARKER)input->get_nextChar() ); 81*16467b97STreehugger Robot state->set_tokenStartCharPositionInLine( input->get_charPositionInLine() ); 82*16467b97STreehugger Robot state->set_tokenStartLine( input->get_line() ); 83*16467b97STreehugger Robot state->set_text(""); 84*16467b97STreehugger Robot 85*16467b97STreehugger Robot if (istream->_LA(1) == ANTLR_CHARSTREAM_EOF) 86*16467b97STreehugger Robot { 87*16467b97STreehugger Robot // Reached the end of the current stream, nothing more to do if this is 88*16467b97STreehugger Robot // the last in the stack. 89*16467b97STreehugger Robot // 90*16467b97STreehugger Robot TokenType& teof = m_eofToken; 91*16467b97STreehugger Robot 92*16467b97STreehugger Robot teof.set_startIndex(lexer->getCharIndex()); 93*16467b97STreehugger Robot teof.set_stopIndex(lexer->getCharIndex()); 94*16467b97STreehugger Robot teof.set_line(lexer->getLine()); 95*16467b97STreehugger Robot return &teof; 96*16467b97STreehugger Robot } 97*16467b97STreehugger Robot 98*16467b97STreehugger Robot state->set_token_present( false ); 99*16467b97STreehugger Robot state->set_error(false); // Start out without an exception 100*16467b97STreehugger Robot state->set_failed(false); 101*16467b97STreehugger Robot 102*16467b97STreehugger Robot // Call the generated lexer, see if it can get a new token together. 103*16467b97STreehugger Robot // 104*16467b97STreehugger Robot lexer->mTokens(); 105*16467b97STreehugger Robot 106*16467b97STreehugger Robot if (state->get_error() == true) 107*16467b97STreehugger Robot { 108*16467b97STreehugger Robot // Recognition exception, report it and try to recover. 109*16467b97STreehugger Robot // 110*16467b97STreehugger Robot state->set_failed(true); 111*16467b97STreehugger Robot lexer->get_rec()->reportError(); 112*16467b97STreehugger Robot lexer->recover(); 113*16467b97STreehugger Robot } 114*16467b97STreehugger Robot else 115*16467b97STreehugger Robot { 116*16467b97STreehugger Robot if ( !state->get_token_present() ) 117*16467b97STreehugger Robot { 118*16467b97STreehugger Robot // Emit the real token, which adds it in to the token stream basically 119*16467b97STreehugger Robot // 120*16467b97STreehugger Robot lexer->emit(); 121*16467b97STreehugger Robot } 122*16467b97STreehugger Robot else if ( *(state->get_token()) == m_skipToken ) 123*16467b97STreehugger Robot { 124*16467b97STreehugger Robot // A real token could have been generated, but "Computer say's naaaaah" and it 125*16467b97STreehugger Robot // it is just something we need to skip altogether. 126*16467b97STreehugger Robot // 127*16467b97STreehugger Robot continue; 128*16467b97STreehugger Robot } 129*16467b97STreehugger Robot 130*16467b97STreehugger Robot // Good token, not skipped, not EOF token 131*16467b97STreehugger Robot // 132*16467b97STreehugger Robot return state->get_token(); 133*16467b97STreehugger Robot } 134*16467b97STreehugger Robot } 135*16467b97STreehugger Robot } 136*16467b97STreehugger Robot} 137*16467b97STreehugger Robot 138*16467b97STreehugger Robottemplate<class ImplTraits> 139*16467b97STreehugger Robottypename TokenSource<ImplTraits>::TokenType* TokenSource<ImplTraits>::nextToken() 140*16467b97STreehugger Robot{ 141*16467b97STreehugger Robot return this->nextToken( BoolForwarder<LexerType::IsFiltered>() ); 142*16467b97STreehugger Robot} 143*16467b97STreehugger Robot 144*16467b97STreehugger Robottemplate<class ImplTraits> 145*16467b97STreehugger Robottypename TokenSource<ImplTraits>::CommonTokenType* TokenSource<ImplTraits>::nextToken( BoolForwarder<true> /*isFiltered*/ ) 146*16467b97STreehugger Robot{ 147*16467b97STreehugger Robot LexerType* lexer; 148*16467b97STreehugger Robot typename LexerType::RecognizerSharedStateType* state; 149*16467b97STreehugger Robot 150*16467b97STreehugger Robot lexer = this->get_super(); 151*16467b97STreehugger Robot state = lexer->get_lexstate(); 152*16467b97STreehugger Robot 153*16467b97STreehugger Robot /* Get rid of any previous token (token factory takes care of 154*16467b97STreehugger Robot * any deallocation when this token is finally used up. 155*16467b97STreehugger Robot */ 156*16467b97STreehugger Robot state->set_token_present( false ); 157*16467b97STreehugger Robot state->set_error( false ); /* Start out without an exception */ 158*16467b97STreehugger Robot state->set_failed(false); 159*16467b97STreehugger Robot 160*16467b97STreehugger Robot /* Record the start of the token in our input stream. 161*16467b97STreehugger Robot */ 162*16467b97STreehugger Robot state->set_tokenStartCharIndex( lexer->index() ); 163*16467b97STreehugger Robot state->set_tokenStartCharPositionInLine( lexer->getCharPositionInLine() ); 164*16467b97STreehugger Robot state->set_tokenStartLine( lexer->getLine() ); 165*16467b97STreehugger Robot state->set_text(""); 166*16467b97STreehugger Robot 167*16467b97STreehugger Robot /* Now call the matching rules and see if we can generate a new token 168*16467b97STreehugger Robot */ 169*16467b97STreehugger Robot for (;;) 170*16467b97STreehugger Robot { 171*16467b97STreehugger Robot if (lexer->LA(1) == ANTLR_CHARSTREAM_EOF) 172*16467b97STreehugger Robot { 173*16467b97STreehugger Robot /* Reached the end of the stream, nothing more to do. 174*16467b97STreehugger Robot */ 175*16467b97STreehugger Robot CommonTokenType& teof = m_eofToken; 176*16467b97STreehugger Robot 177*16467b97STreehugger Robot teof.set_startIndex(lexer->getCharIndex()); 178*16467b97STreehugger Robot teof.set_stopIndex(lexer->getCharIndex()); 179*16467b97STreehugger Robot teof.set_line(lexer->getLine()); 180*16467b97STreehugger Robot return &teof; 181*16467b97STreehugger Robot } 182*16467b97STreehugger Robot 183*16467b97STreehugger Robot state->set_token_present(false); 184*16467b97STreehugger Robot state->set_error(false); /* Start out without an exception */ 185*16467b97STreehugger Robot 186*16467b97STreehugger Robot { 187*16467b97STreehugger Robot ANTLR_MARKER m; 188*16467b97STreehugger Robot 189*16467b97STreehugger Robot m = lexer->get_istream()->mark(); 190*16467b97STreehugger Robot state->set_backtracking(1); /* No exceptions */ 191*16467b97STreehugger Robot state->set_failed(false); 192*16467b97STreehugger Robot 193*16467b97STreehugger Robot /* Call the generated lexer, see if it can get a new token together. 194*16467b97STreehugger Robot */ 195*16467b97STreehugger Robot lexer->mTokens(); 196*16467b97STreehugger Robot state->set_backtracking(0); 197*16467b97STreehugger Robot 198*16467b97STreehugger Robot /* mTokens backtracks with synpred at BACKTRACKING==2 199*16467b97STreehugger Robot and we set the synpredgate to allow actions at level 1. */ 200*16467b97STreehugger Robot 201*16467b97STreehugger Robot if(state->get_failed()) 202*16467b97STreehugger Robot { 203*16467b97STreehugger Robot lexer->rewind(m); 204*16467b97STreehugger Robot lexer->consume(); //<! advance one char and try again !> 205*16467b97STreehugger Robot } 206*16467b97STreehugger Robot else 207*16467b97STreehugger Robot { 208*16467b97STreehugger Robot lexer->emit(); /* Assemble the token and emit it to the stream */ 209*16467b97STreehugger Robot TokenType* tok = state->get_token(); 210*16467b97STreehugger Robot return tok; 211*16467b97STreehugger Robot } 212*16467b97STreehugger Robot } 213*16467b97STreehugger Robot } 214*16467b97STreehugger Robot} 215*16467b97STreehugger Robot 216*16467b97STreehugger Robottemplate<class ImplTraits> 217*16467b97STreehugger Robottypename TokenSource<ImplTraits>::CommonTokenType* TokenSource<ImplTraits>::nextToken( BoolForwarder<false> /*isFiltered*/ ) 218*16467b97STreehugger Robot{ 219*16467b97STreehugger Robot // Find the next token in the current stream 220*16467b97STreehugger Robot // 221*16467b97STreehugger Robot CommonTokenType* tok = this->nextTokenStr(); 222*16467b97STreehugger Robot 223*16467b97STreehugger Robot // If we got to the EOF token then switch to the previous 224*16467b97STreehugger Robot // input stream if there were any and just return the 225*16467b97STreehugger Robot // EOF if there are none. We must check the next token 226*16467b97STreehugger Robot // in any outstanding input stream we pop into the active 227*16467b97STreehugger Robot // role to see if it was sitting at EOF after PUSHing the 228*16467b97STreehugger Robot // stream we just consumed, otherwise we will return EOF 229*16467b97STreehugger Robot // on the reinstalled input stream, when in actual fact 230*16467b97STreehugger Robot // there might be more input streams to POP before the 231*16467b97STreehugger Robot // real EOF of the whole logical inptu stream. Hence we 232*16467b97STreehugger Robot // use a while loop here until we find somethign in the stream 233*16467b97STreehugger Robot // that isn't EOF or we reach the actual end of the last input 234*16467b97STreehugger Robot // stream on the stack. 235*16467b97STreehugger Robot // 236*16467b97STreehugger Robot while(tok->get_type() == CommonTokenType::TOKEN_EOF) 237*16467b97STreehugger Robot { 238*16467b97STreehugger Robot typename ImplTraits::LexerType* lexer; 239*16467b97STreehugger Robot lexer = static_cast<typename ImplTraits::LexerType*>( this->get_super() ); 240*16467b97STreehugger Robot 241*16467b97STreehugger Robot if ( lexer->get_rec()->get_state()->get_streams().size() > 0) 242*16467b97STreehugger Robot { 243*16467b97STreehugger Robot // We have another input stream in the stack so we 244*16467b97STreehugger Robot // need to revert to it, then resume the loop to check 245*16467b97STreehugger Robot // it wasn't sitting at EOF itself. 246*16467b97STreehugger Robot // 247*16467b97STreehugger Robot lexer->popCharStream(); 248*16467b97STreehugger Robot tok = this->nextTokenStr(); 249*16467b97STreehugger Robot } 250*16467b97STreehugger Robot else 251*16467b97STreehugger Robot { 252*16467b97STreehugger Robot // There were no more streams on the input stack 253*16467b97STreehugger Robot // so this EOF is the 'real' logical EOF for 254*16467b97STreehugger Robot // the input stream. So we just exit the loop and 255*16467b97STreehugger Robot // return the EOF we have found. 256*16467b97STreehugger Robot // 257*16467b97STreehugger Robot break; 258*16467b97STreehugger Robot } 259*16467b97STreehugger Robot 260*16467b97STreehugger Robot } 261*16467b97STreehugger Robot 262*16467b97STreehugger Robot // return whatever token we have, which may be EOF 263*16467b97STreehugger Robot // 264*16467b97STreehugger Robot return tok; 265*16467b97STreehugger Robot} 266*16467b97STreehugger Robot 267*16467b97STreehugger Robottemplate<class ImplTraits> 268*16467b97STreehugger RobotTokenStream<ImplTraits>::TokenStream() 269*16467b97STreehugger Robot{ 270*16467b97STreehugger Robot m_tokenSource = NULL; 271*16467b97STreehugger Robot m_debugger = NULL; 272*16467b97STreehugger Robot m_initialStreamState = false; 273*16467b97STreehugger Robot} 274*16467b97STreehugger Robot 275*16467b97STreehugger Robottemplate<class ImplTraits> 276*16467b97STreehugger Robottypename TokenStream<ImplTraits>::IntStreamType* TokenStream<ImplTraits>::get_istream() 277*16467b97STreehugger Robot{ 278*16467b97STreehugger Robot return this; 279*16467b97STreehugger Robot} 280*16467b97STreehugger Robot 281*16467b97STreehugger Robottemplate<class ImplTraits> 282*16467b97STreehugger RobotTokenStream<ImplTraits>::TokenStream(TokenSourceType* source, DebugEventListenerType* debugger) 283*16467b97STreehugger Robot{ 284*16467b97STreehugger Robot m_initialStreamState = false; 285*16467b97STreehugger Robot m_tokenSource = source; 286*16467b97STreehugger Robot m_debugger = debugger; 287*16467b97STreehugger Robot} 288*16467b97STreehugger Robot 289*16467b97STreehugger Robottemplate<class ImplTraits> 290*16467b97STreehugger RobotCommonTokenStream<ImplTraits>::CommonTokenStream(ANTLR_UINT32 , TokenSourceType* source, 291*16467b97STreehugger Robot DebugEventListenerType* debugger) 292*16467b97STreehugger Robot : CommonTokenStream<ImplTraits>::BaseType( source, debugger ) 293*16467b97STreehugger Robot{ 294*16467b97STreehugger Robot m_p = -1; 295*16467b97STreehugger Robot m_channel = TOKEN_DEFAULT_CHANNEL; 296*16467b97STreehugger Robot m_discardOffChannel = false; 297*16467b97STreehugger Robot m_nissued = 0; 298*16467b97STreehugger Robot} 299*16467b97STreehugger Robot 300*16467b97STreehugger Robottemplate<class ImplTraits> 301*16467b97STreehugger Robottypename CommonTokenStream<ImplTraits>::TokensType& CommonTokenStream<ImplTraits>::get_tokens() 302*16467b97STreehugger Robot{ 303*16467b97STreehugger Robot return m_tokens; 304*16467b97STreehugger Robot} 305*16467b97STreehugger Robot 306*16467b97STreehugger Robottemplate<class ImplTraits> 307*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokensType& CommonTokenStream<ImplTraits>::get_tokens() const 308*16467b97STreehugger Robot{ 309*16467b97STreehugger Robot return m_tokens; 310*16467b97STreehugger Robot} 311*16467b97STreehugger Robot 312*16467b97STreehugger Robottemplate<class ImplTraits> 313*16467b97STreehugger Robottypename CommonTokenStream<ImplTraits>::DiscardSetType& CommonTokenStream<ImplTraits>::get_discardSet() 314*16467b97STreehugger Robot{ 315*16467b97STreehugger Robot return m_discardSet; 316*16467b97STreehugger Robot} 317*16467b97STreehugger Robot 318*16467b97STreehugger Robottemplate<class ImplTraits> 319*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::DiscardSetType& CommonTokenStream<ImplTraits>::get_discardSet() const 320*16467b97STreehugger Robot{ 321*16467b97STreehugger Robot return m_discardSet; 322*16467b97STreehugger Robot} 323*16467b97STreehugger Robot 324*16467b97STreehugger Robottemplate<class ImplTraits> 325*16467b97STreehugger RobotANTLR_INLINE ANTLR_INT32 CommonTokenStream<ImplTraits>::get_p() const 326*16467b97STreehugger Robot{ 327*16467b97STreehugger Robot return m_p; 328*16467b97STreehugger Robot} 329*16467b97STreehugger Robot 330*16467b97STreehugger Robottemplate<class ImplTraits> 331*16467b97STreehugger RobotANTLR_INLINE void CommonTokenStream<ImplTraits>::set_p( ANTLR_INT32 p ) 332*16467b97STreehugger Robot{ 333*16467b97STreehugger Robot m_p = p; 334*16467b97STreehugger Robot} 335*16467b97STreehugger Robot 336*16467b97STreehugger Robottemplate<class ImplTraits> 337*16467b97STreehugger RobotANTLR_INLINE void CommonTokenStream<ImplTraits>::inc_p() 338*16467b97STreehugger Robot{ 339*16467b97STreehugger Robot ++m_p; 340*16467b97STreehugger Robot} 341*16467b97STreehugger Robot 342*16467b97STreehugger Robottemplate<class ImplTraits> 343*16467b97STreehugger RobotANTLR_INLINE void CommonTokenStream<ImplTraits>::dec_p() 344*16467b97STreehugger Robot{ 345*16467b97STreehugger Robot --m_p; 346*16467b97STreehugger Robot} 347*16467b97STreehugger Robot 348*16467b97STreehugger Robottemplate<class ImplTraits> 349*16467b97STreehugger RobotANTLR_INLINE ANTLR_MARKER CommonTokenStream<ImplTraits>::index_impl() 350*16467b97STreehugger Robot{ 351*16467b97STreehugger Robot return m_p; 352*16467b97STreehugger Robot} 353*16467b97STreehugger Robot 354*16467b97STreehugger Robot// Reset a token stream so it can be used again and can reuse it's 355*16467b97STreehugger Robot// resources. 356*16467b97STreehugger Robot// 357*16467b97STreehugger Robottemplate<class ImplTraits> 358*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::reset() 359*16467b97STreehugger Robot{ 360*16467b97STreehugger Robot // Free any resources that ar most like specifc to the 361*16467b97STreehugger Robot // run we just did. 362*16467b97STreehugger Robot // 363*16467b97STreehugger Robot m_discardSet.clear(); 364*16467b97STreehugger Robot m_channelOverrides.clear(); 365*16467b97STreehugger Robot 366*16467b97STreehugger Robot // Now, if there were any existing tokens in the stream, 367*16467b97STreehugger Robot // then we just reset the vector count so that it starts 368*16467b97STreehugger Robot // again. We must traverse the entries unfortunately as 369*16467b97STreehugger Robot // there may be free pointers for custom token types and 370*16467b97STreehugger Robot // so on. However that is just a quick NULL check on the 371*16467b97STreehugger Robot // vector entries. 372*16467b97STreehugger Robot // 373*16467b97STreehugger Robot m_tokens.clear(); 374*16467b97STreehugger Robot 375*16467b97STreehugger Robot // Reset to defaults 376*16467b97STreehugger Robot // 377*16467b97STreehugger Robot m_discardOffChannel = false; 378*16467b97STreehugger Robot m_channel = ImplTraits::CommonTokenType::TOKEN_DEFAULT_CHANNEL; 379*16467b97STreehugger Robot m_p = -1; 380*16467b97STreehugger Robot} 381*16467b97STreehugger Robot 382*16467b97STreehugger Robottemplate<class ImplTraits> 383*16467b97STreehugger Robotvoid TokenStream<ImplTraits>::setDebugListener(DebugEventListenerType* debugger) 384*16467b97STreehugger Robot{ 385*16467b97STreehugger Robot m_debugger = debugger; 386*16467b97STreehugger Robot m_initialStreamState = false; 387*16467b97STreehugger Robot} 388*16467b97STreehugger Robot 389*16467b97STreehugger Robottemplate<class ImplTraits> 390*16467b97STreehugger Robotconst typename TokenStream<ImplTraits>::TokenType* TokenStream<ImplTraits>::_LT(ANTLR_INT32 k) 391*16467b97STreehugger Robot{ 392*16467b97STreehugger Robot ANTLR_INT32 i; 393*16467b97STreehugger Robot ANTLR_INT32 n; 394*16467b97STreehugger Robot TokenStreamType* cts; 395*16467b97STreehugger Robot 396*16467b97STreehugger Robot cts = this->get_super(); 397*16467b97STreehugger Robot 398*16467b97STreehugger Robot if(k < 0) 399*16467b97STreehugger Robot { 400*16467b97STreehugger Robot return cts->LB(-k); 401*16467b97STreehugger Robot } 402*16467b97STreehugger Robot 403*16467b97STreehugger Robot ANTLR_INT32 req_idx = cts->get_p() + k - 1; 404*16467b97STreehugger Robot ANTLR_INT32 cached_size = static_cast<ANTLR_INT32>(this->get_istream()->get_cachedSize()); 405*16467b97STreehugger Robot 406*16467b97STreehugger Robot if( (cts->get_p() == -1) || 407*16467b97STreehugger Robot ( ( req_idx >= cached_size ) && ( (cached_size % ImplTraits::TOKEN_FILL_BUFFER_INCREMENT) == 0 ) ) 408*16467b97STreehugger Robot ) 409*16467b97STreehugger Robot { 410*16467b97STreehugger Robot cts->fillBuffer(); 411*16467b97STreehugger Robot } 412*16467b97STreehugger Robot 413*16467b97STreehugger Robot // Here we used to check for k == 0 and return 0, but this seems 414*16467b97STreehugger Robot // a superfluous check to me. LT(k=0) is therefore just undefined 415*16467b97STreehugger Robot // and we won't waste the clock cycles on the check 416*16467b97STreehugger Robot // 417*16467b97STreehugger Robot cached_size = static_cast<ANTLR_INT32>(this->get_istream()->get_cachedSize()); 418*16467b97STreehugger Robot if ( req_idx >= cached_size ) 419*16467b97STreehugger Robot { 420*16467b97STreehugger Robot TokenType& teof = cts->get_tokenSource()->get_eofToken(); 421*16467b97STreehugger Robot 422*16467b97STreehugger Robot teof.set_startIndex( this->get_istream()->index()); 423*16467b97STreehugger Robot teof.set_stopIndex( this->get_istream()->index()); 424*16467b97STreehugger Robot return &teof; 425*16467b97STreehugger Robot } 426*16467b97STreehugger Robot 427*16467b97STreehugger Robot i = cts->get_p(); 428*16467b97STreehugger Robot n = 1; 429*16467b97STreehugger Robot 430*16467b97STreehugger Robot /* Need to find k good tokens, skipping ones that are off channel 431*16467b97STreehugger Robot */ 432*16467b97STreehugger Robot while( n < k) 433*16467b97STreehugger Robot { 434*16467b97STreehugger Robot /* Skip off-channel tokens */ 435*16467b97STreehugger Robot i = cts->skipOffTokenChannels(i+1); /* leave p on valid token */ 436*16467b97STreehugger Robot n++; 437*16467b97STreehugger Robot } 438*16467b97STreehugger Robot 439*16467b97STreehugger Robot if( ( i >= cached_size ) && ( (cached_size % ImplTraits::TOKEN_FILL_BUFFER_INCREMENT) == 0 ) ) 440*16467b97STreehugger Robot { 441*16467b97STreehugger Robot cts->fillBuffer(); 442*16467b97STreehugger Robot } 443*16467b97STreehugger Robot if ( (ANTLR_UINT32) i >= this->get_istream()->get_cachedSize() ) 444*16467b97STreehugger Robot { 445*16467b97STreehugger Robot TokenType& teof = cts->get_tokenSource()->get_eofToken(); 446*16467b97STreehugger Robot 447*16467b97STreehugger Robot teof.set_startIndex(this->get_istream()->index()); 448*16467b97STreehugger Robot teof.set_stopIndex(this->get_istream()->index()); 449*16467b97STreehugger Robot return &teof; 450*16467b97STreehugger Robot } 451*16467b97STreehugger Robot 452*16467b97STreehugger Robot // Here the token must be in the input vector. Rather then incur 453*16467b97STreehugger Robot // function call penalty, we just return the pointer directly 454*16467b97STreehugger Robot // from the vector 455*16467b97STreehugger Robot // 456*16467b97STreehugger Robot return cts->getToken(i); 457*16467b97STreehugger Robot} 458*16467b97STreehugger Robot 459*16467b97STreehugger Robottemplate<class ImplTraits> 460*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokenType* CommonTokenStream<ImplTraits>::LB(ANTLR_INT32 k) 461*16467b97STreehugger Robot{ 462*16467b97STreehugger Robot ANTLR_INT32 i; 463*16467b97STreehugger Robot ANTLR_INT32 n; 464*16467b97STreehugger Robot 465*16467b97STreehugger Robot if (m_p == -1) 466*16467b97STreehugger Robot { 467*16467b97STreehugger Robot this->fillBuffer(); 468*16467b97STreehugger Robot } 469*16467b97STreehugger Robot if (k == 0) 470*16467b97STreehugger Robot { 471*16467b97STreehugger Robot return NULL; 472*16467b97STreehugger Robot } 473*16467b97STreehugger Robot if ((m_p - k) < 0) 474*16467b97STreehugger Robot { 475*16467b97STreehugger Robot return NULL; 476*16467b97STreehugger Robot } 477*16467b97STreehugger Robot 478*16467b97STreehugger Robot i = m_p; 479*16467b97STreehugger Robot n = 1; 480*16467b97STreehugger Robot 481*16467b97STreehugger Robot /* Need to find k good tokens, going backwards, skipping ones that are off channel 482*16467b97STreehugger Robot */ 483*16467b97STreehugger Robot while (n <= k) 484*16467b97STreehugger Robot { 485*16467b97STreehugger Robot /* Skip off-channel tokens 486*16467b97STreehugger Robot */ 487*16467b97STreehugger Robot 488*16467b97STreehugger Robot i = this->skipOffTokenChannelsReverse(i - 1); /* leave p on valid token */ 489*16467b97STreehugger Robot n++; 490*16467b97STreehugger Robot } 491*16467b97STreehugger Robot if (i < 0) 492*16467b97STreehugger Robot { 493*16467b97STreehugger Robot return NULL; 494*16467b97STreehugger Robot } 495*16467b97STreehugger Robot 496*16467b97STreehugger Robot // Here the token must be in the input vector. Rather then incut 497*16467b97STreehugger Robot // function call penalty, we jsut return the pointer directly 498*16467b97STreehugger Robot // from the vector 499*16467b97STreehugger Robot // 500*16467b97STreehugger Robot return this->getToken(i); 501*16467b97STreehugger Robot} 502*16467b97STreehugger Robot 503*16467b97STreehugger Robottemplate<class ImplTraits> 504*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokenType* CommonTokenStream<ImplTraits>::getToken(ANTLR_MARKER i) 505*16467b97STreehugger Robot{ 506*16467b97STreehugger Robot return this->get(i); 507*16467b97STreehugger Robot} 508*16467b97STreehugger Robot 509*16467b97STreehugger Robot 510*16467b97STreehugger Robottemplate<class ImplTraits> 511*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokenType* CommonTokenStream<ImplTraits>::get(ANTLR_MARKER i) 512*16467b97STreehugger Robot{ 513*16467b97STreehugger Robot return this->getToken( static_cast<ANTLR_MARKER>(i), 514*16467b97STreehugger Robot BoolForwarder<ImplTraits::TOKENS_ACCESSED_FROM_OWNING_RULE>() ); 515*16467b97STreehugger Robot} 516*16467b97STreehugger Robot 517*16467b97STreehugger Robottemplate<class ImplTraits> 518*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokenType* CommonTokenStream<ImplTraits>::getToken( ANTLR_MARKER tok_idx, 519*16467b97STreehugger Robot BoolForwarder<true> /*tokens_accessed_from_owning_rule*/ ) 520*16467b97STreehugger Robot{ 521*16467b97STreehugger Robot typename TokensType::iterator iter = m_tokens.find(tok_idx); 522*16467b97STreehugger Robot if( iter == m_tokens.end() ) 523*16467b97STreehugger Robot { 524*16467b97STreehugger Robot TokenAccessException ex; 525*16467b97STreehugger Robot throw ex; 526*16467b97STreehugger Robot } 527*16467b97STreehugger Robot const TokenType& tok = iter->second; 528*16467b97STreehugger Robot return &tok; 529*16467b97STreehugger Robot} 530*16467b97STreehugger Robot 531*16467b97STreehugger Robottemplate<class ImplTraits> 532*16467b97STreehugger Robotconst typename CommonTokenStream<ImplTraits>::TokenType* CommonTokenStream<ImplTraits>::getToken( ANTLR_MARKER tok_idx, BoolForwarder<false> /*tokens_accessed_from_owning_rule*/ ) 533*16467b97STreehugger Robot{ 534*16467b97STreehugger Robot TokenType& tok = m_tokens.at( static_cast<ANTLR_UINT32>(tok_idx) ); 535*16467b97STreehugger Robot return &tok; 536*16467b97STreehugger Robot} 537*16467b97STreehugger Robot 538*16467b97STreehugger Robottemplate<class ImplTraits> 539*16467b97STreehugger Robottypename TokenStream<ImplTraits>::TokenSourceType* TokenStream<ImplTraits>::get_tokenSource() const 540*16467b97STreehugger Robot{ 541*16467b97STreehugger Robot return m_tokenSource; 542*16467b97STreehugger Robot} 543*16467b97STreehugger Robot 544*16467b97STreehugger Robottemplate<class ImplTraits> 545*16467b97STreehugger Robotvoid TokenStream<ImplTraits>::set_tokenSource( TokenSourceType* tokenSource ) 546*16467b97STreehugger Robot{ 547*16467b97STreehugger Robot m_tokenSource = tokenSource; 548*16467b97STreehugger Robot} 549*16467b97STreehugger Robot 550*16467b97STreehugger Robottemplate<class ImplTraits> 551*16467b97STreehugger Robottypename TokenStream<ImplTraits>::StringType TokenStream<ImplTraits>::toString() 552*16467b97STreehugger Robot{ 553*16467b97STreehugger Robot TokenStreamType* cts = static_cast<TokenStreamType>(this); 554*16467b97STreehugger Robot 555*16467b97STreehugger Robot if (cts->get_p() == -1) 556*16467b97STreehugger Robot { 557*16467b97STreehugger Robot cts->fillBuffer(); 558*16467b97STreehugger Robot } 559*16467b97STreehugger Robot 560*16467b97STreehugger Robot return this->toStringSS(0, this->get_istream()->size()); 561*16467b97STreehugger Robot} 562*16467b97STreehugger Robot 563*16467b97STreehugger Robottemplate<class ImplTraits> 564*16467b97STreehugger Robottypename TokenStream<ImplTraits>::StringType 565*16467b97STreehugger RobotTokenStream<ImplTraits>::toStringSS(ANTLR_MARKER start, ANTLR_MARKER stop) 566*16467b97STreehugger Robot{ 567*16467b97STreehugger Robot StringType string; 568*16467b97STreehugger Robot TokenSourceType* tsource; 569*16467b97STreehugger Robot const TokenType* tok; 570*16467b97STreehugger Robot TokenStreamType* cts; 571*16467b97STreehugger Robot 572*16467b97STreehugger Robot cts = this->get_super(); 573*16467b97STreehugger Robot 574*16467b97STreehugger Robot if (cts->get_p() == -1) 575*16467b97STreehugger Robot { 576*16467b97STreehugger Robot cts->fillBuffer(); 577*16467b97STreehugger Robot } 578*16467b97STreehugger Robot if (stop >= this->get_istream()->size()) 579*16467b97STreehugger Robot { 580*16467b97STreehugger Robot stop = this->get_istream()->size() - 1; 581*16467b97STreehugger Robot } 582*16467b97STreehugger Robot 583*16467b97STreehugger Robot /* Who is giving us these tokens? 584*16467b97STreehugger Robot */ 585*16467b97STreehugger Robot tsource = cts->get_tokenSource(); 586*16467b97STreehugger Robot 587*16467b97STreehugger Robot if (tsource != NULL && !cts->get_tokens().empty() ) 588*16467b97STreehugger Robot { 589*16467b97STreehugger Robot /* Finally, let's get a string 590*16467b97STreehugger Robot */ 591*16467b97STreehugger Robot for (ANTLR_MARKER i = start; i <= stop; i++) 592*16467b97STreehugger Robot { 593*16467b97STreehugger Robot tok = cts->get(i); 594*16467b97STreehugger Robot if (tok != NULL) 595*16467b97STreehugger Robot { 596*16467b97STreehugger Robot string.append( tok->getText() ); 597*16467b97STreehugger Robot } 598*16467b97STreehugger Robot } 599*16467b97STreehugger Robot 600*16467b97STreehugger Robot return string; 601*16467b97STreehugger Robot } 602*16467b97STreehugger Robot return ""; 603*16467b97STreehugger Robot} 604*16467b97STreehugger Robot 605*16467b97STreehugger Robottemplate<class ImplTraits> 606*16467b97STreehugger Robottypename TokenStream<ImplTraits>::StringType 607*16467b97STreehugger RobotTokenStream<ImplTraits>::toStringTT(const TokenType* start, const TokenType* stop) 608*16467b97STreehugger Robot{ 609*16467b97STreehugger Robot if (start != NULL && stop != NULL) 610*16467b97STreehugger Robot { 611*16467b97STreehugger Robot return this->toStringSS( start->get_tokenIndex(), 612*16467b97STreehugger Robot stop->get_tokenIndex()); 613*16467b97STreehugger Robot } 614*16467b97STreehugger Robot else 615*16467b97STreehugger Robot { 616*16467b97STreehugger Robot return ""; 617*16467b97STreehugger Robot } 618*16467b97STreehugger Robot} 619*16467b97STreehugger Robot 620*16467b97STreehugger Robot/** A simple filter mechanism whereby you can tell this token stream 621*16467b97STreehugger Robot * to force all tokens of type ttype to be on channel. For example, 622*16467b97STreehugger Robot * when interpreting, we cannot execute actions so we need to tell 623*16467b97STreehugger Robot * the stream to force all WS and NEWLINE to be a different, ignored, 624*16467b97STreehugger Robot * channel. 625*16467b97STreehugger Robot */ 626*16467b97STreehugger Robottemplate<class ImplTraits> 627*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::setTokenTypeChannel ( ANTLR_UINT32 ttype, ANTLR_UINT32 channel) 628*16467b97STreehugger Robot{ 629*16467b97STreehugger Robot /* We add one to the channel so we can distinguish NULL as being no entry in the 630*16467b97STreehugger Robot * table for a particular token type. 631*16467b97STreehugger Robot */ 632*16467b97STreehugger Robot m_channelOverrides[ttype] = (ANTLR_UINT32)channel + 1; 633*16467b97STreehugger Robot 634*16467b97STreehugger Robot} 635*16467b97STreehugger Robot 636*16467b97STreehugger Robottemplate<class ImplTraits> 637*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::discardTokenType(ANTLR_INT32 ttype) 638*16467b97STreehugger Robot{ 639*16467b97STreehugger Robot /* We add one to the channel so we can distinguish NULL as being no entry in the 640*16467b97STreehugger Robot * table for a particular token type. We could use bitsets for this I suppose too. 641*16467b97STreehugger Robot */ 642*16467b97STreehugger Robot m_discardSet.insert(ttype); 643*16467b97STreehugger Robot} 644*16467b97STreehugger Robot 645*16467b97STreehugger Robottemplate<class ImplTraits> 646*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::discardOffChannelToks(bool discard) 647*16467b97STreehugger Robot{ 648*16467b97STreehugger Robot m_discardOffChannel = discard; 649*16467b97STreehugger Robot} 650*16467b97STreehugger Robot 651*16467b97STreehugger Robottemplate<class ImplTraits> 652*16467b97STreehugger Robottypename CommonTokenStream<ImplTraits>::TokensType* CommonTokenStream<ImplTraits>::getTokens() 653*16467b97STreehugger Robot{ 654*16467b97STreehugger Robot if (m_p == -1) 655*16467b97STreehugger Robot { 656*16467b97STreehugger Robot this->fillBuffer(); 657*16467b97STreehugger Robot } 658*16467b97STreehugger Robot 659*16467b97STreehugger Robot return &m_tokens; 660*16467b97STreehugger Robot} 661*16467b97STreehugger Robot 662*16467b97STreehugger Robottemplate<class ImplTraits> 663*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::getTokenRange(ANTLR_UINT32 start, ANTLR_UINT32 stop, 664*16467b97STreehugger Robot TokensListType& tokenRange) 665*16467b97STreehugger Robot{ 666*16467b97STreehugger Robot return this->getTokensSet(start, stop, NULL, tokenRange); 667*16467b97STreehugger Robot} 668*16467b97STreehugger Robot 669*16467b97STreehugger Robot/** Given a start and stop index, return a List of all tokens in 670*16467b97STreehugger Robot * the token type BitSet. Return null if no tokens were found. This 671*16467b97STreehugger Robot * method looks at both on and off channel tokens. 672*16467b97STreehugger Robot */ 673*16467b97STreehugger Robottemplate<class ImplTraits> 674*16467b97STreehugger Robotvoid 675*16467b97STreehugger RobotCommonTokenStream<ImplTraits>::getTokensSet(ANTLR_UINT32 start, ANTLR_UINT32 stop, BitsetType* types, 676*16467b97STreehugger Robot TokensListType& filteredList ) 677*16467b97STreehugger Robot{ 678*16467b97STreehugger Robot ANTLR_UINT32 i; 679*16467b97STreehugger Robot ANTLR_UINT32 n; 680*16467b97STreehugger Robot TokenType* tok; 681*16467b97STreehugger Robot 682*16467b97STreehugger Robot if ( m_p == -1) 683*16467b97STreehugger Robot { 684*16467b97STreehugger Robot this->fillBuffer(); 685*16467b97STreehugger Robot } 686*16467b97STreehugger Robot if (stop > this->get_istream()->size()) 687*16467b97STreehugger Robot { 688*16467b97STreehugger Robot stop = this->get_istream()->size(); 689*16467b97STreehugger Robot } 690*16467b97STreehugger Robot if (start > stop) 691*16467b97STreehugger Robot { 692*16467b97STreehugger Robot return; 693*16467b97STreehugger Robot } 694*16467b97STreehugger Robot 695*16467b97STreehugger Robot /* We have the range set, now we need to iterate through the 696*16467b97STreehugger Robot * installed tokens and create a new list with just the ones we want 697*16467b97STreehugger Robot * in it. We are just moving pointers about really. 698*16467b97STreehugger Robot */ 699*16467b97STreehugger Robot for(i = start, n = 0; i<= stop; i++) 700*16467b97STreehugger Robot { 701*16467b97STreehugger Robot tok = this->get(i); 702*16467b97STreehugger Robot 703*16467b97STreehugger Robot if ( types == NULL 704*16467b97STreehugger Robot || (types->isMember( tok->get_type() ) == true ) 705*16467b97STreehugger Robot ) 706*16467b97STreehugger Robot { 707*16467b97STreehugger Robot filteredList.push_back(tok); 708*16467b97STreehugger Robot } 709*16467b97STreehugger Robot } 710*16467b97STreehugger Robot 711*16467b97STreehugger Robot return ; 712*16467b97STreehugger Robot} 713*16467b97STreehugger Robot 714*16467b97STreehugger Robottemplate<class ImplTraits> 715*16467b97STreehugger Robotvoid 716*16467b97STreehugger RobotCommonTokenStream<ImplTraits>::getTokensList(ANTLR_UINT32 start, ANTLR_UINT32 stop, 717*16467b97STreehugger Robot const IntListType& list, TokensListType& newlist) 718*16467b97STreehugger Robot{ 719*16467b97STreehugger Robot BitsetType* bitSet; 720*16467b97STreehugger Robot 721*16467b97STreehugger Robot bitSet = Bitset<ImplTraits>::BitsetFromList(list); 722*16467b97STreehugger Robot this->getTokensSet(start, stop, bitSet, newlist); 723*16467b97STreehugger Robot delete bitSet; 724*16467b97STreehugger Robot} 725*16467b97STreehugger Robot 726*16467b97STreehugger Robottemplate<class ImplTraits> 727*16467b97STreehugger Robotvoid 728*16467b97STreehugger RobotCommonTokenStream<ImplTraits>::getTokensType(ANTLR_UINT32 start, ANTLR_UINT32 stop, ANTLR_UINT32 type, 729*16467b97STreehugger Robot TokensListType& newlist ) 730*16467b97STreehugger Robot{ 731*16467b97STreehugger Robot BitsetType* bitSet; 732*16467b97STreehugger Robot 733*16467b97STreehugger Robot bitSet = BitsetType::BitsetOf(type, -1); 734*16467b97STreehugger Robot this->getTokensSet(start, stop, bitSet, newlist); 735*16467b97STreehugger Robot 736*16467b97STreehugger Robot delete bitSet; 737*16467b97STreehugger Robot} 738*16467b97STreehugger Robot 739*16467b97STreehugger Robottemplate<class ImplTraits> 740*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::fillBufferExt() 741*16467b97STreehugger Robot{ 742*16467b97STreehugger Robot this->fillBuffer(); 743*16467b97STreehugger Robot} 744*16467b97STreehugger Robot 745*16467b97STreehugger Robottemplate<class ImplTraits> 746*16467b97STreehugger Robotbool CommonTokenStream<ImplTraits>::hasReachedFillbufferTarget( ANTLR_UINT32 cnt, 747*16467b97STreehugger Robot BoolForwarder<true> ) 748*16467b97STreehugger Robot{ 749*16467b97STreehugger Robot return ( cnt >= ImplTraits::TOKEN_FILL_BUFFER_INCREMENT ); 750*16467b97STreehugger Robot} 751*16467b97STreehugger Robot 752*16467b97STreehugger Robottemplate<class ImplTraits> 753*16467b97STreehugger Robotbool CommonTokenStream<ImplTraits>::hasReachedFillbufferTarget( ANTLR_UINT32, 754*16467b97STreehugger Robot BoolForwarder<false> ) 755*16467b97STreehugger Robot{ 756*16467b97STreehugger Robot return false; 757*16467b97STreehugger Robot} 758*16467b97STreehugger Robot 759*16467b97STreehugger Robot 760*16467b97STreehugger Robottemplate<class ImplTraits> 761*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::fillBuffer() 762*16467b97STreehugger Robot{ 763*16467b97STreehugger Robot ANTLR_UINT32 index; 764*16467b97STreehugger Robot TokenType* tok; 765*16467b97STreehugger Robot bool discard; 766*16467b97STreehugger Robot 767*16467b97STreehugger Robot /* Start at index 0 of course 768*16467b97STreehugger Robot */ 769*16467b97STreehugger Robot ANTLR_UINT32 cached_p = (m_p < 0) ? 0 : m_p; 770*16467b97STreehugger Robot index = m_nissued; 771*16467b97STreehugger Robot ANTLR_UINT32 cnt = 0; 772*16467b97STreehugger Robot 773*16467b97STreehugger Robot /* Pick out the next token from the token source 774*16467b97STreehugger Robot * Remember we just get a pointer (reference if you like) here 775*16467b97STreehugger Robot * and so if we store it anywhere, we don't set any pointers to auto free it. 776*16467b97STreehugger Robot */ 777*16467b97STreehugger Robot tok = this->get_tokenSource()->nextToken(); 778*16467b97STreehugger Robot 779*16467b97STreehugger Robot while ( tok->get_type() != TokenType::TOKEN_EOF ) 780*16467b97STreehugger Robot { 781*16467b97STreehugger Robot discard = false; /* Assume we are not discarding */ 782*16467b97STreehugger Robot 783*16467b97STreehugger Robot /* I employ a bit of a trick, or perhaps hack here. Rather than 784*16467b97STreehugger Robot * store a pointer to a structure in the override map and discard set 785*16467b97STreehugger Robot * we store the value + 1 cast to a void *. Hence on systems where NULL = (void *)0 786*16467b97STreehugger Robot * we can distinguish "not being there" from "being channel or type 0" 787*16467b97STreehugger Robot */ 788*16467b97STreehugger Robot 789*16467b97STreehugger Robot if ( m_discardSet.find(tok->get_type()) != m_discardSet.end() ) 790*16467b97STreehugger Robot { 791*16467b97STreehugger Robot discard = true; 792*16467b97STreehugger Robot } 793*16467b97STreehugger Robot else if ( m_discardOffChannel == true 794*16467b97STreehugger Robot && tok->get_channel() != m_channel 795*16467b97STreehugger Robot ) 796*16467b97STreehugger Robot { 797*16467b97STreehugger Robot discard = true; 798*16467b97STreehugger Robot } 799*16467b97STreehugger Robot else if (!m_channelOverrides.empty()) 800*16467b97STreehugger Robot { 801*16467b97STreehugger Robot /* See if this type is in the override map 802*16467b97STreehugger Robot */ 803*16467b97STreehugger Robot typename ChannelOverridesType::iterator iter = m_channelOverrides.find( tok->get_type() + 1 ); 804*16467b97STreehugger Robot 805*16467b97STreehugger Robot if (iter != m_channelOverrides.end()) 806*16467b97STreehugger Robot { 807*16467b97STreehugger Robot /* Override found 808*16467b97STreehugger Robot */ 809*16467b97STreehugger Robot tok->set_channel( ANTLR_UINT32_CAST(iter->second) - 1); 810*16467b97STreehugger Robot } 811*16467b97STreehugger Robot } 812*16467b97STreehugger Robot 813*16467b97STreehugger Robot /* If not discarding it, add it to the list at the current index 814*16467b97STreehugger Robot */ 815*16467b97STreehugger Robot if (discard == false) 816*16467b97STreehugger Robot { 817*16467b97STreehugger Robot /* Add it, indicating that we will delete it and the table should not 818*16467b97STreehugger Robot */ 819*16467b97STreehugger Robot tok->set_tokenIndex(index); 820*16467b97STreehugger Robot ++m_p; 821*16467b97STreehugger Robot this->insertToken(*tok); 822*16467b97STreehugger Robot index++; 823*16467b97STreehugger Robot m_nissued++; 824*16467b97STreehugger Robot cnt++; 825*16467b97STreehugger Robot } 826*16467b97STreehugger Robot 827*16467b97STreehugger Robot if( !this->hasReachedFillbufferTarget( cnt, 828*16467b97STreehugger Robot BoolForwarder<ImplTraits::TOKENS_ACCESSED_FROM_OWNING_RULE>() ) ) 829*16467b97STreehugger Robot tok = this->get_tokenSource()->nextToken(); 830*16467b97STreehugger Robot else 831*16467b97STreehugger Robot break; 832*16467b97STreehugger Robot } 833*16467b97STreehugger Robot 834*16467b97STreehugger Robot /* Cache the size so we don't keep doing indirect method calls. We do this as 835*16467b97STreehugger Robot * early as possible so that anything after this may utilize the cached value. 836*16467b97STreehugger Robot */ 837*16467b97STreehugger Robot this->get_istream()->set_cachedSize( m_nissued ); 838*16467b97STreehugger Robot 839*16467b97STreehugger Robot /* Set the consume pointer to the first token that is on our channel, we just read 840*16467b97STreehugger Robot */ 841*16467b97STreehugger Robot m_p = cached_p; 842*16467b97STreehugger Robot m_p = this->skipOffTokenChannels( m_p ); 843*16467b97STreehugger Robot 844*16467b97STreehugger Robot} 845*16467b97STreehugger Robot/// Given a starting index, return the index of the first on-channel 846*16467b97STreehugger Robot/// token. 847*16467b97STreehugger Robot/// 848*16467b97STreehugger Robottemplate<class ImplTraits> 849*16467b97STreehugger RobotANTLR_UINT32 CommonTokenStream<ImplTraits>::skipOffTokenChannels(ANTLR_INT32 i) 850*16467b97STreehugger Robot{ 851*16467b97STreehugger Robot ANTLR_INT32 n; 852*16467b97STreehugger Robot n = this->get_istream()->get_cachedSize(); 853*16467b97STreehugger Robot 854*16467b97STreehugger Robot while (i < n) 855*16467b97STreehugger Robot { 856*16467b97STreehugger Robot const TokenType* tok = this->getToken(i); 857*16467b97STreehugger Robot 858*16467b97STreehugger Robot if (tok->get_channel() != m_channel ) 859*16467b97STreehugger Robot { 860*16467b97STreehugger Robot i++; 861*16467b97STreehugger Robot } 862*16467b97STreehugger Robot else 863*16467b97STreehugger Robot { 864*16467b97STreehugger Robot return i; 865*16467b97STreehugger Robot } 866*16467b97STreehugger Robot } 867*16467b97STreehugger Robot return i; 868*16467b97STreehugger Robot} 869*16467b97STreehugger Robot 870*16467b97STreehugger Robottemplate<class ImplTraits> 871*16467b97STreehugger RobotANTLR_UINT32 CommonTokenStream<ImplTraits>::skipOffTokenChannelsReverse(ANTLR_INT32 x) 872*16467b97STreehugger Robot{ 873*16467b97STreehugger Robot while (x >= 0) 874*16467b97STreehugger Robot { 875*16467b97STreehugger Robot const TokenType* tok = this->getToken(x); 876*16467b97STreehugger Robot 877*16467b97STreehugger Robot if( tok->get_channel() != m_channel ) 878*16467b97STreehugger Robot { 879*16467b97STreehugger Robot x--; 880*16467b97STreehugger Robot } 881*16467b97STreehugger Robot else 882*16467b97STreehugger Robot { 883*16467b97STreehugger Robot return x; 884*16467b97STreehugger Robot } 885*16467b97STreehugger Robot } 886*16467b97STreehugger Robot return x; 887*16467b97STreehugger Robot} 888*16467b97STreehugger Robot 889*16467b97STreehugger Robottemplate<class ImplTraits> 890*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::discardTokens( ANTLR_MARKER start, ANTLR_MARKER stop ) 891*16467b97STreehugger Robot{ 892*16467b97STreehugger Robot this->discardTokens( start, stop, BoolForwarder< ImplTraits::TOKENS_ACCESSED_FROM_OWNING_RULE >() ); 893*16467b97STreehugger Robot} 894*16467b97STreehugger Robot 895*16467b97STreehugger Robottemplate<class ImplTraits> 896*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::discardTokens( ANTLR_MARKER start, ANTLR_MARKER stop, 897*16467b97STreehugger Robot BoolForwarder<true> /*tokens_accessed_from_owning_rule */ ) 898*16467b97STreehugger Robot{ 899*16467b97STreehugger Robot typename TokensType::iterator iter1 = m_tokens.lower_bound(start); 900*16467b97STreehugger Robot typename TokensType::iterator iter2 = m_tokens.upper_bound(stop); 901*16467b97STreehugger Robot m_tokens.erase( iter1, iter2 ); 902*16467b97STreehugger Robot} 903*16467b97STreehugger Robot 904*16467b97STreehugger Robottemplate<class ImplTraits> 905*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::discardTokens( ANTLR_MARKER start, ANTLR_MARKER stop, 906*16467b97STreehugger Robot BoolForwarder<false> /*tokens_accessed_from_owning_rule*/ ) 907*16467b97STreehugger Robot{ 908*16467b97STreehugger Robot m_tokens.erase( m_tokens.begin() + start, m_tokens.begin() + stop ); 909*16467b97STreehugger Robot} 910*16467b97STreehugger Robot 911*16467b97STreehugger Robottemplate<class ImplTraits> 912*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::insertToken( const TokenType& tok ) 913*16467b97STreehugger Robot{ 914*16467b97STreehugger Robot this->insertToken( tok, BoolForwarder< ImplTraits::TOKENS_ACCESSED_FROM_OWNING_RULE >() ); 915*16467b97STreehugger Robot} 916*16467b97STreehugger Robot 917*16467b97STreehugger Robottemplate<class ImplTraits> 918*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::insertToken( const TokenType& tok, BoolForwarder<true> /*tokens_accessed_from_owning_rule*/ ) 919*16467b97STreehugger Robot{ 920*16467b97STreehugger Robot assert( m_tokens.find( tok.get_index() ) == m_tokens.end() ); 921*16467b97STreehugger Robot assert( tok.get_index() == m_nissued ); 922*16467b97STreehugger Robot m_tokens[ tok.get_index() ] = tok; 923*16467b97STreehugger Robot} 924*16467b97STreehugger Robot 925*16467b97STreehugger Robottemplate<class ImplTraits> 926*16467b97STreehugger Robotvoid CommonTokenStream<ImplTraits>::insertToken( const TokenType& tok, BoolForwarder<false> /*tokens_accessed_from_owning_rule*/ ) 927*16467b97STreehugger Robot{ 928*16467b97STreehugger Robot m_tokens.push_back( tok ); 929*16467b97STreehugger Robot} 930*16467b97STreehugger Robot 931*16467b97STreehugger Robottemplate<class ImplTraits> 932*16467b97STreehugger RobotCommonTokenStream<ImplTraits>::~CommonTokenStream() 933*16467b97STreehugger Robot{ 934*16467b97STreehugger Robot m_tokens.clear(); 935*16467b97STreehugger Robot} 936*16467b97STreehugger Robot 937*16467b97STreehugger RobotANTLR_END_NAMESPACE() 938