📄 antlr3baserecognizer.c
字号:
*/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); /* 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); recognizer->error = ANTLR3_FALSE; recognizer->failed = ANTLR3_FALSE; return ANTLR3_TRUE; /* Success in recovery */ } /* We could not find anything viable to do, so this is going to * cause an exception. */ return ANTLR3_FALSE;}/** Eat tokens from the input stream until we get one of JUST the right type */static void consumeUntil (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 tokenType){ 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 'consumeUntil' 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 the one we want. */ while (ttype != ANTLR3_TOKEN_EOF && ttype != tokenType) { is->consume(is); ttype = is->LA(is, 1); }}/** 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); }}/** Return the rule invokation stack (how we got here in the parse. * In the java version Ter just asks the JVM for all the information * but it C we don't get this information, so I am going to do nothing * right now, but when the genrated code is there I will look to see how much * overhead is involved in pushing and popping this informatino on rule entry * and exit. It is only good for error reporting and error recovery, though * I don;t see that we are using it in errory recovery yet anyway as the context * sensitive recvoery just calls the normal recoery funtions. * TODO: Consult with Ter on this one as to usefulness, it is easy but do I need it? */static pANTLR3_STACK getRuleInvocationStack (pANTLR3_BASE_RECOGNIZER recognizer){ return NULL;}static pANTLR3_STACK getRuleInvocationStackNamed (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 name){ return NULL;}/** Convenience method for template rewrites - NYI. */static pANTLR3_HASH_TABLE toStrings (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_HASH_TABLE tokens){ return NULL;}static voidfreeList (void * list){ ((pANTLR3_LIST)list)->free(list);}/** Pointer to a function to return whether the rule has parsed input starting at the supplied * start index before. If the rule has not parsed input starting from the supplied start index, * then it will return ANTLR3_MEMO_RULE_UNKNOWN. If it has parsed from the suppled start point * then it will return the point where it last stopped parsing after that start point. * * \remark * The rule memos are an ANTLR3_LIST of ANTLR3_LISTS, however if this becomes any kind of performance * issue (it probably won't teh has tables are pretty quick) then we could make a special int only * version of the table. */static ANTLR3_UINT64 getRuleMemoization (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ruleIndex, ANTLR3_UINT64 ruleParseStart){ /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST. */ pANTLR3_LIST ruleList; ANTLR3_UINT64 stopIndex; /* See if we have a list in the ruleMemos for this rule, and if not, then create one * as we will need it eventually. */ ruleList = recognizer->ruleMemo->get(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex); if (ruleList == NULL) { /* Did not find it, so create a new one */ ruleList = antlr3ListNew(31); recognizer->ruleMemo->put(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex, ANTLR3_FUNC_PTR(ruleList), freeList); } /* See if there is a stop index associated with the supplied start index. * We index on the start position + 1, just in case there is ever a need to * memoize the first token ever, at index 0. */ stopIndex = ANTLR3_UINT64_CAST(ruleList->get(ruleList, ruleParseStart+1)); if (stopIndex == 0) { return MEMO_RULE_UNKNOWN; } return stopIndex;}/** Has this rule already parsed input at the current index in the * input stream? Return the stop token index or MEMO_RULE_UNKNOWN. * If we attempted but failed to parse properly before, return * MEMO_RULE_FAILED. * * This method has a side-effect: if we have seen this input for * this rule and successfully parsed before, then seek ahead to * 1 past the stop token matched for this rule last time. */static ANTLR3_BOOLEAN alreadyParsedRule (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ruleIndex){ ANTLR3_UINT64 stopIndex; 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 'alreadyParsedRule' called by unknown paresr type - provide override for this function\n"); return ANTLR3_FALSE; break; } /* See if we have a memo marker for this. */ stopIndex = recognizer->getRuleMemoization(recognizer, ruleIndex, is->index(is)); if (stopIndex == MEMO_RULE_UNKNOWN) { return ANTLR3_FALSE; } if (stopIndex == MEMO_RULE_FAILED) { recognizer->failed = ANTLR3_TRUE; } else { is->seek(is, stopIndex+1); } /* If here then the rule was executed for this input already */ return ANTLR3_TRUE;}/** Record whether or not this rule parsed the input at this position * successfully. */static void memoize (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ruleIndex, ANTLR3_UINT64 ruleParseStart){ /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST. */ pANTLR3_LIST ruleList; ANTLR3_UINT64 stopIndex; 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; } stopIndex = recognizer->failed == ANTLR3_TRUE ? MEMO_RULE_FAILED : is->index(is) - 1; ruleList = recognizer->ruleMemo->get(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex); if (ruleList != NULL) { /* Add one to key in case the start is 0 eveer */ ruleList->put(ruleList, ruleParseStart+1, ANTLR3_FUNC_PTR(stopIndex), NULL); }}/** A syntactic predicate. Returns true/false depending on whether * the specified grammar fragment matches the current input stream. * This resets the failed instance var afterwards. */static ANTLR3_BOOLEAN synpred (pANTLR3_BASE_RECOGNIZER recognizer, void * ctx, void (*predicate)(void * ctx)){ ANTLR3_UINT64 start; 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 'synPred' called by unknown paresr type - provide override for this function\n"); return ANTLR3_FALSE; break; } /* Begin backtracking so we can get back to where we started after trying out * the syntactic predicate. */ start = is->mark(is); recognizer->backtracking++; /* Try the syntactical predicate */ predicate(ctx); /* Reset */ is->rewind(is, start); recognizer->backtracking--; if (recognizer->failed == ANTLR3_TRUE) { /* Predicate failed */ recognizer->failed = ANTLR3_FALSE; return ANTLR3_FALSE; } else { /* Predicate was succesful */ recognizer->failed = ANTLR3_FALSE; return ANTLR3_TRUE; }}static voidreset(pANTLR3_BASE_RECOGNIZER recognizer){ if (recognizer->following != NULL) { recognizer->following->free(recognizer->following); } /* Install a new following set */ recognizer->following = antlr3StackNew(64);}#ifdef WIN32#pragma warning( default : 4100 )#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -