]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/cpp/DataBoardTest/libantlr3c-3.2/src/antlr3baserecognizer.c
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / cpp / DataBoardTest / libantlr3c-3.2 / src / antlr3baserecognizer.c
1 /** \file\r
2  * Contains the base functions that all recognizers require.\r
3  * Any function can be overridden by a lexer/parser/tree parser or by the\r
4  * ANTLR3 programmer.\r
5  * \r
6  * \addtogroup pANTLR3_BASE_RECOGNIZER\r
7  * @{\r
8  */\r
9 #include    <antlr3baserecognizer.h>\r
10 \r
11 // [The "BSD licence"]\r
12 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC\r
13 // http://www.temporal-wave.com\r
14 // http://www.linkedin.com/in/jimidle\r
15 //\r
16 // All rights reserved.\r
17 //\r
18 // Redistribution and use in source and binary forms, with or without\r
19 // modification, are permitted provided that the following conditions\r
20 // are met:\r
21 // 1. Redistributions of source code must retain the above copyright\r
22 //    notice, this list of conditions and the following disclaimer.\r
23 // 2. Redistributions in binary form must reproduce the above copyright\r
24 //    notice, this list of conditions and the following disclaimer in the\r
25 //    documentation and/or other materials provided with the distribution.\r
26 // 3. The name of the author may not be used to endorse or promote products\r
27 //    derived from this software without specific prior written permission.\r
28 //\r
29 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
30 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
31 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
32 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
33 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
34 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
36 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
37 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
38 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
39 \r
40 #ifdef  ANTLR3_WINDOWS\r
41 #pragma warning( disable : 4100 )\r
42 #endif\r
43 \r
44 /* Interface functions -standard implementations cover parser and treeparser\r
45  * almost completely but are overridden by the parser or tree parser as needed. Lexer overrides\r
46  * most of these functions.\r
47  */\r
48 static void                                     beginResync                                     (pANTLR3_BASE_RECOGNIZER recognizer);\r
49 static pANTLR3_BITSET           computeErrorRecoverySet     (pANTLR3_BASE_RECOGNIZER recognizer);\r
50 static void                                     endResync                                       (pANTLR3_BASE_RECOGNIZER recognizer);\r
51 static void                                     beginBacktrack                          (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level);\r
52 static void                                     endBacktrack                            (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level, ANTLR3_BOOLEAN successful);\r
53 \r
54 static void *                           match                                           (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);\r
55 static void                                     matchAny                                        (pANTLR3_BASE_RECOGNIZER recognizer);\r
56 static void                                     mismatch                                        (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);\r
57 static ANTLR3_BOOLEAN           mismatchIsUnwantedToken         (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, ANTLR3_UINT32 ttype);\r
58 static ANTLR3_BOOLEAN           mismatchIsMissingToken          (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_BITSET_LIST follow);\r
59 static void                                     reportError                                     (pANTLR3_BASE_RECOGNIZER recognizer);\r
60 static pANTLR3_BITSET           computeCSRuleFollow                     (pANTLR3_BASE_RECOGNIZER recognizer);\r
61 static pANTLR3_BITSET           combineFollows                          (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_BOOLEAN exact);\r
62 static void                                     displayRecognitionError     (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames);\r
63 static void                                     recover                                         (pANTLR3_BASE_RECOGNIZER recognizer);\r
64 static void     *                               recoverFromMismatchedToken  (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);\r
65 static void     *                               recoverFromMismatchedSet    (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow);\r
66 static ANTLR3_BOOLEAN           recoverFromMismatchedElement(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow);\r
67 static void                                     consumeUntil                            (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 tokenType);\r
68 static void                                     consumeUntilSet                         (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET set);\r
69 static pANTLR3_STACK            getRuleInvocationStack      (pANTLR3_BASE_RECOGNIZER recognizer);\r
70 static pANTLR3_STACK            getRuleInvocationStackNamed (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 name);\r
71 static pANTLR3_HASH_TABLE       toStrings                                       (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_HASH_TABLE);\r
72 static ANTLR3_MARKER            getRuleMemoization                      (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_INTKEY ruleIndex, ANTLR3_MARKER ruleParseStart);\r
73 static ANTLR3_BOOLEAN           alreadyParsedRule                       (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex);\r
74 static void                                     memoize                                         (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex, ANTLR3_MARKER ruleParseStart);\r
75 static ANTLR3_BOOLEAN           synpred                                         (pANTLR3_BASE_RECOGNIZER recognizer, void * ctx, void (*predicate)(void * ctx));\r
76 static void                                     reset                                           (pANTLR3_BASE_RECOGNIZER recognizer);\r
77 static void                                     freeBR                                          (pANTLR3_BASE_RECOGNIZER recognizer);\r
78 static void *                           getCurrentInputSymbol           (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream);\r
79 static void *                           getMissingSymbol                        (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream, pANTLR3_EXCEPTION      e,\r
80                                                                                                                         ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow);\r
81 static ANTLR3_UINT32            getNumberOfSyntaxErrors         (pANTLR3_BASE_RECOGNIZER recognizer);\r
82 \r
83 ANTLR3_API pANTLR3_BASE_RECOGNIZER\r
84 antlr3BaseRecognizerNew(ANTLR3_UINT32 type, ANTLR3_UINT32 sizeHint, pANTLR3_RECOGNIZER_SHARED_STATE state)\r
85 {\r
86     pANTLR3_BASE_RECOGNIZER recognizer;\r
87 \r
88     // Allocate memory for the structure\r
89     //\r
90     recognizer      = (pANTLR3_BASE_RECOGNIZER) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_BASE_RECOGNIZER));\r
91 \r
92     if  (recognizer == NULL)\r
93     {\r
94                 // Allocation failed\r
95                 //\r
96                 return  NULL;\r
97     }\r
98 \r
99         \r
100         // If we have been supplied with a pre-existing recognizer state\r
101         // then we just install it, otherwise we must create one from scratch\r
102         //\r
103         if      (state == NULL)\r
104         {\r
105                 recognizer->state = (pANTLR3_RECOGNIZER_SHARED_STATE) ANTLR3_CALLOC(1, (size_t)sizeof(ANTLR3_RECOGNIZER_SHARED_STATE));\r
106 \r
107                 if      (recognizer->state == NULL)\r
108                 {\r
109                         ANTLR3_FREE(recognizer);\r
110                         return  NULL;\r
111                 }\r
112 \r
113                 // Initialize any new recognizer state\r
114                 //\r
115                 recognizer->state->errorRecovery        = ANTLR3_FALSE;\r
116                 recognizer->state->lastErrorIndex       = -1;\r
117                 recognizer->state->failed               = ANTLR3_FALSE;\r
118                 recognizer->state->errorCount           = 0;\r
119                 recognizer->state->backtracking         = 0;\r
120                 recognizer->state->following            = NULL;\r
121                 recognizer->state->ruleMemo             = NULL;\r
122                 recognizer->state->tokenNames           = NULL;\r
123                 recognizer->state->sizeHint             = sizeHint;\r
124                 recognizer->state->tokSource            = NULL;\r
125                 recognizer->state->tokFactory           = NULL;\r
126 \r
127                 // Rather than check to see if we must initialize\r
128                 // the stack every time we are asked for an new rewrite stream\r
129                 // we just always create an empty stack and then just\r
130                 // free it when the base recognizer is freed.\r
131                 //\r
132                 recognizer->state->rStreams             = antlr3VectorNew(0);  // We don't know the size.\r
133 \r
134                 if      (recognizer->state->rStreams == NULL)\r
135                 {\r
136                         // Out of memory\r
137                         //\r
138                         ANTLR3_FREE(recognizer->state);\r
139                         ANTLR3_FREE(recognizer);\r
140                         return  NULL;\r
141                 }\r
142         }\r
143         else\r
144         {\r
145                 // Install the one we were given, and do not reset it here\r
146                 // as it will either already have been initialized or will\r
147                 // be in a state that needs to be preserved.\r
148                 //\r
149                 recognizer->state = state;\r
150         }\r
151                 \r
152     // Install the BR API\r
153     //\r
154     recognizer->alreadyParsedRule           = alreadyParsedRule;\r
155     recognizer->beginResync                 = beginResync;\r
156     recognizer->combineFollows              = combineFollows;\r
157     recognizer->beginBacktrack              = beginBacktrack;\r
158     recognizer->endBacktrack                = endBacktrack;\r
159     recognizer->computeCSRuleFollow         = computeCSRuleFollow;\r
160     recognizer->computeErrorRecoverySet     = computeErrorRecoverySet;\r
161     recognizer->consumeUntil                = consumeUntil;\r
162     recognizer->consumeUntilSet             = consumeUntilSet;\r
163     recognizer->displayRecognitionError     = displayRecognitionError;\r
164     recognizer->endResync                   = endResync;\r
165     recognizer->exConstruct                 = antlr3MTExceptionNew;\r
166     recognizer->getRuleInvocationStack      = getRuleInvocationStack;\r
167     recognizer->getRuleInvocationStackNamed = getRuleInvocationStackNamed;\r
168     recognizer->getRuleMemoization          = getRuleMemoization;\r
169     recognizer->match                       = match;\r
170     recognizer->matchAny                    = matchAny;\r
171     recognizer->memoize                     = memoize;\r
172     recognizer->mismatch                    = mismatch;\r
173     recognizer->mismatchIsUnwantedToken     = mismatchIsUnwantedToken;\r
174     recognizer->mismatchIsMissingToken      = mismatchIsMissingToken;\r
175     recognizer->recover                     = recover;\r
176     recognizer->recoverFromMismatchedElement= recoverFromMismatchedElement;\r
177     recognizer->recoverFromMismatchedSet    = recoverFromMismatchedSet;\r
178     recognizer->recoverFromMismatchedToken  = recoverFromMismatchedToken;\r
179     recognizer->getNumberOfSyntaxErrors     = getNumberOfSyntaxErrors;\r
180     recognizer->reportError                 = reportError;\r
181     recognizer->reset                       = reset;\r
182     recognizer->synpred                     = synpred;\r
183     recognizer->toStrings                   = toStrings;\r
184     recognizer->getCurrentInputSymbol       = getCurrentInputSymbol;\r
185     recognizer->getMissingSymbol            = getMissingSymbol;\r
186     recognizer->debugger                    = NULL;\r
187 \r
188     recognizer->free = freeBR;\r
189 \r
190     /* Initialize variables\r
191      */\r
192     recognizer->type                    = type;\r
193 \r
194 \r
195     return  recognizer;\r
196 }\r
197 static void     \r
198 freeBR      (pANTLR3_BASE_RECOGNIZER recognizer)\r
199 {\r
200     pANTLR3_EXCEPTION thisE;\r
201 \r
202         // Did we have a state allocated?\r
203         //\r
204         if      (recognizer->state != NULL)\r
205         {\r
206                 // Free any rule memoization we set up\r
207                 //\r
208                 if      (recognizer->state->ruleMemo != NULL)\r
209                 {\r
210                         recognizer->state->ruleMemo->free(recognizer->state->ruleMemo);\r
211                         recognizer->state->ruleMemo = NULL;\r
212                 }\r
213 \r
214                 // Free any exception space we have left around\r
215                 //\r
216                 thisE = recognizer->state->exception;\r
217                 if      (thisE != NULL)\r
218                 {\r
219                         thisE->freeEx(thisE);\r
220                 }\r
221 \r
222                 // Free any rewrite streams we have allocated\r
223                 //\r
224                 if      (recognizer->state->rStreams != NULL)\r
225                 {\r
226                         recognizer->state->rStreams->free(recognizer->state->rStreams);\r
227                 }\r
228 \r
229                 // Free up any token factory we created (error recovery for instance)\r
230                 //\r
231                 if      (recognizer->state->tokFactory != NULL)\r
232                 {\r
233                         recognizer->state->tokFactory->close(recognizer->state->tokFactory);\r
234                 }\r
235                 // Free the shared state memory\r
236                 //\r
237                 ANTLR3_FREE(recognizer->state);\r
238         }\r
239 \r
240         // Free the actual recognizer space\r
241         //\r
242     ANTLR3_FREE(recognizer);\r
243 }\r
244 \r
245 /**\r
246  * Creates a new Mismatched Token Exception and inserts in the recognizer\r
247  * exception stack.\r
248  * \r
249  * \param recognizer\r
250  * Context pointer for this recognizer\r
251  * \r
252  */\r
253 ANTLR3_API      void\r
254 antlr3MTExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)\r
255 {\r
256     /* Create a basic recognition exception structure\r
257      */\r
258     antlr3RecognitionExceptionNew(recognizer);\r
259 \r
260     /* Now update it to indicate this is a Mismatched token exception\r
261      */\r
262     recognizer->state->exception->name          = ANTLR3_MISMATCHED_EX_NAME;\r
263     recognizer->state->exception->type          = ANTLR3_MISMATCHED_TOKEN_EXCEPTION;\r
264 \r
265     return;\r
266 }\r
267 \r
268 ANTLR3_API      void\r
269 antlr3RecognitionExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)\r
270 {\r
271         pANTLR3_EXCEPTION                               ex;\r
272         pANTLR3_LEXER                                   lexer;\r
273         pANTLR3_PARSER                                  parser;\r
274         pANTLR3_TREE_PARSER                             tparser;\r
275 \r
276         pANTLR3_INPUT_STREAM                    ins;\r
277         pANTLR3_INT_STREAM                              is;\r
278         pANTLR3_COMMON_TOKEN_STREAM         cts;\r
279         pANTLR3_TREE_NODE_STREAM            tns;\r
280 \r
281         ins         = NULL;\r
282         cts         = NULL;\r
283         tns         = NULL;\r
284         is          = NULL;\r
285         lexer   = NULL;\r
286         parser  = NULL;\r
287         tparser = NULL;\r
288 \r
289         switch  (recognizer->type)\r
290         {\r
291         case    ANTLR3_TYPE_LEXER:\r
292 \r
293                 lexer   = (pANTLR3_LEXER) (recognizer->super);\r
294                 ins     = lexer->input;\r
295                 is      = ins->istream;\r
296 \r
297                 break;\r
298 \r
299         case    ANTLR3_TYPE_PARSER:\r
300 \r
301                 parser  = (pANTLR3_PARSER) (recognizer->super);\r
302                 cts     = (pANTLR3_COMMON_TOKEN_STREAM)(parser->tstream->super);\r
303                 is      = parser->tstream->istream;\r
304 \r
305                 break;\r
306 \r
307         case    ANTLR3_TYPE_TREE_PARSER:\r
308 \r
309                 tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
310                 tns     = tparser->ctnstream->tnstream;\r
311                 is      = tns->istream;\r
312 \r
313                 break;\r
314 \r
315         default:\r
316 \r
317                 ANTLR3_FPRINTF(stderr, "Base recognizer function antlr3RecognitionExceptionNew called by unknown parser type - provide override for this function\n");\r
318                 return;\r
319 \r
320                 break;\r
321         }\r
322 \r
323         /* Create a basic exception structure\r
324          */\r
325         ex = antlr3ExceptionNew(ANTLR3_RECOGNITION_EXCEPTION,\r
326                 (void *)ANTLR3_RECOGNITION_EX_NAME,\r
327                 NULL,\r
328                 ANTLR3_FALSE);\r
329 \r
330         /* Rest of information depends on the base type of the \r
331          * input stream.\r
332          */\r
333         switch  (is->type & ANTLR3_INPUT_MASK)\r
334         {\r
335         case    ANTLR3_CHARSTREAM:\r
336 \r
337                 ex->c                   = is->_LA                       (is, 1);                                        /* Current input character                      */\r
338                 ex->line                = ins->getLine                  (ins);                                          /* Line number comes from stream                */\r
339                 ex->charPositionInLine  = ins->getCharPositionInLine    (ins);      /* Line offset also comes from the stream   */\r
340                 ex->index               = is->index                     (is);\r
341                 ex->streamName          = ins->fileName;\r
342                 ex->message             = "Unexpected character";\r
343                 break;\r
344 \r
345         case    ANTLR3_TOKENSTREAM:\r
346 \r
347                 ex->token               = cts->tstream->_LT                                             (cts->tstream, 1);          /* Current input token                          */\r
348                 ex->line                = ((pANTLR3_COMMON_TOKEN)(ex->token))->getLine                  (ex->token);\r
349                 ex->charPositionInLine  = ((pANTLR3_COMMON_TOKEN)(ex->token))->getCharPositionInLine    (ex->token);\r
350                 ex->index               = cts->tstream->istream->index                                  (cts->tstream->istream);\r
351                 if      (((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)\r
352                 {\r
353                         ex->streamName          = NULL;\r
354                 }\r
355                 else\r
356                 {\r
357                         ex->streamName          = ((pANTLR3_COMMON_TOKEN)(ex->token))->input->fileName;\r
358                 }\r
359                 ex->message             = "Unexpected token";\r
360                 break;\r
361 \r
362         case    ANTLR3_COMMONTREENODE:\r
363 \r
364                 ex->token               = tns->_LT                                                  (tns, 1);       /* Current input tree node                      */\r
365                 ex->line                = ((pANTLR3_BASE_TREE)(ex->token))->getLine                 (ex->token);\r
366                 ex->charPositionInLine  = ((pANTLR3_BASE_TREE)(ex->token))->getCharPositionInLine   (ex->token);\r
367                 ex->index               = tns->istream->index                                       (tns->istream);\r
368 \r
369                 // Are you ready for this? Deep breath now...\r
370                 //\r
371                 {\r
372                         pANTLR3_COMMON_TREE tnode;\r
373 \r
374                         tnode           = ((pANTLR3_COMMON_TREE)(((pANTLR3_BASE_TREE)(ex->token))->super));\r
375 \r
376                         if      (tnode->token    == NULL)\r
377                         {\r
378                                 ex->streamName = ((pANTLR3_BASE_TREE)(ex->token))->strFactory->newStr(((pANTLR3_BASE_TREE)(ex->token))->strFactory, (pANTLR3_UINT8)"-unknown source-");\r
379                         }\r
380                         else\r
381                         {\r
382                                 if      (tnode->token->input == NULL)\r
383                                 {\r
384                                         ex->streamName          = NULL;\r
385                                 }\r
386                                 else\r
387                                 {\r
388                                         ex->streamName          = tnode->token->input->fileName;\r
389                                 }\r
390                         }\r
391                         ex->message             = "Unexpected node";\r
392                 }\r
393                 break;\r
394         }\r
395 \r
396         ex->input                                               = is;\r
397         ex->nextException                               = recognizer->state->exception; /* So we don't leak the memory */\r
398         recognizer->state->exception    = ex;\r
399         recognizer->state->error            = ANTLR3_TRUE;          /* Exception is outstanding */\r
400 \r
401         return;\r
402 }\r
403 \r
404 \r
405 /// Match current input symbol against ttype.  Upon error, do one token\r
406 /// insertion or deletion if possible.  \r
407 /// To turn off single token insertion or deletion error\r
408 /// recovery, override mismatchRecover() and have it call\r
409 /// plain mismatch(), which does not recover.  Then any error\r
410 /// in a rule will cause an exception and immediate exit from\r
411 /// rule.  Rule would recover by resynchronizing to the set of\r
412 /// symbols that can follow rule ref.\r
413 ///\r
414 static void *\r
415 match(  pANTLR3_BASE_RECOGNIZER recognizer,\r
416                 ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)\r
417 {\r
418     pANTLR3_PARSER                      parser;\r
419     pANTLR3_TREE_PARSER     tparser;\r
420     pANTLR3_INT_STREAM      is;\r
421         void                                    * matchedSymbol;\r
422 \r
423     switch      (recognizer->type)\r
424     {\r
425                 case    ANTLR3_TYPE_PARSER:\r
426 \r
427                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
428                         tparser = NULL;\r
429                         is      = parser->tstream->istream;\r
430 \r
431                         break;\r
432 \r
433                 case    ANTLR3_TYPE_TREE_PARSER:\r
434 \r
435                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
436                         parser  = NULL;\r
437                         is      = tparser->ctnstream->tnstream->istream;\r
438 \r
439                         break;\r
440 \r
441                 default:\r
442                     \r
443                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'match' called by unknown parser type - provide override for this function\n");\r
444                         return ANTLR3_FALSE;\r
445 \r
446                         break;\r
447     }\r
448 \r
449         // Pick up the current input token/node for assignment to labels\r
450         //\r
451         matchedSymbol = recognizer->getCurrentInputSymbol(recognizer, is);\r
452 \r
453     if  (is->_LA(is, 1) == ttype)\r
454     {\r
455                 // The token was the one we were told to expect\r
456                 //\r
457                 is->consume(is);                                                                        // Consume that token from the stream\r
458                 recognizer->state->errorRecovery        = ANTLR3_FALSE; // Not in error recovery now (if we were)\r
459                 recognizer->state->failed                       = ANTLR3_FALSE; // The match was a success\r
460                 return matchedSymbol;                                                           // We are done\r
461     }\r
462 \r
463     // We did not find the expected token type, if we are backtracking then\r
464     // we just set the failed flag and return.\r
465     //\r
466     if  (recognizer->state->backtracking > 0)\r
467     {\r
468                 // Backtracking is going on\r
469                 //\r
470                 recognizer->state->failed  = ANTLR3_TRUE;\r
471                 return matchedSymbol;\r
472         }\r
473 \r
474     // We did not find the expected token and there is no backtracking\r
475     // going on, so we mismatch, which creates an exception in the recognizer exception\r
476     // stack.\r
477     //\r
478         matchedSymbol = recognizer->recoverFromMismatchedToken(recognizer, ttype, follow);\r
479     return matchedSymbol;\r
480 }\r
481 \r
482 /// Consumes the next token, whatever it is, and resets the recognizer state\r
483 /// so that it is not in error.\r
484 ///\r
485 /// \param recognizer\r
486 /// Recognizer context pointer\r
487 ///\r
488 static void\r
489 matchAny(pANTLR3_BASE_RECOGNIZER recognizer)\r
490 {\r
491     pANTLR3_PARSER          parser;\r
492     pANTLR3_TREE_PARSER     tparser;\r
493     pANTLR3_INT_STREAM      is;\r
494 \r
495     switch      (recognizer->type)\r
496     {\r
497                 case    ANTLR3_TYPE_PARSER:\r
498 \r
499                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
500                         tparser = NULL;\r
501                         is      = parser->tstream->istream;\r
502 \r
503                         break;\r
504 \r
505                 case    ANTLR3_TYPE_TREE_PARSER:\r
506 \r
507                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
508                         parser  = NULL;\r
509                         is      = tparser->ctnstream->tnstream->istream;\r
510 \r
511                         break;\r
512 \r
513                 default:\r
514                     \r
515                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'matchAny' called by unknown parser type - provide override for this function\n");\r
516                         return;\r
517 \r
518                 break;\r
519     }\r
520     recognizer->state->errorRecovery    = ANTLR3_FALSE;\r
521     recognizer->state->failed               = ANTLR3_FALSE;\r
522     is->consume(is);\r
523 \r
524     return;\r
525 }\r
526 ///\r
527 ///\r
528 static ANTLR3_BOOLEAN\r
529 mismatchIsUnwantedToken(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, ANTLR3_UINT32 ttype)\r
530 {\r
531         ANTLR3_UINT32 nextt;\r
532 \r
533         nextt = is->_LA(is, 2);\r
534 \r
535         if      (nextt == ttype)\r
536         {\r
537                 if      (recognizer->state->exception != NULL)\r
538                 {\r
539                         recognizer->state->exception->expecting = nextt;\r
540                 }\r
541                 return ANTLR3_TRUE;             // This token is unknown, but the next one is the one we wanted\r
542         }\r
543         else\r
544         {\r
545                 return ANTLR3_FALSE;    // Neither this token, nor the one following is the one we wanted\r
546         }\r
547 }\r
548 \r
549 ///\r
550 ///\r
551 static ANTLR3_BOOLEAN\r
552 mismatchIsMissingToken(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_BITSET_LIST follow)\r
553 {\r
554         ANTLR3_BOOLEAN  retcode;\r
555         pANTLR3_BITSET  followClone;\r
556         pANTLR3_BITSET  viableTokensFollowingThisRule;\r
557 \r
558         if      (follow == NULL)\r
559         {\r
560                 // There is no information about the tokens that can follow the last one\r
561                 // hence we must say that the current one we found is not a member of the \r
562                 // follow set and does not indicate a missing token. We will just consume this\r
563                 // single token and see if the parser works it out from there.\r
564                 //\r
565                 return  ANTLR3_FALSE;\r
566         }\r
567 \r
568         followClone                                             = NULL;\r
569         viableTokensFollowingThisRule   = NULL;\r
570 \r
571         // The C bitset maps are laid down at compile time by the\r
572         // C code generation. Hence we cannot remove things from them\r
573         // and so on. So, in order to remove EOR (if we need to) then\r
574         // we clone the static bitset.\r
575         //\r
576         followClone = antlr3BitsetLoad(follow);\r
577         if      (followClone == NULL)\r
578         {\r
579                 return ANTLR3_FALSE;\r
580         }\r
581 \r
582         // Compute what can follow this grammar reference\r
583         //\r
584         if      (followClone->isMember(followClone, ANTLR3_EOR_TOKEN_TYPE))\r
585         {\r
586                 // EOR can follow, but if we are not the start symbol, we\r
587                 // need to remove it.\r
588                 //\r
589                 if      (recognizer->state->following->vector->count >= 0)\r
590                 {\r
591                         followClone->remove(followClone, ANTLR3_EOR_TOKEN_TYPE);\r
592                 }\r
593 \r
594                 // Now compute the visiable tokens that can follow this rule, according to context\r
595                 // and make them part of the follow set.\r
596                 //\r
597                 viableTokensFollowingThisRule = recognizer->computeCSRuleFollow(recognizer);\r
598                 followClone->borInPlace(followClone, viableTokensFollowingThisRule);\r
599         }\r
600 \r
601         /// if current token is consistent with what could come after set\r
602         /// then we know we're missing a token; error recovery is free to\r
603         /// "insert" the missing token\r
604         ///\r
605         /// BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR\r
606         /// in follow set to indicate that the fall of the start symbol is\r
607         /// in the set (EOF can follow).\r
608         ///\r
609         if      (               followClone->isMember(followClone, is->_LA(is, 1))\r
610                         ||      followClone->isMember(followClone, ANTLR3_EOR_TOKEN_TYPE)\r
611                 )\r
612         {\r
613                 retcode = ANTLR3_TRUE;\r
614         }\r
615         else\r
616         {\r
617                 retcode = ANTLR3_FALSE;\r
618         }\r
619 \r
620         if      (viableTokensFollowingThisRule != NULL)\r
621         {\r
622                 viableTokensFollowingThisRule->free(viableTokensFollowingThisRule);\r
623         }\r
624         if      (followClone != NULL)\r
625         {\r
626                 followClone->free(followClone);\r
627         }\r
628 \r
629         return retcode;\r
630 \r
631 }\r
632 \r
633 /// Factor out what to do upon token mismatch so tree parsers can behave\r
634 /// differently.  Override and call mismatchRecover(input, ttype, follow)\r
635 /// to get single token insertion and deletion.  Use this to turn off\r
636 /// single token insertion and deletion. Override mismatchRecover\r
637 /// to call this instead.\r
638 ///\r
639 /// \remark mismatch only works for parsers and must be overridden for anything else.\r
640 ///\r
641 static  void\r
642 mismatch(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)\r
643 {\r
644     pANTLR3_PARSER          parser;\r
645     pANTLR3_TREE_PARSER     tparser;\r
646     pANTLR3_INT_STREAM      is;\r
647 \r
648     // Install a mismatched token exception in the exception stack\r
649     //\r
650     antlr3MTExceptionNew(recognizer);\r
651     recognizer->state->exception->expecting    = ttype;\r
652 \r
653     switch      (recognizer->type)\r
654     {\r
655                 case    ANTLR3_TYPE_PARSER:\r
656 \r
657                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
658                         tparser = NULL;\r
659                         is      = parser->tstream->istream;\r
660 \r
661                         break;\r
662 \r
663                 default:\r
664                     \r
665                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'mismatch' called by unknown parser type - provide override for this function\n");\r
666                         return;\r
667 \r
668                         break;\r
669     }\r
670 \r
671         if      (mismatchIsUnwantedToken(recognizer, is, ttype))\r
672         {\r
673                 // Create a basic recognition exception structure\r
674                 //\r
675             antlr3RecognitionExceptionNew(recognizer);\r
676                 \r
677                 // Now update it to indicate this is an unwanted token exception\r
678                 //\r
679                 recognizer->state->exception->name              = ANTLR3_UNWANTED_TOKEN_EXCEPTION_NAME;\r
680                 recognizer->state->exception->type              = ANTLR3_UNWANTED_TOKEN_EXCEPTION;\r
681 \r
682                 return;\r
683         }\r
684         \r
685         if      (mismatchIsMissingToken(recognizer, is, follow))\r
686         {\r
687                 // Create a basic recognition exception structure\r
688                 //\r
689             antlr3RecognitionExceptionNew(recognizer);\r
690                 \r
691                 // Now update it to indicate this is an unwanted token exception\r
692                 //\r
693                 recognizer->state->exception->name              = ANTLR3_MISSING_TOKEN_EXCEPTION_NAME;\r
694                 recognizer->state->exception->type              = ANTLR3_MISSING_TOKEN_EXCEPTION;\r
695 \r
696                 return;\r
697         }\r
698 \r
699         // Just a mismatched token is all we can dtermine\r
700         //\r
701         antlr3MTExceptionNew(recognizer);\r
702 \r
703         return;\r
704 }\r
705 /// Report a recognition problem.\r
706 ///\r
707 /// This method sets errorRecovery to indicate the parser is recovering\r
708 /// not parsing.  Once in recovery mode, no errors are generated.\r
709 /// To get out of recovery mode, the parser must successfully match\r
710 /// a token (after a resync).  So it will go:\r
711 ///\r
712 ///             1. error occurs\r
713 ///             2. enter recovery mode, report error\r
714 ///             3. consume until token found in resynch set\r
715 ///             4. try to resume parsing\r
716 ///             5. next match() will reset errorRecovery mode\r
717 ///\r
718 /// If you override, make sure to update errorCount if you care about that.\r
719 ///\r
720 static void                     \r
721 reportError                 (pANTLR3_BASE_RECOGNIZER recognizer)\r
722 {\r
723     if  (recognizer->state->errorRecovery == ANTLR3_TRUE)\r
724     {\r
725                 // Already in error recovery so don't display another error while doing so\r
726                 //\r
727                 return;\r
728     }\r
729 \r
730     // Signal we are in error recovery now\r
731     //\r
732     recognizer->state->errorRecovery = ANTLR3_TRUE;\r
733         \r
734         // Indicate this recognizer had an error while processing.\r
735         //\r
736         recognizer->state->errorCount++;\r
737 \r
738         // Call the error display routine\r
739         //\r
740     recognizer->displayRecognitionError(recognizer, recognizer->state->tokenNames);\r
741 }\r
742 \r
743 static void\r
744 beginBacktrack          (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level)\r
745 {\r
746         if      (recognizer->debugger != NULL)\r
747         {\r
748                 recognizer->debugger->beginBacktrack(recognizer->debugger, level);\r
749         }\r
750 }\r
751 \r
752 static void\r
753 endBacktrack            (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 level, ANTLR3_BOOLEAN successful)\r
754 {\r
755         if      (recognizer->debugger != NULL)\r
756         {\r
757                 recognizer->debugger->endBacktrack(recognizer->debugger, level, successful);\r
758         }\r
759 }\r
760 static void                     \r
761 beginResync                 (pANTLR3_BASE_RECOGNIZER recognizer)\r
762 {\r
763         if      (recognizer->debugger != NULL)\r
764         {\r
765                 recognizer->debugger->beginResync(recognizer->debugger);\r
766         }\r
767 }\r
768 \r
769 static void                     \r
770 endResync                   (pANTLR3_BASE_RECOGNIZER recognizer)\r
771 {\r
772         if      (recognizer->debugger != NULL)\r
773         {\r
774                 recognizer->debugger->endResync(recognizer->debugger);\r
775         }\r
776 }\r
777 \r
778 /// Compute the error recovery set for the current rule.\r
779 /// Documentation below is from the Java implementation.\r
780 ///\r
781 /// During rule invocation, the parser pushes the set of tokens that can\r
782 /// follow that rule reference on the stack; this amounts to\r
783 /// computing FIRST of what follows the rule reference in the\r
784 /// enclosing rule. This local follow set only includes tokens\r
785 /// from within the rule; i.e., the FIRST computation done by\r
786 /// ANTLR stops at the end of a rule.\r
787 //\r
788 /// EXAMPLE\r
789 //\r
790 /// When you find a "no viable alt exception", the input is not\r
791 /// consistent with any of the alternatives for rule r.  The best\r
792 /// thing to do is to consume tokens until you see something that\r
793 /// can legally follow a call to r *or* any rule that called r.\r
794 /// You don't want the exact set of viable next tokens because the\r
795 /// input might just be missing a token--you might consume the\r
796 /// rest of the input looking for one of the missing tokens.\r
797 ///\r
798 /// Consider grammar:\r
799 ///\r
800 /// a : '[' b ']'\r
801 ///   | '(' b ')'\r
802 ///   ;\r
803 /// b : c '^' INT ;\r
804 /// c : ID\r
805 ///   | INT\r
806 ///   ;\r
807 ///\r
808 /// At each rule invocation, the set of tokens that could follow\r
809 /// that rule is pushed on a stack.  Here are the various "local"\r
810 /// follow sets:\r
811 ///\r
812 /// FOLLOW(b1_in_a) = FIRST(']') = ']'\r
813 /// FOLLOW(b2_in_a) = FIRST(')') = ')'\r
814 /// FOLLOW(c_in_b) = FIRST('^') = '^'\r
815 ///\r
816 /// Upon erroneous input "[]", the call chain is\r
817 ///\r
818 /// a -> b -> c\r
819 ///\r
820 /// and, hence, the follow context stack is:\r
821 ///\r
822 /// depth  local follow set     after call to rule\r
823 ///   0         <EOF>                    a (from main())\r
824 ///   1          ']'                     b\r
825 ///   3          '^'                     c\r
826 ///\r
827 /// Notice that ')' is not included, because b would have to have\r
828 /// been called from a different context in rule a for ')' to be\r
829 /// included.\r
830 ///\r
831 /// For error recovery, we cannot consider FOLLOW(c)\r
832 /// (context-sensitive or otherwise).  We need the combined set of\r
833 /// all context-sensitive FOLLOW sets--the set of all tokens that\r
834 /// could follow any reference in the call chain.  We need to\r
835 /// resync to one of those tokens.  Note that FOLLOW(c)='^' and if\r
836 /// we resync'd to that token, we'd consume until EOF.  We need to\r
837 /// sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.\r
838 /// In this case, for input "[]", LA(1) is in this set so we would\r
839 /// not consume anything and after printing an error rule c would\r
840 /// return normally.  It would not find the required '^' though.\r
841 /// At this point, it gets a mismatched token error and throws an\r
842 /// exception (since LA(1) is not in the viable following token\r
843 /// set).  The rule exception handler tries to recover, but finds\r
844 /// the same recovery set and doesn't consume anything.  Rule b\r
845 /// exits normally returning to rule a.  Now it finds the ']' (and\r
846 /// with the successful match exits errorRecovery mode).\r
847 ///\r
848 /// So, you can see that the parser walks up call chain looking\r
849 /// for the token that was a member of the recovery set.\r
850 ///\r
851 /// Errors are not generated in errorRecovery mode.\r
852 ///\r
853 /// ANTLR's error recovery mechanism is based upon original ideas:\r
854 ///\r
855 /// "Algorithms + Data Structures = Programs" by Niklaus Wirth\r
856 ///\r
857 /// and\r
858 ///\r
859 /// "A note on error recovery in recursive descent parsers":\r
860 /// http://portal.acm.org/citation.cfm?id=947902.947905\r
861 ///\r
862 /// Later, Josef Grosch had some good ideas:\r
863 ///\r
864 /// "Efficient and Comfortable Error Recovery in Recursive Descent\r
865 /// Parsers":\r
866 /// ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip\r
867 ///\r
868 /// Like Grosch I implemented local FOLLOW sets that are combined\r
869 /// at run-time upon error to avoid overhead during parsing.\r
870 ///\r
871 static pANTLR3_BITSET           \r
872 computeErrorRecoverySet     (pANTLR3_BASE_RECOGNIZER recognizer)\r
873 {\r
874     return   recognizer->combineFollows(recognizer, ANTLR3_FALSE);\r
875 }\r
876 \r
877 /// Compute the context-sensitive FOLLOW set for current rule.\r
878 /// Documentation below is from the Java runtime.\r
879 ///\r
880 /// This is the set of token types that can follow a specific rule\r
881 /// reference given a specific call chain.  You get the set of\r
882 /// viable tokens that can possibly come next (look ahead depth 1)\r
883 /// given the current call chain.  Contrast this with the\r
884 /// definition of plain FOLLOW for rule r:\r
885 ///\r
886 ///  FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}\r
887 ///\r
888 /// where x in T* and alpha, beta in V*; T is set of terminals and\r
889 /// V is the set of terminals and non terminals.  In other words,\r
890 /// FOLLOW(r) is the set of all tokens that can possibly follow\r
891 /// references to r in///any* sentential form (context).  At\r
892 /// runtime, however, we know precisely which context applies as\r
893 /// we have the call chain.  We may compute the exact (rather\r
894 /// than covering superset) set of following tokens.\r
895 ///\r
896 /// For example, consider grammar:\r
897 ///\r
898 /// stat : ID '=' expr ';'      // FOLLOW(stat)=={EOF}\r
899 ///      | "return" expr '.'\r
900 ///      ;\r
901 /// expr : atom ('+' atom)* ;   // FOLLOW(expr)=={';','.',')'}\r
902 /// atom : INT                  // FOLLOW(atom)=={'+',')',';','.'}\r
903 ///      | '(' expr ')'\r
904 ///      ;\r
905 ///\r
906 /// The FOLLOW sets are all inclusive whereas context-sensitive\r
907 /// FOLLOW sets are precisely what could follow a rule reference.\r
908 /// For input input "i=(3);", here is the derivation:\r
909 ///\r
910 /// stat => ID '=' expr ';'\r
911 ///      => ID '=' atom ('+' atom)* ';'\r
912 ///      => ID '=' '(' expr ')' ('+' atom)* ';'\r
913 ///      => ID '=' '(' atom ')' ('+' atom)* ';'\r
914 ///      => ID '=' '(' INT ')' ('+' atom)* ';'\r
915 ///      => ID '=' '(' INT ')' ';'\r
916 ///\r
917 /// At the "3" token, you'd have a call chain of\r
918 ///\r
919 ///   stat -> expr -> atom -> expr -> atom\r
920 ///\r
921 /// What can follow that specific nested ref to atom?  Exactly ')'\r
922 /// as you can see by looking at the derivation of this specific\r
923 /// input.  Contrast this with the FOLLOW(atom)={'+',')',';','.'}.\r
924 ///\r
925 /// You want the exact viable token set when recovering from a\r
926 /// token mismatch.  Upon token mismatch, if LA(1) is member of\r
927 /// the viable next token set, then you know there is most likely\r
928 /// a missing token in the input stream.  "Insert" one by just not\r
929 /// throwing an exception.\r
930 ///\r
931 static pANTLR3_BITSET           \r
932 computeCSRuleFollow         (pANTLR3_BASE_RECOGNIZER recognizer)\r
933 {\r
934     return   recognizer->combineFollows(recognizer, ANTLR3_FALSE);\r
935 }\r
936 \r
937 /// Compute the current followset for the input stream.\r
938 ///\r
939 static pANTLR3_BITSET           \r
940 combineFollows              (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_BOOLEAN exact)\r
941 {\r
942     pANTLR3_BITSET      followSet;\r
943     pANTLR3_BITSET      localFollowSet;\r
944     ANTLR3_UINT32       top;\r
945     ANTLR3_UINT32       i;\r
946 \r
947     top = recognizer->state->following->size(recognizer->state->following);\r
948 \r
949     followSet       = antlr3BitsetNew(0);\r
950         localFollowSet  = NULL;\r
951 \r
952     for (i = top; i>0; i--)\r
953     {\r
954                 localFollowSet = antlr3BitsetLoad((pANTLR3_BITSET_LIST) recognizer->state->following->get(recognizer->state->following, i-1));\r
955 \r
956                 if  (localFollowSet != NULL)\r
957                 {\r
958                         followSet->borInPlace(followSet, localFollowSet);\r
959 \r
960                         if      (exact == ANTLR3_TRUE)\r
961                         {\r
962                                 if      (localFollowSet->isMember(localFollowSet, ANTLR3_EOR_TOKEN_TYPE) == ANTLR3_FALSE)\r
963                                 {\r
964                                         // Only leave EOR in the set if at top (start rule); this lets us know\r
965                                         // if we have to include the follow(start rule); I.E., EOF\r
966                                         //\r
967                                         if      (i>1)\r
968                                         {\r
969                                                 followSet->remove(followSet, ANTLR3_EOR_TOKEN_TYPE);\r
970                                         }\r
971                                 }\r
972                                 else\r
973                                 {\r
974                                         break;  // Cannot see End Of Rule from here, just drop out\r
975                                 }\r
976                         }\r
977                         localFollowSet->free(localFollowSet);\r
978                         localFollowSet = NULL;\r
979                 }\r
980     }\r
981 \r
982         if      (localFollowSet != NULL)\r
983         {\r
984                 localFollowSet->free(localFollowSet);\r
985         }\r
986     return  followSet;\r
987 }\r
988 \r
989 /// Standard/Example error display method.\r
990 /// No generic error message display funciton coudl possibly do everything correctly\r
991 /// for all possible parsers. Hence you are provided with this example routine, which\r
992 /// you should override in your parser/tree parser to do as you will.\r
993 ///\r
994 /// Here we depart somewhat from the Java runtime as that has now split up a lot\r
995 /// of the error display routines into spearate units. However, ther is little advantage\r
996 /// to this in the C version as you will probably implement all such routines as a \r
997 /// separate translation unit, rather than install them all as pointers to functions\r
998 /// in the base recognizer.\r
999 ///\r
1000 static void                     \r
1001 displayRecognitionError     (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames)\r
1002 {\r
1003         pANTLR3_PARSER                  parser;\r
1004         pANTLR3_TREE_PARSER         tparser;\r
1005         pANTLR3_INT_STREAM          is;\r
1006         pANTLR3_STRING                  ttext;\r
1007         pANTLR3_STRING                  ftext;\r
1008         pANTLR3_EXCEPTION           ex;\r
1009         pANTLR3_COMMON_TOKEN    theToken;\r
1010         pANTLR3_BASE_TREE           theBaseTree;\r
1011         pANTLR3_COMMON_TREE         theCommonTree;\r
1012 \r
1013         // Retrieve some info for easy reading.\r
1014         //\r
1015         ex          =           recognizer->state->exception;\r
1016         ttext   =               NULL;\r
1017 \r
1018         // See if there is a 'filename' we can use\r
1019         //\r
1020         if      (ex->streamName == NULL)\r
1021         {\r
1022                 if      (((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)\r
1023                 {\r
1024                         ANTLR3_FPRINTF(stderr, "-end of input-(");\r
1025                 }\r
1026                 else\r
1027                 {\r
1028                         ANTLR3_FPRINTF(stderr, "-unknown source-(");\r
1029                 }\r
1030         }\r
1031         else\r
1032         {\r
1033                 ftext = ex->streamName->to8(ex->streamName);\r
1034                 ANTLR3_FPRINTF(stderr, "%s(", ftext->chars);\r
1035         }\r
1036 \r
1037         // Next comes the line number\r
1038         //\r
1039 \r
1040         ANTLR3_FPRINTF(stderr, "%d) ", recognizer->state->exception->line);\r
1041         ANTLR3_FPRINTF(stderr, " : error %d : %s", \r
1042                                                                                 recognizer->state->exception->type,\r
1043                                         (pANTLR3_UINT8)    (recognizer->state->exception->message));\r
1044 \r
1045 \r
1046         // How we determine the next piece is dependent on which thing raised the\r
1047         // error.\r
1048         //\r
1049         switch  (recognizer->type)\r
1050         {\r
1051         case    ANTLR3_TYPE_PARSER:\r
1052 \r
1053                 // Prepare the knowledge we know we have\r
1054                 //\r
1055                 parser      = (pANTLR3_PARSER) (recognizer->super);\r
1056                 tparser     = NULL;\r
1057                 is                      = parser->tstream->istream;\r
1058                 theToken    = (pANTLR3_COMMON_TOKEN)(recognizer->state->exception->token);\r
1059                 ttext       = theToken->toString(theToken);\r
1060 \r
1061                 ANTLR3_FPRINTF(stderr, ", at offset %d", recognizer->state->exception->charPositionInLine);\r
1062                 if  (theToken != NULL)\r
1063                 {\r
1064                         if (theToken->type == ANTLR3_TOKEN_EOF)\r
1065                         {\r
1066                                 ANTLR3_FPRINTF(stderr, ", at <EOF>");\r
1067                         }\r
1068                         else\r
1069                         {\r
1070                                 // Guard against null text in a token\r
1071                                 //\r
1072                                 ANTLR3_FPRINTF(stderr, "\n    near %s\n    ", ttext == NULL ? (pANTLR3_UINT8)"<no text for the token>" : ttext->chars);\r
1073                         }\r
1074                 }\r
1075                 break;\r
1076 \r
1077         case    ANTLR3_TYPE_TREE_PARSER:\r
1078 \r
1079                 tparser         = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1080                 parser          = NULL;\r
1081                 is                      = tparser->ctnstream->tnstream->istream;\r
1082                 theBaseTree     = (pANTLR3_BASE_TREE)(recognizer->state->exception->token);\r
1083                 ttext           = theBaseTree->toStringTree(theBaseTree);\r
1084 \r
1085                 if  (theBaseTree != NULL)\r
1086                 {\r
1087                         theCommonTree   = (pANTLR3_COMMON_TREE)     theBaseTree->super;\r
1088 \r
1089                         if      (theCommonTree != NULL)\r
1090                         {\r
1091                                 theToken        = (pANTLR3_COMMON_TOKEN)    theBaseTree->getToken(theBaseTree);\r
1092                         }\r
1093                         ANTLR3_FPRINTF(stderr, ", at offset %d", theBaseTree->getCharPositionInLine(theBaseTree));\r
1094                         ANTLR3_FPRINTF(stderr, ", near %s", ttext->chars);\r
1095                 }\r
1096                 break;\r
1097 \r
1098         default:\r
1099 \r
1100                 ANTLR3_FPRINTF(stderr, "Base recognizer function displayRecognitionError called by unknown parser type - provide override for this function\n");\r
1101                 return;\r
1102                 break;\r
1103         }\r
1104 \r
1105         // Although this function should generally be provided by the implementation, this one\r
1106         // should be as helpful as possible for grammar developers and serve as an example\r
1107         // of what you can do with each exception type. In general, when you make up your\r
1108         // 'real' handler, you should debug the routine with all possible errors you expect\r
1109         // which will then let you be as specific as possible about all circumstances.\r
1110         //\r
1111         // Note that in the general case, errors thrown by tree parsers indicate a problem\r
1112         // with the output of the parser or with the tree grammar itself. The job of the parser\r
1113         // is to produce a perfect (in traversal terms) syntactically correct tree, so errors\r
1114         // at that stage should really be semantic errors that your own code determines and handles\r
1115         // in whatever way is appropriate.\r
1116         //\r
1117         switch  (ex->type)\r
1118         {\r
1119         case    ANTLR3_UNWANTED_TOKEN_EXCEPTION:\r
1120 \r
1121                 // Indicates that the recognizer was fed a token which seesm to be\r
1122                 // spurious input. We can detect this when the token that follows\r
1123                 // this unwanted token would normally be part of the syntactically\r
1124                 // correct stream. Then we can see that the token we are looking at\r
1125                 // is just something that should not be there and throw this exception.\r
1126                 //\r
1127                 if      (tokenNames == NULL)\r
1128                 {\r
1129                         ANTLR3_FPRINTF(stderr, " : Extraneous input...");\r
1130                 }\r
1131                 else\r
1132                 {\r
1133                         if      (ex->expecting == ANTLR3_TOKEN_EOF)\r
1134                         {\r
1135                                 ANTLR3_FPRINTF(stderr, " : Extraneous input - expected <EOF>\n");\r
1136                         }\r
1137                         else\r
1138                         {\r
1139                                 ANTLR3_FPRINTF(stderr, " : Extraneous input - expected %s ...\n", tokenNames[ex->expecting]);\r
1140                         }\r
1141                 }\r
1142                 break;\r
1143 \r
1144         case    ANTLR3_MISSING_TOKEN_EXCEPTION:\r
1145 \r
1146                 // Indicates that the recognizer detected that the token we just\r
1147                 // hit would be valid syntactically if preceeded by a particular \r
1148                 // token. Perhaps a missing ';' at line end or a missing ',' in an\r
1149                 // expression list, and such like.\r
1150                 //\r
1151                 if      (tokenNames == NULL)\r
1152                 {\r
1153                         ANTLR3_FPRINTF(stderr, " : Missing token (%d)...\n", ex->expecting);\r
1154                 }\r
1155                 else\r
1156                 {\r
1157                         if      (ex->expecting == ANTLR3_TOKEN_EOF)\r
1158                         {\r
1159                                 ANTLR3_FPRINTF(stderr, " : Missing <EOF>\n");\r
1160                         }\r
1161                         else\r
1162                         {\r
1163                                 ANTLR3_FPRINTF(stderr, " : Missing %s \n", tokenNames[ex->expecting]);\r
1164                         }\r
1165                 }\r
1166                 break;\r
1167 \r
1168         case    ANTLR3_RECOGNITION_EXCEPTION:\r
1169 \r
1170                 // Indicates that the recognizer received a token\r
1171                 // in the input that was not predicted. This is the basic exception type \r
1172                 // from which all others are derived. So we assume it was a syntax error.\r
1173                 // You may get this if there are not more tokens and more are needed\r
1174                 // to complete a parse for instance.\r
1175                 //\r
1176                 ANTLR3_FPRINTF(stderr, " : syntax error...\n");    \r
1177                 break;\r
1178 \r
1179         case    ANTLR3_MISMATCHED_TOKEN_EXCEPTION:\r
1180 \r
1181                 // We were expecting to see one thing and got another. This is the\r
1182                 // most common error if we coudl not detect a missing or unwanted token.\r
1183                 // Here you can spend your efforts to\r
1184                 // derive more useful error messages based on the expected\r
1185                 // token set and the last token and so on. The error following\r
1186                 // bitmaps do a good job of reducing the set that we were looking\r
1187                 // for down to something small. Knowing what you are parsing may be\r
1188                 // able to allow you to be even more specific about an error.\r
1189                 //\r
1190                 if      (tokenNames == NULL)\r
1191                 {\r
1192                         ANTLR3_FPRINTF(stderr, " : syntax error...\n");\r
1193                 }\r
1194                 else\r
1195                 {\r
1196                         if      (ex->expecting == ANTLR3_TOKEN_EOF)\r
1197                         {\r
1198                                 ANTLR3_FPRINTF(stderr, " : expected <EOF>\n");\r
1199                         }\r
1200                         else\r
1201                         {\r
1202                                 ANTLR3_FPRINTF(stderr, " : expected %s ...\n", tokenNames[ex->expecting]);\r
1203                         }\r
1204                 }\r
1205                 break;\r
1206 \r
1207         case    ANTLR3_NO_VIABLE_ALT_EXCEPTION:\r
1208 \r
1209                 // We could not pick any alt decision from the input given\r
1210                 // so god knows what happened - however when you examine your grammar,\r
1211                 // you should. It means that at the point where the current token occurred\r
1212                 // that the DFA indicates nowhere to go from here.\r
1213                 //\r
1214                 ANTLR3_FPRINTF(stderr, " : cannot match to any predicted input...\n");\r
1215 \r
1216                 break;\r
1217 \r
1218         case    ANTLR3_MISMATCHED_SET_EXCEPTION:\r
1219 \r
1220                 {\r
1221                         ANTLR3_UINT32     count;\r
1222                         ANTLR3_UINT32     bit;\r
1223                         ANTLR3_UINT32     size;\r
1224                         ANTLR3_UINT32     numbits;\r
1225                         pANTLR3_BITSET    errBits;\r
1226 \r
1227                         // This means we were able to deal with one of a set of\r
1228                         // possible tokens at this point, but we did not see any\r
1229                         // member of that set.\r
1230                         //\r
1231                         ANTLR3_FPRINTF(stderr, " : unexpected input...\n  expected one of : ");\r
1232 \r
1233                         // What tokens could we have accepted at this point in the\r
1234                         // parse?\r
1235                         //\r
1236                         count   = 0;\r
1237                         errBits = antlr3BitsetLoad              (ex->expectingSet);\r
1238                         numbits = errBits->numBits              (errBits);\r
1239                         size    = errBits->size                 (errBits);\r
1240 \r
1241                         if  (size > 0)\r
1242                         {\r
1243                                 // However many tokens we could have dealt with here, it is usually\r
1244                                 // not useful to print ALL of the set here. I arbitrarily chose 8\r
1245                                 // here, but you should do whatever makes sense for you of course.\r
1246                                 // No token number 0, so look for bit 1 and on.\r
1247                                 //\r
1248                                 for     (bit = 1; bit < numbits && count < 8 && count < size; bit++)\r
1249                                 {\r
1250                                         // TODO: This doesn;t look right - should be asking if the bit is set!!\r
1251                                         //\r
1252                                         if  (tokenNames[bit])\r
1253                                         {\r
1254                                                 ANTLR3_FPRINTF(stderr, "%s%s", count > 0 ? ", " : "", tokenNames[bit]); \r
1255                                                 count++;\r
1256                                         }\r
1257                                 }\r
1258                                 ANTLR3_FPRINTF(stderr, "\n");\r
1259                         }\r
1260                         else\r
1261                         {\r
1262                                 ANTLR3_FPRINTF(stderr, "Actually dude, we didn't seem to be expecting anything here, or at least\n");\r
1263                                 ANTLR3_FPRINTF(stderr, "I could not work out what I was expecting, like so many of us these days!\n");\r
1264                         }\r
1265                 }\r
1266                 break;\r
1267 \r
1268         case    ANTLR3_EARLY_EXIT_EXCEPTION:\r
1269 \r
1270                 // We entered a loop requiring a number of token sequences\r
1271                 // but found a token that ended that sequence earlier than\r
1272                 // we should have done.\r
1273                 //\r
1274                 ANTLR3_FPRINTF(stderr, " : missing elements...\n");\r
1275                 break;\r
1276 \r
1277         default:\r
1278 \r
1279                 // We don't handle any other exceptions here, but you can\r
1280                 // if you wish. If we get an exception that hits this point\r
1281                 // then we are just going to report what we know about the\r
1282                 // token.\r
1283                 //\r
1284                 ANTLR3_FPRINTF(stderr, " : syntax not recognized...\n");\r
1285                 break;\r
1286         }\r
1287 \r
1288         // Here you have the token that was in error which if this is\r
1289         // the standard implementation will tell you the line and offset\r
1290         // and also record the address of the start of the line in the\r
1291         // input stream. You could therefore print the source line and so on.\r
1292         // Generally though, I would expect that your lexer/parser will keep\r
1293         // its own map of lines and source pointers or whatever as there\r
1294         // are a lot of specific things you need to know about the input\r
1295         // to do something like that.\r
1296         // Here is where you do it though :-).\r
1297         //\r
1298 }\r
1299 \r
1300 /// Return how many syntax errors were detected by this recognizer\r
1301 ///\r
1302 static ANTLR3_UINT32\r
1303 getNumberOfSyntaxErrors(pANTLR3_BASE_RECOGNIZER recognizer)\r
1304 {\r
1305         return  recognizer->state->errorCount;\r
1306 }\r
1307 \r
1308 /// Recover from an error found on the input stream.  Mostly this is\r
1309 /// NoViableAlt exceptions, but could be a mismatched token that\r
1310 /// the match() routine could not recover from.\r
1311 ///\r
1312 static void                     \r
1313 recover                     (pANTLR3_BASE_RECOGNIZER recognizer)\r
1314 {\r
1315     // Used to compute the follow set of tokens\r
1316     //\r
1317     pANTLR3_BITSET                      followSet;\r
1318     pANTLR3_PARSER                      parser;\r
1319     pANTLR3_TREE_PARSER     tparser;\r
1320     pANTLR3_INT_STREAM      is;\r
1321 \r
1322     switch      (recognizer->type)\r
1323     {\r
1324                 case    ANTLR3_TYPE_PARSER:\r
1325 \r
1326                 parser  = (pANTLR3_PARSER) (recognizer->super);\r
1327                 tparser = NULL;\r
1328                 is              = parser->tstream->istream;\r
1329 \r
1330         break;\r
1331 \r
1332     case        ANTLR3_TYPE_TREE_PARSER:\r
1333 \r
1334                 tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1335                 parser  = NULL;\r
1336                 is              = tparser->ctnstream->tnstream->istream;\r
1337 \r
1338         break;\r
1339 \r
1340     default:\r
1341             \r
1342                 ANTLR3_FPRINTF(stderr, "Base recognizer function recover called by unknown parser type - provide override for this function\n");\r
1343                 return;\r
1344 \r
1345         break;\r
1346     }\r
1347 \r
1348         // Are we about to repeat the same error?\r
1349         //\r
1350     if  (recognizer->state->lastErrorIndex == is->index(is))\r
1351     {\r
1352                 // The last error was at the same token index point. This must be a case\r
1353                 // where LT(1) is in the recovery token set so nothing is\r
1354                 // consumed. Consume a single token so at least to prevent\r
1355                 // an infinite loop; this is a failsafe.\r
1356                 //\r
1357                 is->consume(is);\r
1358     }\r
1359 \r
1360     // Record error index position\r
1361     //\r
1362     recognizer->state->lastErrorIndex    = is->index(is);\r
1363     \r
1364     // Work out the follows set for error recovery\r
1365     //\r
1366     followSet   = recognizer->computeErrorRecoverySet(recognizer);\r
1367 \r
1368     // Call resync hook (for debuggers and so on)\r
1369     //\r
1370     recognizer->beginResync(recognizer);\r
1371 \r
1372     // Consume tokens until we have resynced to something in the follows set\r
1373     //\r
1374     recognizer->consumeUntilSet(recognizer, followSet);\r
1375 \r
1376     // End resync hook \r
1377     //\r
1378     recognizer->endResync(recognizer);\r
1379 \r
1380     // Destroy the temporary bitset we produced.\r
1381     //\r
1382     followSet->free(followSet);\r
1383 \r
1384     // Reset the inError flag so we don't re-report the exception\r
1385     //\r
1386     recognizer->state->error    = ANTLR3_FALSE;\r
1387     recognizer->state->failed   = ANTLR3_FALSE;\r
1388 }\r
1389 \r
1390 \r
1391 /// Attempt to recover from a single missing or extra token.\r
1392 ///\r
1393 /// EXTRA TOKEN\r
1394 ///\r
1395 /// LA(1) is not what we are looking for.  If LA(2) has the right token,\r
1396 /// however, then assume LA(1) is some extra spurious token.  Delete it\r
1397 /// and LA(2) as if we were doing a normal match(), which advances the\r
1398 /// input.\r
1399 ///\r
1400 /// MISSING TOKEN\r
1401 ///\r
1402 /// If current token is consistent with what could come after\r
1403 /// ttype then it is ok to "insert" the missing token, else throw\r
1404 /// exception For example, Input "i=(3;" is clearly missing the\r
1405 /// ')'.  When the parser returns from the nested call to expr, it\r
1406 /// will have call chain:\r
1407 ///\r
1408 ///    stat -> expr -> atom\r
1409 ///\r
1410 /// and it will be trying to match the ')' at this point in the\r
1411 /// derivation:\r
1412 ///\r
1413 ///       => ID '=' '(' INT ')' ('+' atom)* ';'\r
1414 ///                          ^\r
1415 /// match() will see that ';' doesn't match ')' and report a\r
1416 /// mismatched token error.  To recover, it sees that LA(1)==';'\r
1417 /// is in the set of tokens that can follow the ')' token\r
1418 /// reference in rule atom.  It can assume that you forgot the ')'.\r
1419 ///\r
1420 /// The exception that was passed in, in the java implementation is\r
1421 /// sorted in the recognizer exception stack in the C version. To 'throw' it we set the\r
1422 /// error flag and rules cascade back when this is set.\r
1423 ///\r
1424 static void *   \r
1425 recoverFromMismatchedToken  (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)\r
1426 {\r
1427         pANTLR3_PARSER                    parser;\r
1428         pANTLR3_TREE_PARSER           tparser;\r
1429         pANTLR3_INT_STREAM            is;\r
1430         void                                    * matchedSymbol;\r
1431 \r
1432         // Invoke the debugger event if there is a debugger listening to us\r
1433         //\r
1434         if      (recognizer->debugger != NULL)\r
1435         {\r
1436                 recognizer->debugger->recognitionException(recognizer->debugger, recognizer->state->exception);\r
1437         }\r
1438 \r
1439         switch  (recognizer->type)\r
1440         {\r
1441         case    ANTLR3_TYPE_PARSER:\r
1442 \r
1443                 parser  = (pANTLR3_PARSER) (recognizer->super);\r
1444                 tparser = NULL;\r
1445                 is      = parser->tstream->istream;\r
1446 \r
1447                 break;\r
1448 \r
1449         case    ANTLR3_TYPE_TREE_PARSER:\r
1450 \r
1451                 tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1452                 parser  = NULL;\r
1453                 is      = tparser->ctnstream->tnstream->istream;\r
1454 \r
1455                 break;\r
1456 \r
1457         default:\r
1458 \r
1459                 ANTLR3_FPRINTF(stderr, "Base recognizer function recoverFromMismatchedToken called by unknown parser type - provide override for this function\n");\r
1460                 return NULL;\r
1461 \r
1462                 break;\r
1463         }\r
1464 \r
1465         // Create an exception if we need one\r
1466         //\r
1467         if      (recognizer->state->exception == NULL)\r
1468         {\r
1469                 antlr3RecognitionExceptionNew(recognizer);\r
1470         }\r
1471 \r
1472         // If the next token after the one we are looking at in the input stream\r
1473         // is what we are looking for then we remove the one we have discovered\r
1474         // from the stream by consuming it, then consume this next one along too as\r
1475         // if nothing had happened.\r
1476         //\r
1477         if      ( recognizer->mismatchIsUnwantedToken(recognizer, is, ttype) == ANTLR3_TRUE)\r
1478         {\r
1479                 recognizer->state->exception->type              = ANTLR3_UNWANTED_TOKEN_EXCEPTION;\r
1480                 recognizer->state->exception->message   = ANTLR3_UNWANTED_TOKEN_EXCEPTION_NAME;\r
1481 \r
1482                 // Call resync hook (for debuggers and so on)\r
1483                 //\r
1484                 if      (recognizer->debugger != NULL)\r
1485                 {\r
1486                         recognizer->debugger->beginResync(recognizer->debugger);\r
1487                 }\r
1488 \r
1489                 recognizer->beginResync(recognizer);\r
1490 \r
1491                 // "delete" the extra token\r
1492                 //\r
1493                 recognizer->beginResync(recognizer);\r
1494                 is->consume(is);\r
1495                 recognizer->endResync(recognizer);\r
1496                 // End resync hook \r
1497                 //\r
1498                 if      (recognizer->debugger != NULL)\r
1499                 {\r
1500                         recognizer->debugger->endResync(recognizer->debugger);\r
1501                 }\r
1502 \r
1503                 // Print out the error after we consume so that ANTLRWorks sees the\r
1504                 // token in the exception.\r
1505                 //\r
1506                 recognizer->reportError(recognizer);\r
1507 \r
1508                 // Return the token we are actually matching\r
1509                 //\r
1510                 matchedSymbol = recognizer->getCurrentInputSymbol(recognizer, is);\r
1511 \r
1512                 // Consume the token that the rule actually expected to get as if everything\r
1513                 // was hunky dory.\r
1514                 //\r
1515                 is->consume(is);\r
1516 \r
1517                 recognizer->state->error  = ANTLR3_FALSE;       // Exception is not outstanding any more\r
1518 \r
1519                 return  matchedSymbol;\r
1520         }\r
1521 \r
1522         // Single token deletion (Unwanted above) did not work\r
1523         // so we see if we can insert a token instead by calculating which\r
1524         // token would be missing\r
1525         //\r
1526         if      (mismatchIsMissingToken(recognizer, is, follow))\r
1527         {\r
1528                 // We can fake the missing token and proceed\r
1529                 //\r
1530                 matchedSymbol = recognizer->getMissingSymbol(recognizer, is, recognizer->state->exception, ttype, follow);\r
1531                 recognizer->state->exception->type              = ANTLR3_MISSING_TOKEN_EXCEPTION;\r
1532                 recognizer->state->exception->message   = ANTLR3_MISSING_TOKEN_EXCEPTION_NAME;\r
1533                 recognizer->state->exception->token             = matchedSymbol;\r
1534                 recognizer->state->exception->expecting = ttype;\r
1535 \r
1536                 // Print out the error after we insert so that ANTLRWorks sees the\r
1537                 // token in the exception.\r
1538                 //\r
1539                 recognizer->reportError(recognizer);\r
1540 \r
1541                 recognizer->state->error  = ANTLR3_FALSE;       // Exception is not outstanding any more\r
1542 \r
1543                 return  matchedSymbol;\r
1544         }\r
1545 \r
1546 \r
1547         // Neither deleting nor inserting tokens allows recovery\r
1548         // must just report the exception.\r
1549         //\r
1550         recognizer->state->error            = ANTLR3_TRUE;\r
1551         return NULL;\r
1552 }\r
1553 \r
1554 static void *\r
1555 recoverFromMismatchedSet            (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST follow)\r
1556 {\r
1557     pANTLR3_PARSER                      parser;\r
1558     pANTLR3_TREE_PARSER     tparser;\r
1559     pANTLR3_INT_STREAM      is;\r
1560         pANTLR3_COMMON_TOKEN    matchedSymbol;\r
1561 \r
1562     switch      (recognizer->type)\r
1563     {\r
1564     case        ANTLR3_TYPE_PARSER:\r
1565 \r
1566                 parser  = (pANTLR3_PARSER) (recognizer->super);\r
1567                 tparser = NULL;\r
1568                 is      = parser->tstream->istream;\r
1569 \r
1570         break;\r
1571 \r
1572     case        ANTLR3_TYPE_TREE_PARSER:\r
1573 \r
1574                 tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1575                 parser  = NULL;\r
1576                 is      = tparser->ctnstream->tnstream->istream;\r
1577 \r
1578         break;\r
1579 \r
1580     default:\r
1581             \r
1582                 ANTLR3_FPRINTF(stderr, "Base recognizer function recoverFromMismatchedSet called by unknown parser type - provide override for this function\n");\r
1583                 return NULL;\r
1584 \r
1585         break;\r
1586     }\r
1587 \r
1588         if      (recognizer->mismatchIsMissingToken(recognizer, is, follow) == ANTLR3_TRUE)\r
1589         {\r
1590                 // We can fake the missing token and proceed\r
1591                 //\r
1592                 matchedSymbol = recognizer->getMissingSymbol(recognizer, is, recognizer->state->exception, ANTLR3_TOKEN_INVALID, follow);\r
1593                 recognizer->state->exception->type      = ANTLR3_MISSING_TOKEN_EXCEPTION;\r
1594                 recognizer->state->exception->token     = matchedSymbol;\r
1595 \r
1596                 // Print out the error after we insert so that ANTLRWorks sees the\r
1597                 // token in the exception.\r
1598                 //\r
1599                 recognizer->reportError(recognizer);\r
1600 \r
1601                 recognizer->state->error  = ANTLR3_FALSE;       // Exception is not outstanding any more\r
1602 \r
1603                 return  matchedSymbol;\r
1604         }\r
1605 \r
1606     // TODO - Single token deletion like in recoverFromMismatchedToken()\r
1607     //\r
1608     recognizer->state->error    = ANTLR3_TRUE;\r
1609         recognizer->state->failed       = ANTLR3_TRUE;\r
1610         return NULL;\r
1611 }\r
1612 \r
1613 /// This code is factored out from mismatched token and mismatched set\r
1614 ///  recovery.  It handles "single token insertion" error recovery for\r
1615 /// both.  No tokens are consumed to recover from insertions.  Return\r
1616 /// true if recovery was possible else return false.\r
1617 ///\r
1618 static ANTLR3_BOOLEAN   \r
1619 recoverFromMismatchedElement        (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET_LIST followBits)\r
1620 {\r
1621     pANTLR3_BITSET          viableToksFollowingRule;\r
1622     pANTLR3_BITSET          follow;\r
1623     pANTLR3_PARSER          parser;\r
1624     pANTLR3_TREE_PARSER     tparser;\r
1625     pANTLR3_INT_STREAM      is;\r
1626 \r
1627     switch      (recognizer->type)\r
1628     {\r
1629     case        ANTLR3_TYPE_PARSER:\r
1630 \r
1631                 parser  = (pANTLR3_PARSER) (recognizer->super);\r
1632                 tparser = NULL;\r
1633                 is      = parser->tstream->istream;\r
1634 \r
1635         break;\r
1636 \r
1637     case        ANTLR3_TYPE_TREE_PARSER:\r
1638 \r
1639                 tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1640                 parser  = NULL;\r
1641                 is      = tparser->ctnstream->tnstream->istream;\r
1642 \r
1643         break;\r
1644 \r
1645     default:\r
1646             \r
1647                 ANTLR3_FPRINTF(stderr, "Base recognizer function recover called by unknown parser type - provide override for this function\n");\r
1648                 return ANTLR3_FALSE;\r
1649 \r
1650         break;\r
1651     }\r
1652 \r
1653     follow      = antlr3BitsetLoad(followBits);\r
1654 \r
1655     if  (follow == NULL)\r
1656     {\r
1657                 /* The follow set is NULL, which means we don't know what can come \r
1658                  * next, so we "hit and hope" by just signifying that we cannot\r
1659                  * recover, which will just cause the next token to be consumed,\r
1660                  * which might dig us out.\r
1661                  */\r
1662                 return  ANTLR3_FALSE;\r
1663     }\r
1664 \r
1665     /* We have a bitmap for the follow set, hence we can compute \r
1666      * what can follow this grammar element reference.\r
1667      */\r
1668     if  (follow->isMember(follow, ANTLR3_EOR_TOKEN_TYPE) == ANTLR3_TRUE)\r
1669     {\r
1670                 /* First we need to know which of the available tokens are viable\r
1671                  * to follow this reference.\r
1672                  */\r
1673                 viableToksFollowingRule = recognizer->computeCSRuleFollow(recognizer);\r
1674 \r
1675                 /* Remove the EOR token, which we do not wish to compute with\r
1676                  */\r
1677                 follow->remove(follow, ANTLR3_EOR_TOKEN_TYPE);\r
1678                 viableToksFollowingRule->free(viableToksFollowingRule);\r
1679                 /* We now have the computed set of what can follow the current token\r
1680                  */\r
1681     }\r
1682 \r
1683     /* We can now see if the current token works with the set of tokens\r
1684      * that could follow the current grammar reference. If it looks like it\r
1685      * is consistent, then we can "insert" that token by not throwing\r
1686      * an exception and assuming that we saw it. \r
1687      */\r
1688     if  ( follow->isMember(follow, is->_LA(is, 1)) == ANTLR3_TRUE)\r
1689     {\r
1690                 /* report the error, but don't cause any rules to abort and stuff\r
1691                  */\r
1692                 recognizer->reportError(recognizer);\r
1693                 if      (follow != NULL)\r
1694                 {\r
1695                         follow->free(follow);\r
1696                 }\r
1697                 recognizer->state->error                        = ANTLR3_FALSE;\r
1698                 recognizer->state->failed                       = ANTLR3_FALSE;\r
1699                 return ANTLR3_TRUE;     /* Success in recovery  */\r
1700     }\r
1701 \r
1702     if  (follow != NULL)\r
1703     {\r
1704                 follow->free(follow);\r
1705     }\r
1706 \r
1707     /* We could not find anything viable to do, so this is going to \r
1708      * cause an exception.\r
1709      */\r
1710     return  ANTLR3_FALSE;\r
1711 }\r
1712 \r
1713 /// Eat tokens from the input stream until we get one of JUST the right type\r
1714 ///\r
1715 static void             \r
1716 consumeUntil    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 tokenType)\r
1717 {\r
1718     ANTLR3_UINT32                       ttype;\r
1719     pANTLR3_PARSER                      parser;\r
1720     pANTLR3_TREE_PARSER     tparser;\r
1721     pANTLR3_INT_STREAM      is;\r
1722 \r
1723     switch      (recognizer->type)\r
1724     {\r
1725                 case    ANTLR3_TYPE_PARSER:\r
1726 \r
1727                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
1728                         tparser = NULL;\r
1729                         is      = parser->tstream->istream;\r
1730 \r
1731                         break;\r
1732 \r
1733                 case    ANTLR3_TYPE_TREE_PARSER:\r
1734 \r
1735                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1736                         parser  = NULL;\r
1737                         is      = tparser->ctnstream->tnstream->istream;\r
1738 \r
1739                         break;\r
1740 \r
1741                 default:\r
1742                     \r
1743                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'consumeUntil' called by unknown parser type - provide override for this function\n");\r
1744                         return;\r
1745 \r
1746                         break;\r
1747     }\r
1748 \r
1749     // What do have at the moment?\r
1750     //\r
1751     ttype       = is->_LA(is, 1);\r
1752 \r
1753     // Start eating tokens until we get to the one we want.\r
1754     //\r
1755     while   (ttype != ANTLR3_TOKEN_EOF && ttype != tokenType)\r
1756     {\r
1757                 is->consume(is);\r
1758                 ttype   = is->_LA(is, 1);\r
1759     }\r
1760 }\r
1761 \r
1762 /// Eat tokens from the input stream until we find one that\r
1763 /// belongs to the supplied set.\r
1764 ///\r
1765 static void             \r
1766 consumeUntilSet                     (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET set)\r
1767 {\r
1768     ANTLR3_UINT32           ttype;\r
1769     pANTLR3_PARSER          parser;\r
1770     pANTLR3_TREE_PARSER     tparser;\r
1771     pANTLR3_INT_STREAM      is;\r
1772 \r
1773     switch      (recognizer->type)\r
1774     {\r
1775                 case    ANTLR3_TYPE_PARSER:\r
1776 \r
1777                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
1778                         tparser = NULL;\r
1779                         is      = parser->tstream->istream;\r
1780 \r
1781                         break;\r
1782 \r
1783                 case    ANTLR3_TYPE_TREE_PARSER:\r
1784 \r
1785                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1786                         parser  = NULL;\r
1787                         is      = tparser->ctnstream->tnstream->istream;\r
1788 \r
1789                         break;\r
1790 \r
1791                 default:\r
1792                     \r
1793                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'consumeUntilSet' called by unknown parser type - provide override for this function\n");\r
1794                         return;\r
1795 \r
1796                         break;\r
1797     }\r
1798 \r
1799     // What do have at the moment?\r
1800     //\r
1801     ttype       = is->_LA(is, 1);\r
1802 \r
1803     // Start eating tokens until we get to one we want.\r
1804     //\r
1805     while   (ttype != ANTLR3_TOKEN_EOF && set->isMember(set, ttype) == ANTLR3_FALSE)\r
1806     {\r
1807                 is->consume(is);\r
1808                 ttype   = is->_LA(is, 1);\r
1809     }\r
1810 }\r
1811 \r
1812 /** Return the rule invocation stack (how we got here in the parse.\r
1813  *  In the java version Ter just asks the JVM for all the information\r
1814  *  but in C we don't get this information, so I am going to do nothing \r
1815  *  right now.\r
1816  */\r
1817 static pANTLR3_STACK    \r
1818 getRuleInvocationStack              (pANTLR3_BASE_RECOGNIZER recognizer)\r
1819 {\r
1820     return NULL;\r
1821 }\r
1822 \r
1823 static pANTLR3_STACK    \r
1824 getRuleInvocationStackNamed         (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 name)\r
1825 {\r
1826     return NULL;\r
1827 }\r
1828 \r
1829 /** Convenience method for template rewrites - NYI.\r
1830  */\r
1831 static pANTLR3_HASH_TABLE       \r
1832 toStrings                           (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_HASH_TABLE tokens)\r
1833 {\r
1834     return NULL;\r
1835 }\r
1836 \r
1837 static  void ANTLR3_CDECL\r
1838 freeIntTrie    (void * trie)\r
1839 {\r
1840     ((pANTLR3_INT_TRIE)trie)->free((pANTLR3_INT_TRIE)trie);\r
1841 }\r
1842 \r
1843 \r
1844 /** Pointer to a function to return whether the rule has parsed input starting at the supplied \r
1845  *  start index before. If the rule has not parsed input starting from the supplied start index,\r
1846  *  then it will return ANTLR3_MEMO_RULE_UNKNOWN. If it has parsed from the suppled start point\r
1847  *  then it will return the point where it last stopped parsing after that start point.\r
1848  *\r
1849  * \remark\r
1850  * The rule memos are an ANTLR3_LIST of ANTLR3_LISTS, however if this becomes any kind of performance\r
1851  * issue (it probably won't, the hash tables are pretty quick) then we could make a special int only\r
1852  * version of the table.\r
1853  */\r
1854 static ANTLR3_MARKER    \r
1855 getRuleMemoization                  (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_INTKEY ruleIndex, ANTLR3_MARKER ruleParseStart)\r
1856 {\r
1857     /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST.\r
1858      */\r
1859     pANTLR3_INT_TRIE    ruleList;\r
1860     ANTLR3_MARKER       stopIndex;\r
1861     pANTLR3_TRIE_ENTRY  entry;\r
1862 \r
1863     /* See if we have a list in the ruleMemos for this rule, and if not, then create one\r
1864      * as we will need it eventually if we are being asked for the memo here.\r
1865      */\r
1866     entry       = recognizer->state->ruleMemo->get(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex);\r
1867 \r
1868     if  (entry == NULL)\r
1869     {\r
1870                 /* Did not find it, so create a new one for it, with a bit depth based on the \r
1871                  * size of the input stream. We need the bit depth to incorporate the number if\r
1872                  * bits required to represent the largest possible stop index in the input, which is the\r
1873                  * last character. An int stream is free to return the largest 64 bit offset if it has\r
1874                  * no idea of the size, but you should remember that this will cause the leftmost\r
1875                  * bit match algorithm to run to 63 bits, which will be the whole time spent in the trie ;-)\r
1876                  */\r
1877                 ruleList    = antlr3IntTrieNew(63);     /* Depth is theoretically 64 bits, but probably not ;-) */\r
1878 \r
1879                 if (ruleList != NULL)\r
1880                 {\r
1881                         recognizer->state->ruleMemo->add(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex, ANTLR3_HASH_TYPE_STR, 0, ANTLR3_FUNC_PTR(ruleList), freeIntTrie);\r
1882                 }\r
1883 \r
1884                 /* We cannot have a stopIndex in a trie we have just created of course\r
1885                  */\r
1886                 return  MEMO_RULE_UNKNOWN;\r
1887     }\r
1888 \r
1889     ruleList    = (pANTLR3_INT_TRIE) (entry->data.ptr);\r
1890 \r
1891     /* See if there is a stop index associated with the supplied start index.\r
1892      */\r
1893     stopIndex   = 0;\r
1894 \r
1895     entry = ruleList->get(ruleList, ruleParseStart);\r
1896     if (entry != NULL)\r
1897     {\r
1898                 stopIndex = (ANTLR3_MARKER)(entry->data.intVal);\r
1899     }\r
1900 \r
1901     if  (stopIndex == 0)\r
1902     {\r
1903                 return MEMO_RULE_UNKNOWN;\r
1904     }\r
1905 \r
1906     return  stopIndex;\r
1907 }\r
1908 \r
1909 /** Has this rule already parsed input at the current index in the\r
1910  *  input stream?  Return ANTLR3_TRUE if we have and ANTLR3_FALSE\r
1911  *  if we have not.\r
1912  *\r
1913  *  This method has a side-effect: if we have seen this input for\r
1914  *  this rule and successfully parsed before, then seek ahead to\r
1915  *  1 past the stop token matched for this rule last time.\r
1916  */\r
1917 static ANTLR3_BOOLEAN   \r
1918 alreadyParsedRule                   (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex)\r
1919 {\r
1920     ANTLR3_MARKER                       stopIndex;\r
1921     pANTLR3_LEXER                       lexer;\r
1922     pANTLR3_PARSER                      parser;\r
1923     pANTLR3_TREE_PARSER     tparser;\r
1924     pANTLR3_INT_STREAM      is;\r
1925 \r
1926     switch      (recognizer->type)\r
1927     {\r
1928                 case    ANTLR3_TYPE_PARSER:\r
1929 \r
1930                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
1931                         tparser = NULL;\r
1932                         lexer   = NULL;\r
1933                         is      = parser->tstream->istream;\r
1934 \r
1935                         break;\r
1936 \r
1937                 case    ANTLR3_TYPE_TREE_PARSER:\r
1938 \r
1939                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
1940                         parser  = NULL;\r
1941                         lexer   = NULL;\r
1942                         is      = tparser->ctnstream->tnstream->istream;\r
1943 \r
1944                         break;\r
1945 \r
1946                 case    ANTLR3_TYPE_LEXER:\r
1947 \r
1948                         lexer   = (pANTLR3_LEXER)   (recognizer->super);\r
1949                         parser  = NULL;\r
1950                         tparser = NULL;\r
1951                         is      = lexer->input->istream;\r
1952                         break;\r
1953 \r
1954                 default:\r
1955                     \r
1956                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'alreadyParsedRule' called by unknown parser type - provide override for this function\n");\r
1957                         return ANTLR3_FALSE;\r
1958 \r
1959                         break;\r
1960     }\r
1961 \r
1962     /* See if we have a memo marker for this.\r
1963      */\r
1964     stopIndex       = recognizer->getRuleMemoization(recognizer, ruleIndex, is->index(is));\r
1965 \r
1966     if  (stopIndex  == MEMO_RULE_UNKNOWN)\r
1967     {\r
1968                 return ANTLR3_FALSE;\r
1969     }\r
1970 \r
1971     if  (stopIndex == MEMO_RULE_FAILED)\r
1972     {\r
1973                 recognizer->state->failed = ANTLR3_TRUE;\r
1974     }\r
1975     else\r
1976     {\r
1977                 is->seek(is, stopIndex+1);\r
1978     }\r
1979 \r
1980     /* If here then the rule was executed for this input already\r
1981      */\r
1982     return  ANTLR3_TRUE;\r
1983 }\r
1984 \r
1985 /** Record whether or not this rule parsed the input at this position\r
1986  *  successfully.\r
1987  */\r
1988 static void             \r
1989 memoize (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_MARKER ruleIndex, ANTLR3_MARKER ruleParseStart)\r
1990 {\r
1991     /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST.\r
1992      */\r
1993     pANTLR3_INT_TRIE        ruleList;\r
1994     pANTLR3_TRIE_ENTRY      entry;\r
1995     ANTLR3_MARKER           stopIndex;\r
1996     pANTLR3_LEXER           lexer;\r
1997     pANTLR3_PARSER          parser;\r
1998     pANTLR3_TREE_PARSER     tparser;\r
1999     pANTLR3_INT_STREAM      is;\r
2000 \r
2001     switch      (recognizer->type)\r
2002     {\r
2003                 case    ANTLR3_TYPE_PARSER:\r
2004 \r
2005                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
2006                         tparser = NULL;\r
2007                         is      = parser->tstream->istream;\r
2008 \r
2009                         break;\r
2010 \r
2011                 case    ANTLR3_TYPE_TREE_PARSER:\r
2012 \r
2013                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
2014                         parser  = NULL;\r
2015                         is      = tparser->ctnstream->tnstream->istream;\r
2016 \r
2017                         break;\r
2018 \r
2019                 case    ANTLR3_TYPE_LEXER:\r
2020 \r
2021                         lexer   = (pANTLR3_LEXER)   (recognizer->super);\r
2022                         parser  = NULL;\r
2023                         tparser = NULL;\r
2024                         is              = lexer->input->istream;\r
2025                         break;\r
2026 \r
2027                 default:\r
2028                     \r
2029                         ANTLR3_FPRINTF(stderr, "Base recognizer function consumeUntilSet called by unknown parser type - provide override for this function\n");\r
2030                         return;\r
2031 \r
2032                         break;\r
2033     }\r
2034     \r
2035     stopIndex   = recognizer->state->failed == ANTLR3_TRUE ? MEMO_RULE_FAILED : is->index(is) - 1;\r
2036 \r
2037     entry       = recognizer->state->ruleMemo->get(recognizer->state->ruleMemo, (ANTLR3_INTKEY)ruleIndex);\r
2038 \r
2039     if  (entry != NULL)\r
2040     {\r
2041                 ruleList = (pANTLR3_INT_TRIE)(entry->data.ptr);\r
2042 \r
2043                 /* If we don't already have this entry, append it. The memoize trie does not\r
2044                  * accept duplicates so it won't add it if already there and we just ignore the\r
2045                  * return code as we don't care if it is there already.\r
2046                  */\r
2047                 ruleList->add(ruleList, ruleParseStart, ANTLR3_HASH_TYPE_INT, stopIndex, NULL, NULL);\r
2048     }\r
2049 }\r
2050 /** A syntactic predicate.  Returns true/false depending on whether\r
2051  *  the specified grammar fragment matches the current input stream.\r
2052  *  This resets the failed instance var afterwards.\r
2053  */\r
2054 static ANTLR3_BOOLEAN   \r
2055 synpred (pANTLR3_BASE_RECOGNIZER recognizer, void * ctx, void (*predicate)(void * ctx))\r
2056 {\r
2057     ANTLR3_MARKER   start;\r
2058     pANTLR3_PARSER          parser;\r
2059     pANTLR3_TREE_PARSER     tparser;\r
2060     pANTLR3_INT_STREAM      is;\r
2061 \r
2062     switch      (recognizer->type)\r
2063     {\r
2064                 case    ANTLR3_TYPE_PARSER:\r
2065 \r
2066                         parser  = (pANTLR3_PARSER) (recognizer->super);\r
2067                         tparser = NULL;\r
2068                         is      = parser->tstream->istream;\r
2069 \r
2070                         break;\r
2071 \r
2072                 case    ANTLR3_TYPE_TREE_PARSER:\r
2073 \r
2074                         tparser = (pANTLR3_TREE_PARSER) (recognizer->super);\r
2075                         parser  = NULL;\r
2076                         is      = tparser->ctnstream->tnstream->istream;\r
2077 \r
2078                         break;\r
2079 \r
2080                 default:\r
2081                     \r
2082                         ANTLR3_FPRINTF(stderr, "Base recognizer function 'synPred' called by unknown parser type - provide override for this function\n");\r
2083                         return ANTLR3_FALSE;\r
2084 \r
2085                         break;\r
2086     }\r
2087 \r
2088     /* Begin backtracking so we can get back to where we started after trying out\r
2089      * the syntactic predicate.\r
2090      */\r
2091     start   = is->mark(is);\r
2092     recognizer->state->backtracking++;\r
2093 \r
2094     /* Try the syntactical predicate\r
2095      */\r
2096     predicate(ctx);\r
2097 \r
2098     /* Reset\r
2099      */\r
2100     is->rewind(is, start);\r
2101     recognizer->state->backtracking--;\r
2102 \r
2103     if  (recognizer->state->failed == ANTLR3_TRUE)\r
2104     {\r
2105                 /* Predicate failed\r
2106                  */\r
2107                 recognizer->state->failed = ANTLR3_FALSE;\r
2108                 return  ANTLR3_FALSE;\r
2109     }\r
2110     else\r
2111     {\r
2112                 /* Predicate was successful\r
2113                  */\r
2114                 recognizer->state->failed       = ANTLR3_FALSE;\r
2115                 return  ANTLR3_TRUE;\r
2116     }\r
2117 }\r
2118 \r
2119 static void\r
2120 reset(pANTLR3_BASE_RECOGNIZER recognizer)\r
2121 {\r
2122     if  (recognizer->state->following != NULL)\r
2123     {\r
2124                 recognizer->state->following->free(recognizer->state->following);\r
2125     }\r
2126 \r
2127         // Reset the state flags\r
2128         //\r
2129         recognizer->state->errorRecovery        = ANTLR3_FALSE;\r
2130         recognizer->state->lastErrorIndex       = -1;\r
2131         recognizer->state->failed                       = ANTLR3_FALSE;\r
2132         recognizer->state->errorCount           = 0;\r
2133         recognizer->state->backtracking         = 0;\r
2134         recognizer->state->following            = NULL;\r
2135 \r
2136         if      (recognizer->state != NULL)\r
2137         {\r
2138                 if      (recognizer->state->ruleMemo != NULL)\r
2139                 {\r
2140                         recognizer->state->ruleMemo->free(recognizer->state->ruleMemo);\r
2141                         recognizer->state->ruleMemo = antlr3IntTrieNew(15);     /* 16 bit depth is enough for 32768 rules! */\r
2142                 }\r
2143         }\r
2144         \r
2145 \r
2146     // Install a new following set\r
2147     //\r
2148     recognizer->state->following   = antlr3StackNew(8);\r
2149 \r
2150 }\r
2151 \r
2152 // Default implementation is for parser and assumes a token stream as supplied by the runtime.\r
2153 // You MAY need override this function if the standard TOKEN_STREAM is not what you are using.\r
2154 //\r
2155 static void *                           \r
2156 getCurrentInputSymbol           (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream)\r
2157 {\r
2158         return ((pANTLR3_TOKEN_STREAM)istream->super)->_LT((pANTLR3_TOKEN_STREAM)istream->super, 1);\r
2159 }\r
2160 \r
2161 // Default implementation is for parser and assumes a token stream as supplied by the runtime.\r
2162 // You MAY need override this function if the standard COMMON_TOKEN_STREAM is not what you are using.\r
2163 //\r
2164 static void *                           \r
2165 getMissingSymbol                        (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream, pANTLR3_EXCEPTION      e,\r
2166                                                                         ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow)\r
2167 {\r
2168         pANTLR3_TOKEN_STREAM                    ts;\r
2169         pANTLR3_COMMON_TOKEN_STREAM             cts;\r
2170         pANTLR3_COMMON_TOKEN                    token;\r
2171         pANTLR3_COMMON_TOKEN                    current;\r
2172         pANTLR3_STRING                                  text;\r
2173 \r
2174         // Dereference the standard pointers\r
2175         //\r
2176         ts              = (pANTLR3_TOKEN_STREAM)istream->super;\r
2177         cts             = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;\r
2178         \r
2179         // Work out what to use as the current symbol to make a line and offset etc\r
2180         // If we are at EOF, we use the token before EOF\r
2181         //\r
2182         current = ts->_LT(ts, 1);\r
2183         if      (current->getType(current) == ANTLR3_TOKEN_EOF)\r
2184         {\r
2185                 current = ts->_LT(ts, -1);\r
2186         }\r
2187 \r
2188         // Create a new empty token\r
2189         //\r
2190         if      (recognizer->state->tokFactory == NULL)\r
2191         {\r
2192                 // We don't yet have a token factory for making tokens\r
2193                 // we just need a fake one using the input stream of the current\r
2194                 // token.\r
2195                 //\r
2196                 recognizer->state->tokFactory = antlr3TokenFactoryNew(current->input);\r
2197         }\r
2198         token   = recognizer->state->tokFactory->newToken(recognizer->state->tokFactory);\r
2199 \r
2200         // Set some of the token properties based on the current token\r
2201         //\r
2202         token->setLine                                  (token, current->getLine(current));\r
2203         token->setCharPositionInLine    (token, current->getCharPositionInLine(current));\r
2204         token->setChannel                               (token, ANTLR3_TOKEN_DEFAULT_CHANNEL);\r
2205         token->setType                                  (token, expectedTokenType);\r
2206     token->user1                    = current->user1;\r
2207     token->user2                    = current->user2;\r
2208     token->user3                    = current->user3;\r
2209     token->custom                   = current->custom;\r
2210     token->lineStart                = current->lineStart;\r
2211     \r
2212         // Create the token text that shows it has been inserted\r
2213         //\r
2214         token->setText8(token, (pANTLR3_UINT8)"<missing ");\r
2215         text = token->getText(token);\r
2216 \r
2217         if      (text != NULL)\r
2218         {\r
2219                 text->append8(text, (const char *)recognizer->state->tokenNames[expectedTokenType]);\r
2220                 text->append8(text, (const char *)">");\r
2221         }\r
2222         \r
2223         // Finally return the pointer to our new token\r
2224         //\r
2225         return  token;\r
2226 }\r
2227 \r
2228 \r
2229 #ifdef  ANTLR3_WINDOWS\r
2230 #pragma warning( default : 4100 )\r
2231 #endif\r
2232 \r
2233 /// @}\r
2234 ///\r
2235 \r