/** Given a start and stop index, return a List of all tokens in * the token type BitSet. Return null if no tokens were found. This * method looks at both on and off channel tokens. */ static pANTLR3_LIST getTokensSet (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types) { pANTLR3_LIST filteredList; ANTLR3_UINT32 i; ANTLR3_UINT32 n; pANTLR3_COMMON_TOKEN tok; if (tokenStream->p == -1) { fillBuffer(tokenStream); } if (stop > tokenStream->tstream->istream->size(tokenStream->tstream->istream)) { stop = tokenStream->tstream->istream->size(tokenStream->tstream->istream); } if (start > stop) { return NULL; } /* We have the range set, now we need to iterate through the * installed tokens and create a new list with just the ones we want * in it. We are just moving pointers about really. */ filteredList = antlr3ListNew((ANTLR3_UINT32)tokenStream->tstream->istream->size(tokenStream->tstream->istream)); for (i = start, n = 0; i<= stop; i++) { tok = tokenStream->tstream->get(tokenStream->tstream, i); if ( types == NULL || types->isMember(types, tok->getType(tok) == ANTLR3_TRUE) ) { filteredList->put(filteredList, n++, (void *)tok, NULL); } } /* Did we get any then? */ if (filteredList->size(filteredList) == 0) { filteredList->free(filteredList); filteredList = NULL; } return filteredList; }
/** Eat tokens from the input stream until we find one that * belongs to the supplied set. */ static void consumeUntilSet (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET set) { ANTLR3_UINT32 ttype; pANTLR3_PARSER parser; pANTLR3_TREE_PARSER tparser; pANTLR3_INT_STREAM is; switch (recognizer->type) { case ANTLR3_TYPE_PARSER: parser = (pANTLR3_PARSER) (recognizer->super); tparser = NULL; is = parser->tstream->istream; break; case ANTLR3_TYPE_TREE_PARSER: tparser = (pANTLR3_TREE_PARSER) (recognizer->super); parser = NULL; is = tparser->ctnstream->tnstream->istream; break; default: fprintf(stderr, "Base recognizerfunction 'consumeUntilSet' called by unknown paresr type - provide override for this function\n"); return; break; } /* What do have at the moment? */ ttype = is->_LA(is, 1); /* Start eating tokens until we get to one we want. */ while (ttype != ANTLR3_TOKEN_EOF && set->isMember(set, ttype) == ANTLR3_FALSE) { is->consume(is); ttype = is->_LA(is, 1); } }
/** This code is factored out from mismatched token and mismatched set * recovery. It handles "single token insertion" error recovery for * both. No tokens are consumed to recover from insertions. Return * true if recovery was possible else return false. */ static ANTLR3_BOOLEAN recoverFromMismatchedElement (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_BITSET follow) { pANTLR3_BITSET viableToksFollowingRule; pANTLR3_BITSET newFollow; pANTLR3_PARSER parser; pANTLR3_TREE_PARSER tparser; pANTLR3_INT_STREAM is; switch (recognizer->type) { case ANTLR3_TYPE_PARSER: parser = (pANTLR3_PARSER) (recognizer->super); tparser = NULL; is = parser->tstream->istream; break; case ANTLR3_TYPE_TREE_PARSER: tparser = (pANTLR3_TREE_PARSER) (recognizer->super); parser = NULL; is = tparser->ctnstream->tnstream->istream; break; default: fprintf(stderr, "Base recognizerfunction recover called by unknown paresr type - provide override for this function\n"); return ANTLR3_FALSE; break; } newFollow = NULL; if (follow == NULL) { /* The follow set is NULL, which means we don't know what can come * next, so we "hit and hope" by just signifying that we cannot * recover, which will just cause the next token to be consumed, * which might dig us out. */ return ANTLR3_FALSE; } /* We have a bitmap for the follow set, hence we can compute * what can follow this grammar element reference. */ if (follow->isMember(follow, ANTLR3_EOR_TOKEN_TYPE) == ANTLR3_TRUE) { /* First we need to know which of the available tokens are viable * to follow this reference. */ viableToksFollowingRule = recognizer->computeCSRuleFollow(recognizer); /* Knowing that, we can or in the follow set */ newFollow = follow->or(follow, viableToksFollowingRule); /* Remove the EOR token, which we do not wish to compute with */ newFollow->remove(follow, ANTLR3_EOR_TOKEN_TYPE); viableToksFollowingRule->free(viableToksFollowingRule); /* We now have the computed set of what can follow the current token */ follow = newFollow; } /* We can now see if the current token works with the set of tokens * that could follow the current grammar reference. If it looks like it * is consistent, then we can "insert" that token by not throwing * an exception and assumimng that we saw it. */ if ( follow->isMember(follow, is->_LA(is, 1)) == ANTLR3_TRUE) { /* report the error, but don't cause any rules to abort and stuff */ recognizer->reportError(recognizer); if (newFollow != NULL) { newFollow->free(newFollow); } recognizer->error = ANTLR3_FALSE; recognizer->failed = ANTLR3_FALSE; return ANTLR3_TRUE; /* Success in recovery */ } if (newFollow != NULL) { newFollow->free(newFollow); } /* We could not find anything viable to do, so this is going to * cause an exception. */ return ANTLR3_FALSE; }