xref: /aosp_15_r20/external/antlr/runtime/Cpp/include/antlr3tokenstream.inl (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
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