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