ANTLR_BEGIN_NAMESPACE()

template<class ImplTraits, class CtxType>
CyclicDFA<ImplTraits, CtxType>::CyclicDFA( ANTLR_INT32	decisionNumber
				, const ANTLR_UCHAR*	description
				, const ANTLR_INT32* const	eot
				, const ANTLR_INT32* const	eof
				, const ANTLR_INT32* const	min
				, const ANTLR_INT32* const	max
				, const ANTLR_INT32* const	accept
				, const ANTLR_INT32* const	special
				, const ANTLR_INT32* const *const	transition )
				:m_decisionNumber(decisionNumber)
				, m_eot(eot)
				, m_eof(eof)
				, m_min(min)
				, m_max(max)
				, m_accept(accept)
				, m_special(special)
				, m_transition(transition)
{
	m_description = description;
}

template<class ImplTraits, class CtxType>
CyclicDFA<ImplTraits, CtxType>::CyclicDFA( const CyclicDFA& dfa )
{
	m_decisionNumber = dfa.m_decisionNumber;
	m_description = dfa.m_description;
	m_eot = dfa.m_eot;
	m_eof = dfa.m_eof;
	m_min = dfa.m_min;
	m_max = dfa.m_max;
	m_accept = dfa.m_accept;
	m_special = dfa.m_special;
	m_transition = dfa.m_transition;
}

template<class ImplTraits, class CtxType>
CyclicDFA<ImplTraits, CtxType>& CyclicDFA<ImplTraits, CtxType>::operator=( const CyclicDFA& dfa)
{
	m_decisionNumber = dfa.m_decisionNumber;
	m_description = dfa.m_description;
	m_eot = dfa.m_eot;
	m_eof = dfa.m_eof;
	m_min = dfa.m_min;
	m_max = dfa.m_max;
	m_accept = dfa.m_accept;
	m_special = dfa.m_special;
	m_transition = dfa.m_transition;
	return *this;
}

template<class ImplTraits, class CtxType>
ANTLR_INT32	CyclicDFA<ImplTraits, CtxType>::specialStateTransition(CtxType * ,
																	RecognizerType* ,
																	IntStreamType* , ANTLR_INT32 )
{
	return -1;
}

template<class ImplTraits, class CtxType>
ANTLR_INT32	CyclicDFA<ImplTraits, CtxType>::specialTransition(CtxType * ctx,
																	RecognizerType* recognizer,
																	IntStreamType* is, ANTLR_INT32 s)
{
	return 0;
}

template<class ImplTraits, class CtxType>
  template<typename SuperType>
ANTLR_INT32	CyclicDFA<ImplTraits, CtxType>::predict(CtxType * ctx,
															RecognizerType* recognizer,
															IntStreamType* is, SuperType& super)
{
	ANTLR_MARKER	mark;
    ANTLR_INT32	s;
    ANTLR_INT32	specialState;
    ANTLR_INT32	c;

    mark	= is->mark();	    /* Store where we are right now	*/
    s		= 0;		    /* Always start with state 0	*/

	for (;;)
	{
		/* Pick out any special state entry for this state
		 */
		specialState	= m_special[s];

		/* Transition the special state and consume an input token
		 */
		if  (specialState >= 0)
		{
			s = super.specialStateTransition(ctx, recognizer, is, specialState);

			// Error?
			//
			if	(s<0)
			{
				// If the predicate/rule raised an exception then we leave it
				// in tact, else we have an NVA.
				//
				if	(recognizer->get_state()->get_error() != true)
				{
					this->noViableAlt(recognizer, s);
				}
				is->rewind(mark);
				return	0;
			}
			is->consume();
			continue;
		}

		/* Accept state?
		 */
		if  (m_accept[s] >= 1)
		{
			is->rewind(mark);
			return  m_accept[s];
		}

		/* Look for a normal transition state based upon the input token element
		 */
		c = is->_LA(1);

		/* Check against min and max for this state
		 */
		if  (c>= m_min[s] && c <= m_max[s])
		{
			ANTLR_INT32   snext;

			/* What is the next state?
			 */
			snext = m_transition[s][c - m_min[s]];

			if	(snext < 0)
			{
				/* Was in range but not a normal transition
				 * must check EOT, which is like the else clause.
				 * eot[s]>=0 indicates that an EOT edge goes to another
				 * state.
				 */
				if  ( m_eot[s] >= 0)
				{
					s = m_eot[s];
					is->consume();
					continue;
				}
				this->noViableAlt(recognizer, s);
				is->rewind(mark);
				return	0;
			}

			/* New current state - move to it
			 */
			s	= snext;
			is->consume();
			continue;
		}
		/* EOT Transition?
		 */
		if  ( m_eot[s] >= 0)
		{
			s	= m_eot[s];
			is->consume();
			continue;
		}
		/* EOF transition to accept state?
		 */
		if  ( c == ImplTraits::CommonTokenType::TOKEN_EOF && m_eof[s] >= 0)
		{
			is->rewind(mark);
			return  m_accept[m_eof[s]];
		}

		/* No alt, so bomb
		 */
		this->noViableAlt(recognizer, s);
		is->rewind(mark);
		return 0;
	}
}

template<class ImplTraits, class CtxType>
void CyclicDFA<ImplTraits, CtxType>::noViableAlt(RecognizerType* rec, ANTLR_UINT32 s)
{
	// In backtracking mode, we just set the failed flag so that the
	// alt can just exit right now. If we are parsing though, then
	// we want the exception to be raised.
	//
    if	(rec->get_state()->get_backtracking() > 0)
    {
		rec->get_state()->set_failed(true);
    }
	else
	{
		ANTLR_Exception<ImplTraits, NO_VIABLE_ALT_EXCEPTION, StreamType>* ex 
			= new ANTLR_Exception<ImplTraits, NO_VIABLE_ALT_EXCEPTION, StreamType>( rec, (const char*)m_description );
		ex->set_decisionNum( m_decisionNumber );
		ex->set_state(s);
	}
}

ANTLR_END_NAMESPACE()
