1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** \file
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Contains the base functions that all recognizers require.
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Any function can be overridden by a lexer/parser/tree parser or by the
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ANTLR3 programmer.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \addtogroup pANTLR3_BASE_RECOGNIZER
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * @{
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include    <antlr3baserecognizer.h>
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// [The "BSD licence"]
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// http://www.temporal-wave.com
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// http://www.linkedin.com/in/jimidle
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// All rights reserved.
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Redistribution and use in source and binary forms, with or without
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// modification, are permitted provided that the following conditions
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// are met:
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 1. Redistributions of source code must retain the above copyright
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//    notice, this list of conditions and the following disclaimer.
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 2. Redistributions in binary form must reproduce the above copyright
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//    notice, this list of conditions and the following disclaimer in the
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//    documentation and/or other materials provided with the distribution.
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 3. The name of the author may not be used to endorse or promote products
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//    derived from this software without specific prior written permission.
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifdef	ANTLR3_WINDOWS
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#pragma warning( disable : 4100 )
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* Interface functions -standard implementations cover parser and treeparser
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * almost completely but are overridden by the parser or tree parser as needed. Lexer overrides
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * most of these functions.
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					beginResync					(pANTLR3_BASE_RECOGNIZER recognizer);
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET		computeErrorRecoverySet	    (pANTLR3_BASE_RECOGNIZER recognizer);
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					endResync					(pANTLR3_BASE_RECOGNIZER recognizer);
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					beginBacktrack				(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level);
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					endBacktrack				(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level, ANTLR3_BOOLEAN successful);
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *				match						(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					matchAny					(pANTLR3_BASE_RECOGNIZER recognizer);
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					mismatch					(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN		mismatchIsUnwantedToken		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, ANTLR3_UINT32 ttype);
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN		mismatchIsMissingToken		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_BITSET_LIST follow);
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					reportError					(pANTLR3_BASE_RECOGNIZER recognizer);
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET		computeCSRuleFollow			(pANTLR3_BASE_RECOGNIZER recognizer);
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET		combineFollows				(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_BOOLEAN exact);
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					displayRecognitionError	    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames);
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					recover						(pANTLR3_BASE_RECOGNIZER recognizer);
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void	*				recoverFromMismatchedToken  (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void	*				recoverFromMismatchedSet    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow);
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN		recoverFromMismatchedElement(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow);
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					consumeUntil				(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 tokenType);
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					consumeUntilSet				(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET set);
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_STACK		getRuleInvocationStack	    (pANTLR3_BASE_RECOGNIZER recognizer);
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_STACK		getRuleInvocationStackNamed (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 name);
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_TABLE	toStrings					(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_HASH_TABLE);
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_MARKER		getRuleMemoization			(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_INTKEY ruleIndex, ANTLR3_MARKER ruleParseStart);
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN		alreadyParsedRule			(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex);
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					memoize						(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex, ANTLR3_MARKER ruleParseStart);
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN		synpred						(pANTLR3_BASE_RECOGNIZER recognizer, void * ctx, void (*predicate)(void * ctx));
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					reset						(pANTLR3_BASE_RECOGNIZER recognizer);
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void					freeBR						(pANTLR3_BASE_RECOGNIZER recognizer);
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *				getCurrentInputSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream);
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *				getMissingSymbol			(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver															ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow);
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32		getNumberOfSyntaxErrors		(pANTLR3_BASE_RECOGNIZER recognizer);
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
83324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_BASE_RECOGNIZER
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3BaseRecognizerNew(ANTLR3_UINT32 type, ANTLR3_UINT32 sizeHint, pANTLR3_RECOGNIZER_SHARED_STATE state)
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BASE_RECOGNIZER recognizer;
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Allocate memory for the structure
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer	    = (pANTLR3_BASE_RECOGNIZER) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_BASE_RECOGNIZER));
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer == NULL)
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Allocation failed
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	NULL;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// If we have been supplied with a pre-existing recognizer state
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// then we just install it, otherwise we must create one from scratch
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(state == NULL)
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state = (pANTLR3_RECOGNIZER_SHARED_STATE) ANTLR3_CALLOC(1, (size_t)sizeof(ANTLR3_RECOGNIZER_SHARED_STATE));
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state == NULL)
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FREE(recognizer);
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return	NULL;
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Initialize any new recognizer state
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->errorRecovery	= ANTLR3_FALSE;
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->lastErrorIndex	= -1;
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed		= ANTLR3_FALSE;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->errorCount		= 0;
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->backtracking		= 0;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->following		= NULL;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->ruleMemo		= NULL;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->tokenNames		= NULL;
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->sizeHint             = sizeHint;
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->tokSource		= NULL;
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                recognizer->state->tokFactory           = NULL;
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Rather than check to see if we must initialize
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// the stack every time we are asked for an new rewrite stream
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// we just always create an empty stack and then just
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// free it when the base recognizer is freed.
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->rStreams		= antlr3VectorNew(0);  // We don't know the size.
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->rStreams == NULL)
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// Out of memory
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FREE(recognizer->state);
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FREE(recognizer);
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return	NULL;
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	else
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Install the one we were given, and do not reset it here
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// as it will either already have been initialized or will
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// be in a state that needs to be preserved.
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state = state;
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Install the BR API
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->alreadyParsedRule           = alreadyParsedRule;
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->beginResync                 = beginResync;
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->combineFollows              = combineFollows;
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->beginBacktrack              = beginBacktrack;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->endBacktrack                = endBacktrack;
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->computeCSRuleFollow         = computeCSRuleFollow;
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->computeErrorRecoverySet     = computeErrorRecoverySet;
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->consumeUntil                = consumeUntil;
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->consumeUntilSet             = consumeUntilSet;
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->displayRecognitionError     = displayRecognitionError;
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->endResync                   = endResync;
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->exConstruct                 = antlr3MTExceptionNew;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getRuleInvocationStack      = getRuleInvocationStack;
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getRuleInvocationStackNamed = getRuleInvocationStackNamed;
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getRuleMemoization          = getRuleMemoization;
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->match                       = match;
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->matchAny                    = matchAny;
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->memoize                     = memoize;
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->mismatch                    = mismatch;
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->mismatchIsUnwantedToken     = mismatchIsUnwantedToken;
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->mismatchIsMissingToken      = mismatchIsMissingToken;
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->recover                     = recover;
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->recoverFromMismatchedElement= recoverFromMismatchedElement;
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->recoverFromMismatchedSet    = recoverFromMismatchedSet;
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->recoverFromMismatchedToken  = recoverFromMismatchedToken;
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getNumberOfSyntaxErrors     = getNumberOfSyntaxErrors;
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->reportError                 = reportError;
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->reset                       = reset;
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->synpred                     = synpred;
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->toStrings                   = toStrings;
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getCurrentInputSymbol       = getCurrentInputSymbol;
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->getMissingSymbol            = getMissingSymbol;
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->debugger                    = NULL;
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->free = freeBR;
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Initialize variables
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->type			= type;
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return  recognizer;
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
198324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverfreeBR	    (pANTLR3_BASE_RECOGNIZER recognizer)
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_EXCEPTION thisE;
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Did we have a state allocated?
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->state != NULL)
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Free any rule memoization we set up
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->ruleMemo != NULL)
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->ruleMemo->free(recognizer->state->ruleMemo);
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->ruleMemo = NULL;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Free any exception space we have left around
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		thisE = recognizer->state->exception;
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(thisE != NULL)
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			thisE->freeEx(thisE);
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Free any rewrite streams we have allocated
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->rStreams != NULL)
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->rStreams->free(recognizer->state->rStreams);
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Free up any token factory we created (error recovery for instance)
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->tokFactory != NULL)
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->tokFactory->close(recognizer->state->tokFactory);
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Free the shared state memory
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FREE(recognizer->state);
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Free the actual recognizer space
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_FREE(recognizer);
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/**
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Creates a new Mismatched Token Exception and inserts in the recognizer
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * exception stack.
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param recognizer
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Context pointer for this recognizer
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
253324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API	void
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3MTExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Create a basic recognition exception structure
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    antlr3RecognitionExceptionNew(recognizer);
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Now update it to indicate this is a Mismatched token exception
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->exception->name		= ANTLR3_MISMATCHED_EX_NAME;
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->exception->type		= ANTLR3_MISMATCHED_TOKEN_EXCEPTION;
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return;
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
268324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API	void
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3RecognitionExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_EXCEPTION				ex;
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_LEXER					lexer;
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_PARSER					parser;
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_TREE_PARSER				tparser;
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_INPUT_STREAM			ins;
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_INT_STREAM				is;
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN_STREAM	    cts;
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_TREE_NODE_STREAM	    tns;
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ins	    = NULL;
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	cts	    = NULL;
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	tns	    = NULL;
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	is	    = NULL;
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	lexer   = NULL;
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	parser  = NULL;
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	tparser = NULL;
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	switch	(recognizer->type)
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_LEXER:
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lexer	= (pANTLR3_LEXER) (recognizer->super);
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ins	= lexer->input;
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= ins->istream;
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_PARSER:
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser  = (pANTLR3_PARSER) (recognizer->super);
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		cts	= (pANTLR3_COMMON_TOKEN_STREAM)(parser->tstream->super);
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= parser->tstream->istream;
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_TREE_PARSER:
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tns	= tparser->ctnstream->tnstream;
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= tns->istream;
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	default:
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function antlr3RecognitionExceptionNew called by unknown parser type - provide override for this function\n");
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/* Create a basic exception structure
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ex = antlr3ExceptionNew(ANTLR3_RECOGNITION_EXCEPTION,
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		(void *)ANTLR3_RECOGNITION_EX_NAME,
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NULL,
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FALSE);
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/* Rest of information depends on the base type of the
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 * input stream.
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	switch  (is->type & ANTLR3_INPUT_MASK)
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case    ANTLR3_CHARSTREAM:
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->c			= is->_LA		    	(is, 1);					/* Current input character			*/
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->line		= ins->getLine			(ins);						/* Line number comes from stream		*/
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->charPositionInLine	= ins->getCharPositionInLine	(ins);	    /* Line offset also comes from the stream   */
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->index		= is->index			(is);
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->streamName		= ins->fileName;
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->message		= "Unexpected character";
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case    ANTLR3_TOKENSTREAM:
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->token		= cts->tstream->_LT						(cts->tstream, 1);	    /* Current input token			    */
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->line		= ((pANTLR3_COMMON_TOKEN)(ex->token))->getLine			(ex->token);
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->charPositionInLine	= ((pANTLR3_COMMON_TOKEN)(ex->token))->getCharPositionInLine	(ex->token);
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->index		= cts->tstream->istream->index					(cts->tstream->istream);
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ex->streamName		= NULL;
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ex->streamName		= ((pANTLR3_COMMON_TOKEN)(ex->token))->input->fileName;
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->message		= "Unexpected token";
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case    ANTLR3_COMMONTREENODE:
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->token		= tns->_LT						    (tns, 1);	    /* Current input tree node			    */
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->line		= ((pANTLR3_BASE_TREE)(ex->token))->getLine		    (ex->token);
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->charPositionInLine	= ((pANTLR3_BASE_TREE)(ex->token))->getCharPositionInLine   (ex->token);
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ex->index		= tns->istream->index					    (tns->istream);
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Are you ready for this? Deep breath now...
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			pANTLR3_COMMON_TREE tnode;
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tnode		= ((pANTLR3_COMMON_TREE)(((pANTLR3_BASE_TREE)(ex->token))->super));
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(tnode->token    == NULL)
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ex->streamName = ((pANTLR3_BASE_TREE)(ex->token))->strFactory->newStr(((pANTLR3_BASE_TREE)(ex->token))->strFactory, (pANTLR3_UINT8)"-unknown source-");
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if	(tnode->token->input == NULL)
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ex->streamName		= NULL;
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ex->streamName		= tnode->token->input->fileName;
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ex->message		= "Unexpected node";
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ex->input						= is;
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ex->nextException				= recognizer->state->exception;	/* So we don't leak the memory */
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->exception	= ex;
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->error	    = ANTLR3_TRUE;	    /* Exception is outstanding	*/
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return;
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Match current input symbol against ttype.  Upon error, do one token
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// insertion or deletion if possible.
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// To turn off single token insertion or deletion error
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// recovery, override mismatchRecover() and have it call
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// plain mismatch(), which does not recover.  Then any error
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// in a rule will cause an exception and immediate exit from
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// rule.  Rule would recover by resynchronizing to the set of
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// symbols that can follow rule ref.
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermatch(	pANTLR3_BASE_RECOGNIZER recognizer,
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER			parser;
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	void					* matchedSymbol;
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'match' called by unknown parser type - provide override for this function\n");
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return ANTLR3_FALSE;
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Pick up the current input token/node for assignment to labels
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	matchedSymbol = recognizer->getCurrentInputSymbol(recognizer, is);
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(is->_LA(is, 1) == ttype)
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// The token was the one we were told to expect
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);									// Consume that token from the stream
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->errorRecovery	= ANTLR3_FALSE;	// Not in error recovery now (if we were)
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed			= ANTLR3_FALSE;	// The match was a success
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return matchedSymbol;								// We are done
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // We did not find the expected token type, if we are backtracking then
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // we just set the failed flag and return.
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer->state->backtracking > 0)
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Backtracking is going on
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed  = ANTLR3_TRUE;
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return matchedSymbol;
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // We did not find the expected token and there is no backtracking
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // going on, so we mismatch, which creates an exception in the recognizer exception
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // stack.
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	matchedSymbol = recognizer->recoverFromMismatchedToken(recognizer, ttype, follow);
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return matchedSymbol;
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Consumes the next token, whatever it is, and resets the recognizer state
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// so that it is not in error.
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// \param recognizer
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Recognizer context pointer
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
489324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvermatchAny(pANTLR3_BASE_RECOGNIZER recognizer)
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'matchAny' called by unknown parser type - provide override for this function\n");
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->errorRecovery	= ANTLR3_FALSE;
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->failed		    = ANTLR3_FALSE;
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    is->consume(is);
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return;
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN
529324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvermismatchIsUnwantedToken(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, ANTLR3_UINT32 ttype)
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ANTLR3_UINT32 nextt;
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	nextt = is->_LA(is, 2);
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(nextt == ttype)
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->exception != NULL)
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->exception->expecting = nextt;
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_TRUE;		// This token is unknown, but the next one is the one we wanted
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	else
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_FALSE;	// Neither this token, nor the one following is the one we wanted
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN
552324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvermismatchIsMissingToken(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_BITSET_LIST follow)
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ANTLR3_BOOLEAN	retcode;
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_BITSET	followClone;
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_BITSET	viableTokensFollowingThisRule;
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(follow == NULL)
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// There is no information about the tokens that can follow the last one
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// hence we must say that the current one we found is not a member of the
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// follow set and does not indicate a missing token. We will just consume this
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// single token and see if the parser works it out from there.
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	ANTLR3_FALSE;
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	followClone						= NULL;
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	viableTokensFollowingThisRule	= NULL;
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// The C bitset maps are laid down at compile time by the
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// C code generation. Hence we cannot remove things from them
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// and so on. So, in order to remove EOR (if we need to) then
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// we clone the static bitset.
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	followClone = antlr3BitsetLoad(follow);
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(followClone == NULL)
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_FALSE;
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Compute what can follow this grammar reference
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(followClone->isMember(followClone, ANTLR3_EOR_TOKEN_TYPE))
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// EOR can follow, but if we are not the start symbol, we
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// need to remove it.
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->following->vector->count >= 0)
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			followClone->remove(followClone, ANTLR3_EOR_TOKEN_TYPE);
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Now compute the visiable tokens that can follow this rule, according to context
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// and make them part of the follow set.
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		viableTokensFollowingThisRule = recognizer->computeCSRuleFollow(recognizer);
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		followClone->borInPlace(followClone, viableTokensFollowingThisRule);
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// if current token is consistent with what could come after set
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// then we know we're missing a token; error recovery is free to
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// "insert" the missing token
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	///
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// in follow set to indicate that the fall of the start symbol is
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/// in the set (EOF can follow).
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	///
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(		followClone->isMember(followClone, is->_LA(is, 1))
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			||	followClone->isMember(followClone, ANTLR3_EOR_TOKEN_TYPE)
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		)
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		retcode = ANTLR3_TRUE;
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	else
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		retcode	= ANTLR3_FALSE;
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(viableTokensFollowingThisRule != NULL)
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		viableTokensFollowingThisRule->free(viableTokensFollowingThisRule);
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(followClone != NULL)
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		followClone->free(followClone);
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return retcode;
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Factor out what to do upon token mismatch so tree parsers can behave
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// differently.  Override and call mismatchRecover(input, ttype, follow)
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// to get single token insertion and deletion.  Use this to turn off
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// single token insertion and deletion. Override mismatchRecover
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// to call this instead.
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// \remark mismatch only works for parsers and must be overridden for anything else.
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic	void
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermismatch(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Install a mismatched token exception in the exception stack
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    antlr3MTExceptionNew(recognizer);
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->exception->expecting    = ttype;
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'mismatch' called by unknown parser type - provide override for this function\n");
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(mismatchIsUnwantedToken(recognizer, is, ttype))
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Create a basic recognition exception structure
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    antlr3RecognitionExceptionNew(recognizer);
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Now update it to indicate this is an unwanted token exception
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->name		= ANTLR3_UNWANTED_TOKEN_EXCEPTION_NAME;
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->type		= ANTLR3_UNWANTED_TOKEN_EXCEPTION;
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(mismatchIsMissingToken(recognizer, is, follow))
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Create a basic recognition exception structure
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    antlr3RecognitionExceptionNew(recognizer);
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Now update it to indicate this is an unwanted token exception
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->name		= ANTLR3_MISSING_TOKEN_EXCEPTION_NAME;
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->type		= ANTLR3_MISSING_TOKEN_EXCEPTION;
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Just a mismatched token is all we can dtermine
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	antlr3MTExceptionNew(recognizer);
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return;
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Report a recognition problem.
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// This method sets errorRecovery to indicate the parser is recovering
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// not parsing.  Once in recovery mode, no errors are generated.
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// To get out of recovery mode, the parser must successfully match
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// a token (after a resync).  So it will go:
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///		1. error occurs
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///		2. enter recovery mode, report error
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///		3. consume until token found in resynch set
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///		4. try to resume parsing
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///		5. next match() will reset errorRecovery mode
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// If you override, make sure to update errorCount if you care about that.
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
721324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverreportError		    (pANTLR3_BASE_RECOGNIZER recognizer)
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    	// Invoke the debugger event if there is a debugger listening to us
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->debugger != NULL)
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->debugger->recognitionException(recognizer->debugger, recognizer->state->exception);
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer->state->errorRecovery == ANTLR3_TRUE)
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Already in error recovery so don't display another error while doing so
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Signal we are in error recovery now
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->errorRecovery = ANTLR3_TRUE;
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Indicate this recognizer had an error while processing.
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->errorCount++;
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Call the error display routine
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->displayRecognitionError(recognizer, recognizer->state->tokenNames);
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
751324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverbeginBacktrack		(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level)
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->debugger != NULL)
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->debugger->beginBacktrack(recognizer->debugger, level);
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
760324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverendBacktrack		(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level, ANTLR3_BOOLEAN successful)
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->debugger != NULL)
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->debugger->endBacktrack(recognizer->debugger, level, successful);
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
768324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverbeginResync		    (pANTLR3_BASE_RECOGNIZER recognizer)
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->debugger != NULL)
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->debugger->beginResync(recognizer->debugger);
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
777324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverendResync		    (pANTLR3_BASE_RECOGNIZER recognizer)
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->debugger != NULL)
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->debugger->endResync(recognizer->debugger);
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Compute the error recovery set for the current rule.
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Documentation below is from the Java implementation.
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// During rule invocation, the parser pushes the set of tokens that can
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// follow that rule reference on the stack; this amounts to
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// computing FIRST of what follows the rule reference in the
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// enclosing rule. This local follow set only includes tokens
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// from within the rule; i.e., the FIRST computation done by
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// ANTLR stops at the end of a rule.
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// EXAMPLE
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// When you find a "no viable alt exception", the input is not
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// consistent with any of the alternatives for rule r.  The best
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// thing to do is to consume tokens until you see something that
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// can legally follow a call to r *or* any rule that called r.
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// You don't want the exact set of viable next tokens because the
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// input might just be missing a token--you might consume the
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// rest of the input looking for one of the missing tokens.
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Consider grammar:
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// a : '[' b ']'
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   | '(' b ')'
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   ;
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// b : c '^' INT ;
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// c : ID
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   | INT
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   ;
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// At each rule invocation, the set of tokens that could follow
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// that rule is pushed on a stack.  Here are the various "local"
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// follow sets:
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// FOLLOW(b1_in_a) = FIRST(']') = ']'
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// FOLLOW(b2_in_a) = FIRST(')') = ')'
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// FOLLOW(c_in_b) = FIRST('^') = '^'
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Upon erroneous input "[]", the call chain is
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// a -> b -> c
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// and, hence, the follow context stack is:
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// depth  local follow set     after call to rule
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   0         <EOF>                    a (from main())
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   1          ']'                     b
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   3          '^'                     c
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Notice that ')' is not included, because b would have to have
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// been called from a different context in rule a for ')' to be
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// included.
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// For error recovery, we cannot consider FOLLOW(c)
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// (context-sensitive or otherwise).  We need the combined set of
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// all context-sensitive FOLLOW sets--the set of all tokens that
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// could follow any reference in the call chain.  We need to
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// resync to one of those tokens.  Note that FOLLOW(c)='^' and if
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// we resync'd to that token, we'd consume until EOF.  We need to
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// In this case, for input "[]", LA(1) is in this set so we would
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// not consume anything and after printing an error rule c would
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// return normally.  It would not find the required '^' though.
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// At this point, it gets a mismatched token error and throws an
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// exception (since LA(1) is not in the viable following token
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// set).  The rule exception handler tries to recover, but finds
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// the same recovery set and doesn't consume anything.  Rule b
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// exits normally returning to rule a.  Now it finds the ']' (and
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// with the successful match exits errorRecovery mode).
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// So, you can see that the parser walks up call chain looking
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// for the token that was a member of the recovery set.
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Errors are not generated in errorRecovery mode.
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// ANTLR's error recovery mechanism is based upon original ideas:
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// "Algorithms + Data Structures = Programs" by Niklaus Wirth
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// and
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// "A note on error recovery in recursive descent parsers":
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// http://portal.acm.org/citation.cfm?id=947902.947905
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Later, Josef Grosch had some good ideas:
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// "Efficient and Comfortable Error Recovery in Recursive Descent
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Parsers":
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Like Grosch I implemented local FOLLOW sets that are combined
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// at run-time upon error to avoid overhead during parsing.
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET
879324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvercomputeErrorRecoverySet	    (pANTLR3_BASE_RECOGNIZER recognizer)
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return   recognizer->combineFollows(recognizer, ANTLR3_FALSE);
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Compute the context-sensitive FOLLOW set for current rule.
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Documentation below is from the Java runtime.
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// This is the set of token types that can follow a specific rule
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// reference given a specific call chain.  You get the set of
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// viable tokens that can possibly come next (look ahead depth 1)
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// given the current call chain.  Contrast this with the
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// definition of plain FOLLOW for rule r:
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///  FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// where x in T* and alpha, beta in V*; T is set of terminals and
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// V is the set of terminals and non terminals.  In other words,
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// FOLLOW(r) is the set of all tokens that can possibly follow
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// references to r in///any* sentential form (context).  At
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// runtime, however, we know precisely which context applies as
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// we have the call chain.  We may compute the exact (rather
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// than covering superset) set of following tokens.
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// For example, consider grammar:
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// stat : ID '=' expr ';'      // FOLLOW(stat)=={EOF}
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      | "return" expr '.'
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      ;
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// expr : atom ('+' atom)* ;   // FOLLOW(expr)=={';','.',')'}
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// atom : INT                  // FOLLOW(atom)=={'+',')',';','.'}
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      | '(' expr ')'
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      ;
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// The FOLLOW sets are all inclusive whereas context-sensitive
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// FOLLOW sets are precisely what could follow a rule reference.
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// For input input "i=(3);", here is the derivation:
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// stat => ID '=' expr ';'
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      => ID '=' atom ('+' atom)* ';'
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      => ID '=' '(' expr ')' ('+' atom)* ';'
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      => ID '=' '(' atom ')' ('+' atom)* ';'
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      => ID '=' '(' INT ')' ('+' atom)* ';'
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///      => ID '=' '(' INT ')' ';'
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// At the "3" token, you'd have a call chain of
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///   stat -> expr -> atom -> expr -> atom
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// What can follow that specific nested ref to atom?  Exactly ')'
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// as you can see by looking at the derivation of this specific
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// input.  Contrast this with the FOLLOW(atom)={'+',')',';','.'}.
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// You want the exact viable token set when recovering from a
933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// token mismatch.  Upon token mismatch, if LA(1) is member of
934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// the viable next token set, then you know there is most likely
935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// a missing token in the input stream.  "Insert" one by just not
936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// throwing an exception.
937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET
939324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvercomputeCSRuleFollow	    (pANTLR3_BASE_RECOGNIZER recognizer)
940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return   recognizer->combineFollows(recognizer, ANTLR3_FALSE);
942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Compute the current followset for the input stream.
945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_BITSET
947324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvercombineFollows		    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_BOOLEAN exact)
948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BITSET	followSet;
950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BITSET	localFollowSet;
951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_UINT32	top;
952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_UINT32	i;
953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    top	= recognizer->state->following->size(recognizer->state->following);
955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    followSet	    = antlr3BitsetNew(0);
957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	localFollowSet	= NULL;
958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for (i = top; i>0; i--)
960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		localFollowSet = antlr3BitsetLoad((pANTLR3_BITSET_LIST) recognizer->state->following->get(recognizer->state->following, i-1));
962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if  (localFollowSet != NULL)
964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			followSet->borInPlace(followSet, localFollowSet);
966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(exact == ANTLR3_TRUE)
968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if	(localFollowSet->isMember(localFollowSet, ANTLR3_EOR_TOKEN_TYPE) == ANTLR3_FALSE)
970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// Only leave EOR in the set if at top (start rule); this lets us know
972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// if we have to include the follow(start rule); I.E., EOF
973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					//
974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if	(i>1)
975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					{
976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						followSet->remove(followSet, ANTLR3_EOR_TOKEN_TYPE);
977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else
980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;	// Cannot see End Of Rule from here, just drop out
982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			localFollowSet->free(localFollowSet);
985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			localFollowSet = NULL;
986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(localFollowSet != NULL)
990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		localFollowSet->free(localFollowSet);
992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return  followSet;
994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Standard/Example error display method.
997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// No generic error message display funciton coudl possibly do everything correctly
998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// for all possible parsers. Hence you are provided with this example routine, which
999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// you should override in your parser/tree parser to do as you will.
1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Here we depart somewhat from the Java runtime as that has now split up a lot
1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// of the error display routines into spearate units. However, ther is little advantage
1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// to this in the C version as you will probably implement all such routines as a
1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// separate translation unit, rather than install them all as pointers to functions
1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// in the base recognizer.
1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
1008324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverdisplayRecognitionError	    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames)
1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_PARSER			parser;
1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_TREE_PARSER	    tparser;
1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_INT_STREAM	    is;
1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_STRING			ttext;
1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_STRING			ftext;
1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_EXCEPTION	    ex;
1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN    theToken;
1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_BASE_TREE	    theBaseTree;
1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TREE	    theCommonTree;
1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Retrieve some info for easy reading.
1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ex	    =		recognizer->state->exception;
1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ttext   =		NULL;
1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// See if there is a 'filename' we can use
1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(ex->streamName == NULL)
1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)
1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "-end of input-(");
1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else
1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "-unknown source-(");
1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	else
1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ftext = ex->streamName->to8(ex->streamName);
1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "%s(", ftext->chars);
1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Next comes the line number
1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ANTLR3_FPRINTF(stderr, "%d) ", recognizer->state->exception->line);
1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ANTLR3_FPRINTF(stderr, " : error %d : %s",
1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										recognizer->state->exception->type,
1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					(pANTLR3_UINT8)	   (recognizer->state->exception->message));
1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// How we determine the next piece is dependent on which thing raised the
1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// error.
1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	switch	(recognizer->type)
1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_PARSER:
1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Prepare the knowledge we know we have
1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser	    = (pANTLR3_PARSER) (recognizer->super);
1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser	    = NULL;
1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is			= parser->tstream->istream;
1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		theToken    = (pANTLR3_COMMON_TOKEN)(recognizer->state->exception->token);
1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ttext	    = theToken->toString(theToken);
1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, ", at offset %d", recognizer->state->exception->charPositionInLine);
1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if  (theToken != NULL)
1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if (theToken->type == ANTLR3_TOKEN_EOF)
1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, ", at <EOF>");
1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// Guard against null text in a token
1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//
1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, "\n    near %s\n    ", ttext == NULL ? (pANTLR3_UINT8)"<no text for the token>" : ttext->chars);
1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_TREE_PARSER:
1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser		= (pANTLR3_TREE_PARSER) (recognizer->super);
1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser		= NULL;
1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is			= tparser->ctnstream->tnstream->istream;
1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		theBaseTree	= (pANTLR3_BASE_TREE)(recognizer->state->exception->token);
1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ttext		= theBaseTree->toStringTree(theBaseTree);
1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if  (theBaseTree != NULL)
1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			theCommonTree	= (pANTLR3_COMMON_TREE)	    theBaseTree->super;
1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(theCommonTree != NULL)
1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				theToken	= (pANTLR3_COMMON_TOKEN)    theBaseTree->getToken(theBaseTree);
1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, ", at offset %d", theBaseTree->getCharPositionInLine(theBaseTree));
1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, ", near %s", ttext->chars);
1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	default:
1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function displayRecognitionError called by unknown parser type - provide override for this function\n");
1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Although this function should generally be provided by the implementation, this one
1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// should be as helpful as possible for grammar developers and serve as an example
1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// of what you can do with each exception type. In general, when you make up your
1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// 'real' handler, you should debug the routine with all possible errors you expect
1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// which will then let you be as specific as possible about all circumstances.
1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Note that in the general case, errors thrown by tree parsers indicate a problem
1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// with the output of the parser or with the tree grammar itself. The job of the parser
1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// is to produce a perfect (in traversal terms) syntactically correct tree, so errors
1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// at that stage should really be semantic errors that your own code determines and handles
1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// in whatever way is appropriate.
1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	switch  (ex->type)
1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_UNWANTED_TOKEN_EXCEPTION:
1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Indicates that the recognizer was fed a token which seesm to be
1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// spurious input. We can detect this when the token that follows
1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// this unwanted token would normally be part of the syntactically
1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// correct stream. Then we can see that the token we are looking at
1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// is just something that should not be there and throw this exception.
1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(tokenNames == NULL)
1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, " : Extraneous input...");
1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else
1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(ex->expecting == ANTLR3_TOKEN_EOF)
1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : Extraneous input - expected <EOF>\n");
1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : Extraneous input - expected %s ...\n", tokenNames[ex->expecting]);
1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_MISSING_TOKEN_EXCEPTION:
1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Indicates that the recognizer detected that the token we just
1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// hit would be valid syntactically if preceeded by a particular
1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token. Perhaps a missing ';' at line end or a missing ',' in an
1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// expression list, and such like.
1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(tokenNames == NULL)
1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, " : Missing token (%d)...\n", ex->expecting);
1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else
1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(ex->expecting == ANTLR3_TOKEN_EOF)
1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : Missing <EOF>\n");
1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : Missing %s \n", tokenNames[ex->expecting]);
1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_RECOGNITION_EXCEPTION:
1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Indicates that the recognizer received a token
1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// in the input that was not predicted. This is the basic exception type
1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// from which all others are derived. So we assume it was a syntax error.
1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// You may get this if there are not more tokens and more are needed
1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// to complete a parse for instance.
1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, " : syntax error...\n");
1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case    ANTLR3_MISMATCHED_TOKEN_EXCEPTION:
1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We were expecting to see one thing and got another. This is the
1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// most common error if we coudl not detect a missing or unwanted token.
1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Here you can spend your efforts to
1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// derive more useful error messages based on the expected
1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token set and the last token and so on. The error following
1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// bitmaps do a good job of reducing the set that we were looking
1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// for down to something small. Knowing what you are parsing may be
1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// able to allow you to be even more specific about an error.
1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(tokenNames == NULL)
1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, " : syntax error...\n");
1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else
1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if	(ex->expecting == ANTLR3_TOKEN_EOF)
1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : expected <EOF>\n");
1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, " : expected %s ...\n", tokenNames[ex->expecting]);
1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_NO_VIABLE_ALT_EXCEPTION:
1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We could not pick any alt decision from the input given
1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// so god knows what happened - however when you examine your grammar,
1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// you should. It means that at the point where the current token occurred
1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// that the DFA indicates nowhere to go from here.
1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, " : cannot match to any predicted input...\n");
1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_MISMATCHED_SET_EXCEPTION:
1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_UINT32	  count;
1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_UINT32	  bit;
1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_UINT32	  size;
1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_UINT32	  numbits;
1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			pANTLR3_BITSET	  errBits;
1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// This means we were able to deal with one of a set of
1235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// possible tokens at this point, but we did not see any
1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// member of that set.
1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//
1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, " : unexpected input...\n  expected one of : ");
1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// What tokens could we have accepted at this point in the
1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// parse?
1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//
1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			count   = 0;
1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			errBits = antlr3BitsetLoad		(ex->expectingSet);
1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			numbits = errBits->numBits		(errBits);
1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			size    = errBits->size			(errBits);
1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if  (size > 0)
1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// However many tokens we could have dealt with here, it is usually
1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// not useful to print ALL of the set here. I arbitrarily chose 8
1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// here, but you should do whatever makes sense for you of course.
1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// No token number 0, so look for bit 1 and on.
1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//
1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				for	(bit = 1; bit < numbits && count < 8 && count < size; bit++)
1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// TODO: This doesn;t look right - should be asking if the bit is set!!
1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					//
1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if  (tokenNames[bit])
1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					{
1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						ANTLR3_FPRINTF(stderr, "%s%s", count > 0 ? ", " : "", tokenNames[bit]);
1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						count++;
1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, "\n");
1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, "Actually dude, we didn't seem to be expecting anything here, or at least\n");
1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLR3_FPRINTF(stderr, "I could not work out what I was expecting, like so many of us these days!\n");
1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_EARLY_EXIT_EXCEPTION:
1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We entered a loop requiring a number of token sequences
1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// but found a token that ended that sequence earlier than
1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// we should have done.
1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, " : missing elements...\n");
1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	default:
1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We don't handle any other exceptions here, but you can
1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// if you wish. If we get an exception that hits this point
1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// then we are just going to report what we know about the
1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token.
1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, " : syntax not recognized...\n");
1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Here you have the token that was in error which if this is
1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// the standard implementation will tell you the line and offset
1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// and also record the address of the start of the line in the
1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// input stream. You could therefore print the source line and so on.
1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Generally though, I would expect that your lexer/parser will keep
1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// its own map of lines and source pointers or whatever as there
1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// are a lot of specific things you need to know about the input
1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// to do something like that.
1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Here is where you do it though :-).
1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Return how many syntax errors were detected by this recognizer
1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32
1310324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetNumberOfSyntaxErrors(pANTLR3_BASE_RECOGNIZER recognizer)
1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return	recognizer->state->errorCount;
1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Recover from an error found on the input stream.  Mostly this is
1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// NoViableAlt exceptions, but could be a mismatched token that
1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// the match() routine could not recover from.
1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrecover			    (pANTLR3_BASE_RECOGNIZER recognizer)
1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Used to compute the follow set of tokens
1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BITSET			followSet;
1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER			parser;
1326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser  = (pANTLR3_PARSER) (recognizer->super);
1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser	= NULL;
1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is		= parser->tstream->istream;
1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case	ANTLR3_TYPE_TREE_PARSER:
1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser	= NULL;
1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is		= tparser->ctnstream->tnstream->istream;
1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    default:
1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function recover called by unknown parser type - provide override for this function\n");
1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return;
1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Are we about to repeat the same error?
1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer->state->lastErrorIndex == is->index(is))
1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// The last error was at the same token index point. This must be a case
1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// where LT(1) is in the recovery token set so nothing is
1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// consumed. Consume a single token so at least to prevent
1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// an infinite loop; this is a failsafe.
1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);
1365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Record error index position
1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->lastErrorIndex	 = is->index(is);
1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Work out the follows set for error recovery
1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    followSet	= recognizer->computeErrorRecoverySet(recognizer);
1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Call resync hook (for debuggers and so on)
1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->beginResync(recognizer);
1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Consume tokens until we have resynced to something in the follows set
1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->consumeUntilSet(recognizer, followSet);
1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // End resync hook
1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->endResync(recognizer);
1386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Destroy the temporary bitset we produced.
1388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    followSet->free(followSet);
1390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Reset the inError flag so we don't re-report the exception
1392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->error	= ANTLR3_FALSE;
1394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->failed	= ANTLR3_FALSE;
1395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Attempt to recover from a single missing or extra token.
1399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// EXTRA TOKEN
1401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// LA(1) is not what we are looking for.  If LA(2) has the right token,
1403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// however, then assume LA(1) is some extra spurious token.  Delete it
1404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// and LA(2) as if we were doing a normal match(), which advances the
1405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// input.
1406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// MISSING TOKEN
1408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// If current token is consistent with what could come after
1410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// ttype then it is ok to "insert" the missing token, else throw
1411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// exception For example, Input "i=(3;" is clearly missing the
1412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// ')'.  When the parser returns from the nested call to expr, it
1413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// will have call chain:
1414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///    stat -> expr -> atom
1416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// and it will be trying to match the ')' at this point in the
1418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// derivation:
1419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///       => ID '=' '(' INT ')' ('+' atom)* ';'
1421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///                          ^
1422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// match() will see that ';' doesn't match ')' and report a
1423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// mismatched token error.  To recover, it sees that LA(1)==';'
1424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// is in the set of tokens that can follow the ')' token
1425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// reference in rule atom.  It can assume that you forgot the ')'.
1426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// The exception that was passed in, in the java implementation is
1428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// sorted in the recognizer exception stack in the C version. To 'throw' it we set the
1429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// error flag and rules cascade back when this is set.
1430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *
1432324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverrecoverFromMismatchedToken  (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
1433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_PARSER			  parser;
1435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_TREE_PARSER	      tparser;
1436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_INT_STREAM	      is;
1437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	void					* matchedSymbol;
1438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	switch	(recognizer->type)
1442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_PARSER:
1444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser  = (pANTLR3_PARSER) (recognizer->super);
1446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser	= NULL;
1447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= parser->tstream->istream;
1448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	case	ANTLR3_TYPE_TREE_PARSER:
1452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser	= NULL;
1455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= tparser->ctnstream->tnstream->istream;
1456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	default:
1460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function recoverFromMismatchedToken called by unknown parser type - provide override for this function\n");
1462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return NULL;
1463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		break;
1465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Create an exception if we need one
1468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->state->exception == NULL)
1470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		antlr3RecognitionExceptionNew(recognizer);
1472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// If the next token after the one we are looking at in the input stream
1475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// is what we are looking for then we remove the one we have discovered
1476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// from the stream by consuming it, then consume this next one along too as
1477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// if nothing had happened.
1478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	( recognizer->mismatchIsUnwantedToken(recognizer, is, ttype) == ANTLR3_TRUE)
1480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->type		= ANTLR3_UNWANTED_TOKEN_EXCEPTION;
1482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->message	= ANTLR3_UNWANTED_TOKEN_EXCEPTION_NAME;
1483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Call resync hook (for debuggers and so on)
1485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->debugger != NULL)
1487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->debugger->beginResync(recognizer->debugger);
1489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// "delete" the extra token
1492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->beginResync(recognizer);
1494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);
1495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->endResync(recognizer);
1496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// End resync hook
1497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->debugger != NULL)
1499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->debugger->endResync(recognizer->debugger);
1501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Print out the error after we consume so that ANTLRWorks sees the
1504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token in the exception.
1505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->reportError(recognizer);
1507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Return the token we are actually matching
1509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		matchedSymbol = recognizer->getCurrentInputSymbol(recognizer, is);
1511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Consume the token that the rule actually expected to get as if everything
1513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// was hunky dory.
1514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);
1516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->error  = ANTLR3_FALSE;	// Exception is not outstanding any more
1518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	matchedSymbol;
1520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Single token deletion (Unwanted above) did not work
1523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// so we see if we can insert a token instead by calculating which
1524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// token would be missing
1525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(mismatchIsMissingToken(recognizer, is, follow))
1527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We can fake the missing token and proceed
1529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		matchedSymbol = recognizer->getMissingSymbol(recognizer, is, recognizer->state->exception, ttype, follow);
1531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->type		= ANTLR3_MISSING_TOKEN_EXCEPTION;
1532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->message	= ANTLR3_MISSING_TOKEN_EXCEPTION_NAME;
1533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->token		= matchedSymbol;
1534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->expecting	= ttype;
1535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Print out the error after we insert so that ANTLRWorks sees the
1537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token in the exception.
1538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->reportError(recognizer);
1540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->error  = ANTLR3_FALSE;	// Exception is not outstanding any more
1542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	matchedSymbol;
1544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Neither deleting nor inserting tokens allows recovery
1548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// must just report the exception.
1549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
1550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->error	    = ANTLR3_TRUE;
1551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return NULL;
1552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *
1555324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverrecoverFromMismatchedSet	    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow)
1556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER			parser;
1558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN	matchedSymbol;
1561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case	ANTLR3_TYPE_PARSER:
1565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser  = (pANTLR3_PARSER) (recognizer->super);
1567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser	= NULL;
1568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= parser->tstream->istream;
1569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case	ANTLR3_TYPE_TREE_PARSER:
1573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser	= NULL;
1576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= tparser->ctnstream->tnstream->istream;
1577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    default:
1581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function recoverFromMismatchedSet called by unknown parser type - provide override for this function\n");
1583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return NULL;
1584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->mismatchIsMissingToken(recognizer, is, follow) == ANTLR3_TRUE)
1589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We can fake the missing token and proceed
1591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		matchedSymbol = recognizer->getMissingSymbol(recognizer, is, recognizer->state->exception, ANTLR3_TOKEN_INVALID, follow);
1593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->type	= ANTLR3_MISSING_TOKEN_EXCEPTION;
1594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->exception->token	= matchedSymbol;
1595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Print out the error after we insert so that ANTLRWorks sees the
1597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token in the exception.
1598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
1599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->reportError(recognizer);
1600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->error  = ANTLR3_FALSE;	// Exception is not outstanding any more
1602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	matchedSymbol;
1604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // TODO - Single token deletion like in recoverFromMismatchedToken()
1607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->error	= ANTLR3_TRUE;
1609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->failed	= ANTLR3_TRUE;
1610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return NULL;
1611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// This code is factored out from mismatched token and mismatched set
1614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///  recovery.  It handles "single token insertion" error recovery for
1615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// both.  No tokens are consumed to recover from insertions.  Return
1616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// true if recovery was possible else return false.
1617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN
1619324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverrecoverFromMismatchedElement	    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST followBits)
1620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BITSET	    viableToksFollowingRule;
1622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_BITSET	    follow;
1623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
1624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case	ANTLR3_TYPE_PARSER:
1630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser  = (pANTLR3_PARSER) (recognizer->super);
1632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser	= NULL;
1633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= parser->tstream->istream;
1634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case	ANTLR3_TYPE_TREE_PARSER:
1638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser	= NULL;
1641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is	= tparser->ctnstream->tnstream->istream;
1642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    default:
1646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLR3_FPRINTF(stderr, "Base recognizer function recover called by unknown parser type - provide override for this function\n");
1648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_FALSE;
1649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	break;
1651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    follow	= antlr3BitsetLoad(followBits);
1654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(follow == NULL)
1656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* The follow set is NULL, which means we don't know what can come
1658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * next, so we "hit and hope" by just signifying that we cannot
1659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * recover, which will just cause the next token to be consumed,
1660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * which might dig us out.
1661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	ANTLR3_FALSE;
1663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* We have a bitmap for the follow set, hence we can compute
1666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * what can follow this grammar element reference.
1667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(follow->isMember(follow, ANTLR3_EOR_TOKEN_TYPE) == ANTLR3_TRUE)
1669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* First we need to know which of the available tokens are viable
1671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * to follow this reference.
1672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		viableToksFollowingRule	= recognizer->computeCSRuleFollow(recognizer);
1674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* Remove the EOR token, which we do not wish to compute with
1676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		follow->remove(follow, ANTLR3_EOR_TOKEN_TYPE);
1678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		viableToksFollowingRule->free(viableToksFollowingRule);
1679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* We now have the computed set of what can follow the current token
1680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* We can now see if the current token works with the set of tokens
1684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * that could follow the current grammar reference. If it looks like it
1685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * is consistent, then we can "insert" that token by not throwing
1686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * an exception and assuming that we saw it.
1687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	( follow->isMember(follow, is->_LA(is, 1)) == ANTLR3_TRUE)
1689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* report the error, but don't cause any rules to abort and stuff
1691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->reportError(recognizer);
1693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(follow != NULL)
1694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			follow->free(follow);
1696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->error			= ANTLR3_FALSE;
1698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed			= ANTLR3_FALSE;
1699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_TRUE;	/* Success in recovery	*/
1700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(follow != NULL)
1703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		follow->free(follow);
1705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* We could not find anything viable to do, so this is going to
1708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * cause an exception.
1709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return  ANTLR3_FALSE;
1711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Eat tokens from the input stream until we get one of JUST the right type
1714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
1716324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverconsumeUntil	(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 tokenType)
1717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_UINT32			ttype;
1719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER			parser;
1720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
1726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
1728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
1729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
1730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
1734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
1737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
1738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
1742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'consumeUntil' called by unknown parser type - provide override for this function\n");
1744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // What do have at the moment?
1750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ttype	= is->_LA(is, 1);
1752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Start eating tokens until we get to the one we want.
1754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while   (ttype != ANTLR3_TOKEN_EOF && ttype != tokenType)
1756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);
1758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ttype	= is->_LA(is, 1);
1759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Eat tokens from the input stream until we find one that
1763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// belongs to the supplied set.
1764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
1765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
1766324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverconsumeUntilSet			    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET set)
1767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_UINT32	    ttype;
1769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
1770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
1776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
1778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
1779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
1780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
1784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
1787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
1788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
1792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'consumeUntilSet' called by unknown parser type - provide override for this function\n");
1794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // What do have at the moment?
1800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ttype	= is->_LA(is, 1);
1802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Start eating tokens until we get to one we want.
1804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
1805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while   (ttype != ANTLR3_TOKEN_EOF && set->isMember(set, ttype) == ANTLR3_FALSE)
1806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->consume(is);
1808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ttype	= is->_LA(is, 1);
1809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Return the rule invocation stack (how we got here in the parse.
1813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  In the java version Ter just asks the JVM for all the information
1814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  but in C we don't get this information, so I am going to do nothing
1815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  right now.
1816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
1817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_STACK
1818324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetRuleInvocationStack		    (pANTLR3_BASE_RECOGNIZER recognizer)
1819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return NULL;
1821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_STACK
1824324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetRuleInvocationStackNamed	    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 name)
1825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return NULL;
1827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Convenience method for template rewrites - NYI.
1830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
1831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_TABLE
1832324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvertoStrings			    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_HASH_TABLE tokens)
1833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return NULL;
1835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic	void ANTLR3_CDECL
1838324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverfreeIntTrie    (void * trie)
1839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ((pANTLR3_INT_TRIE)trie)->free((pANTLR3_INT_TRIE)trie);
1841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Pointer to a function to return whether the rule has parsed input starting at the supplied
1845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  start index before. If the rule has not parsed input starting from the supplied start index,
1846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  then it will return ANTLR3_MEMO_RULE_UNKNOWN. If it has parsed from the suppled start point
1847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  then it will return the point where it last stopped parsing after that start point.
1848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
1849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \remark
1850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The rule memos are an ANTLR3_LIST of ANTLR3_LISTS, however if this becomes any kind of performance
1851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * issue (it probably won't, the hash tables are pretty quick) then we could make a special int only
1852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * version of the table.
1853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
1854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_MARKER
1855324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetRuleMemoization		    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_INTKEY ruleIndex, ANTLR3_MARKER ruleParseStart)
1856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST.
1858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_TRIE	ruleList;
1860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_MARKER	stopIndex;
1861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TRIE_ENTRY	entry;
1862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* See if we have a list in the ruleMemos for this rule, and if not, then create one
1864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * as we will need it eventually if we are being asked for the memo here.
1865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    entry	= recognizer->state->ruleMemo->get(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex);
1867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(entry == NULL)
1869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* Did not find it, so create a new one for it, with a bit depth based on the
1871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * size of the input stream. We need the bit depth to incorporate the number if
1872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * bits required to represent the largest possible stop index in the input, which is the
1873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * last character. An int stream is free to return the largest 64 bit offset if it has
1874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * no idea of the size, but you should remember that this will cause the leftmost
1875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * bit match algorithm to run to 63 bits, which will be the whole time spent in the trie ;-)
1876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ruleList    = antlr3IntTrieNew(63);	/* Depth is theoretically 64 bits, but probably not ;-)	*/
1878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if (ruleList != NULL)
1880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->ruleMemo->add(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex, ANTLR3_HASH_TYPE_STR, 0, ANTLR3_FUNC_PTR(ruleList), freeIntTrie);
1882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* We cannot have a stopIndex in a trie we have just created of course
1885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
1886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	MEMO_RULE_UNKNOWN;
1887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ruleList	= (pANTLR3_INT_TRIE) (entry->data.ptr);
1890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* See if there is a stop index associated with the supplied start index.
1892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stopIndex	= 0;
1894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    entry = ruleList->get(ruleList, ruleParseStart);
1896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (entry != NULL)
1897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		stopIndex = (ANTLR3_MARKER)(entry->data.intVal);
1899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(stopIndex == 0)
1902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return MEMO_RULE_UNKNOWN;
1904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return  stopIndex;
1907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Has this rule already parsed input at the current index in the
1910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  input stream?  Return ANTLR3_TRUE if we have and ANTLR3_FALSE
1911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  if we have not.
1912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
1913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  This method has a side-effect: if we have seen this input for
1914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  this rule and successfully parsed before, then seek ahead to
1915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  1 past the stop token matched for this rule last time.
1916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
1917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN
1918324c4644fee44b9898524c09511bd33c3f12e2dfBen GruveralreadyParsedRule		    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex)
1919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_MARKER			stopIndex;
1921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_LEXER			lexer;
1922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER			parser;
1923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
1925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
1927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
1929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
1931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
1932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexer	= NULL;
1933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
1934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
1938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
1940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
1941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexer	= NULL;
1942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
1943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_LEXER:
1947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexer	= (pANTLR3_LEXER)   (recognizer->super);
1949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
1950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
1951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= lexer->input->istream;
1952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
1955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'alreadyParsedRule' called by unknown parser type - provide override for this function\n");
1957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return ANTLR3_FALSE;
1958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
1960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* See if we have a memo marker for this.
1963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stopIndex	    = recognizer->getRuleMemoization(recognizer, ruleIndex, is->index(is));
1965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(stopIndex  == MEMO_RULE_UNKNOWN)
1967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ANTLR3_FALSE;
1969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(stopIndex == MEMO_RULE_FAILED)
1972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed = ANTLR3_TRUE;
1974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
1976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		is->seek(is, stopIndex+1);
1978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* If here then the rule was executed for this input already
1981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return  ANTLR3_TRUE;
1983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
1984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Record whether or not this rule parsed the input at this position
1986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  successfully.
1987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
1988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
1989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermemoize	(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex, ANTLR3_MARKER ruleParseStart)
1990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
1991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST.
1992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
1993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_TRIE	    ruleList;
1994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TRIE_ENTRY	    entry;
1995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_MARKER	    stopIndex;
1996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_LEXER	    lexer;
1997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
1998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
1999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
2000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
2002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
2004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
2006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
2007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
2008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
2012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
2014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
2015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
2016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_LEXER:
2020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexer	= (pANTLR3_LEXER)   (recognizer->super);
2022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
2023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
2024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is		= lexer->input->istream;
2025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
2028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function consumeUntilSet called by unknown parser type - provide override for this function\n");
2030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
2031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stopIndex	= recognizer->state->failed == ANTLR3_TRUE ? MEMO_RULE_FAILED : is->index(is) - 1;
2036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    entry	= recognizer->state->ruleMemo->get(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex);
2038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(entry != NULL)
2040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ruleList = (pANTLR3_INT_TRIE)(entry->data.ptr);
2042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* If we don't already have this entry, append it. The memoize trie does not
2044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * accept duplicates so it won't add it if already there and we just ignore the
2045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 * return code as we don't care if it is there already.
2046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
2047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ruleList->add(ruleList, ruleParseStart, ANTLR3_HASH_TYPE_INT, stopIndex, NULL, NULL);
2048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
2050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** A syntactic predicate.  Returns true/false depending on whether
2051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  the specified grammar fragment matches the current input stream.
2052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  This resets the failed instance var afterwards.
2053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
2054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN
2055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversynpred	(pANTLR3_BASE_RECOGNIZER recognizer, void * ctx, void (*predicate)(void * ctx))
2056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
2057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3_MARKER   start;
2058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_PARSER	    parser;
2059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_TREE_PARSER	    tparser;
2060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pANTLR3_INT_STREAM	    is;
2061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    switch	(recognizer->type)
2063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_PARSER:
2065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser  = (pANTLR3_PARSER) (recognizer->super);
2067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser	= NULL;
2068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= parser->tstream->istream;
2069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		case	ANTLR3_TYPE_TREE_PARSER:
2073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
2075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parser	= NULL;
2076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			is	= tparser->ctnstream->tnstream->istream;
2077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		default:
2081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLR3_FPRINTF(stderr, "Base recognizer function 'synPred' called by unknown parser type - provide override for this function\n");
2083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return ANTLR3_FALSE;
2084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			break;
2086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Begin backtracking so we can get back to where we started after trying out
2089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * the syntactic predicate.
2090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
2091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start   = is->mark(is);
2092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->backtracking++;
2093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Try the syntactical predicate
2095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
2096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    predicate(ctx);
2097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /* Reset
2099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
2100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    is->rewind(is, start);
2101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->backtracking--;
2102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer->state->failed == ANTLR3_TRUE)
2104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* Predicate failed
2106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
2107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed = ANTLR3_FALSE;
2108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	ANTLR3_FALSE;
2109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
2111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* Predicate was successful
2113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
2114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->failed	= ANTLR3_FALSE;
2115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return	ANTLR3_TRUE;
2116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
2118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void
2120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverreset(pANTLR3_BASE_RECOGNIZER recognizer)
2121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
2122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if	(recognizer->state->following != NULL)
2123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
2124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->following->free(recognizer->state->following);
2125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Reset the state flags
2128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->errorRecovery	= ANTLR3_FALSE;
2130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->lastErrorIndex	= -1;
2131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->failed			= ANTLR3_FALSE;
2132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->errorCount		= 0;
2133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->backtracking		= 0;
2134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	recognizer->state->following		= NULL;
2135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->state != NULL)
2137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if	(recognizer->state->ruleMemo != NULL)
2139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
2140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->ruleMemo->free(recognizer->state->ruleMemo);
2141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			recognizer->state->ruleMemo = antlr3IntTrieNew(15);	/* 16 bit depth is enough for 32768 rules! */
2142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Install a new following set
2147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
2148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recognizer->state->following   = antlr3StackNew(8);
2149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
2151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Default implementation is for parser and assumes a token stream as supplied by the runtime.
2153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// You MAY need override this function if the standard TOKEN_STREAM is not what you are using.
2154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
2155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *
2156324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetCurrentInputSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream)
2157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
2158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return ((pANTLR3_TOKEN_STREAM)istream->super)->_LT((pANTLR3_TOKEN_STREAM)istream->super, 1);
2159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
2160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Default implementation is for parser and assumes a token stream as supplied by the runtime.
2162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// You MAY need override this function if the standard COMMON_TOKEN_STREAM is not what you are using.
2163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
2164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void *
2165324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvergetMissingSymbol			(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
2166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow)
2167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
2168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_TOKEN_STREAM			ts;
2169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN_STREAM		cts;
2170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN			token;
2171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_COMMON_TOKEN			current;
2172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	pANTLR3_STRING					text;
2173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Dereference the standard pointers
2175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	ts		= (pANTLR3_TOKEN_STREAM)istream->super;
2177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	cts		= (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
2178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Work out what to use as the current symbol to make a line and offset etc
2180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// If we are at EOF, we use the token before EOF
2181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	current	= ts->_LT(ts, 1);
2183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(current->getType(current) == ANTLR3_TOKEN_EOF)
2184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		current = ts->_LT(ts, -1);
2186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Create a new empty token
2189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(recognizer->state->tokFactory == NULL)
2191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// We don't yet have a token factory for making tokens
2193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// we just need a fake one using the input stream of the current
2194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// token.
2195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//
2196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		recognizer->state->tokFactory = antlr3TokenFactoryNew(current->input);
2197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token	= recognizer->state->tokFactory->newToken(recognizer->state->tokFactory);
2199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Set some of the token properties based on the current token
2201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token->setLine					(token, current->getLine(current));
2203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token->setCharPositionInLine	(token, current->getCharPositionInLine(current));
2204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token->setChannel				(token, ANTLR3_TOKEN_DEFAULT_CHANNEL);
2205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token->setType					(token, expectedTokenType);
2206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token->user1                    = current->user1;
2207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token->user2                    = current->user2;
2208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token->user3                    = current->user3;
2209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token->custom                   = current->custom;
2210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token->lineStart                = current->lineStart;
2211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Create the token text that shows it has been inserted
2213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	token->setText8(token, (pANTLR3_UINT8)"<missing ");
2215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	text = token->getText(token);
2216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	if	(text != NULL)
2218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		text->append8(text, (const char *)recognizer->state->tokenNames[expectedTokenType]);
2220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		text->append8(text, (const char *)">");
2221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Finally return the pointer to our new token
2224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//
2225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	return	token;
2226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
2227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifdef	ANTLR3_WINDOWS
2230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#pragma warning( default : 4100 )
2231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif
2232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// @}
2234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver///
2235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2236