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