📄 antlr3baserecognizer.c
字号:
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;}/** 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 void ANTLR3_CDECLfreeList (void * list){ ((pANTLR3_LIST)list)->free(list);}static void ANTLR3_CDECLfreeIntTrie (void * trie){ ((pANTLR3_INT_TRIE)trie)->free((pANTLR3_INT_TRIE)trie);}/** 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, the hash 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_INT_TRIE ruleList; ANTLR3_UINT64 stopIndex; pANTLR3_TRIE_ENTRY entry; /* See if we have a list in the ruleMemos for this rule, and if not, then create one * as we will need it eventually if we are being asked for the memo here. */ entry = recognizer->ruleMemo->get(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex); if (entry == NULL) { /* Did not find it, so create a new one for it, with a bit depth based on the * size of the input stream. We need the bit depth to incorporate the number if * bits required to represen the largest possible stop index in the input, which is the * last character. An int stream is free to return the largest 64 bit offset if it has * no idea of the size, but you should remember that this will cause the leftmost * bit match algorithm to run to 63 bits, whcih will be the whole time spent in the trie ;-) */ ruleList = antlr3IntTrieNew(63); /* Depth is theoretically 64 bits, but probably not ;-) */ if (ruleList != (pANTLR3_INT_TRIE)ANTLR3_ERR_NOMEM) { recognizer->ruleMemo->add(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex, ANTLR3_HASH_TYPE_STR, 0, ANTLR3_FUNC_PTR(ruleList), freeIntTrie); } /* We cannot have a stopIndex in a trie we have just created of course */ return MEMO_RULE_UNKNOWN; } ruleList = (pANTLR3_INT_TRIE) (entry->data.ptr); /* See if there is a stop index associated with the supplied start index. */ stopIndex = 0; entry = ruleList->get(ruleList, ruleParseStart); if (entry != NULL) { stopIndex = entry->data.intVal; } if (stopIndex == 0) { return MEMO_RULE_UNKNOWN; } return stopIndex;}/** Has this rule already parsed input at the current index in the * input stream? Return ANTLR3_TRUE if we have and ANTLR3_FALSE * if we have not. * * 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_LEXER lexer; 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; lexer = NULL; is = parser->tstream->istream; break; case ANTLR3_TYPE_TREE_PARSER: tparser = (pANTLR3_TREE_PARSER) (recognizer->super); parser = NULL; lexer = NULL; is = tparser->ctnstream->tnstream->istream; break; case ANTLR3_TYPE_LEXER: lexer = (pANTLR3_LEXER) (recognizer->super); parser = NULL; tparser = NULL; is = lexer->input->istream; 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_INT_TRIE ruleList; pANTLR3_TRIE_ENTRY entry; ANTLR3_UINT64 stopIndex; pANTLR3_LEXER lexer; 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; case ANTLR3_TYPE_LEXER: lexer = (pANTLR3_LEXER) (recognizer->super); parser = NULL; tparser = NULL; is = lexer->input->istream; default: fprintf(stderr, "Base recognizerfunction consumeUntilSet called by unknown parser type - provide override for this function\n"); return; break; } stopIndex = recognizer->failed == ANTLR3_TRUE ? MEMO_RULE_FAILED : is->index(is) - 1; entry = recognizer->ruleMemo->get(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex); if (entry != NULL) { ruleList = (pANTLR3_INT_TRIE)(entry->data.ptr); /* If we don't already have this entry, append it. The memoize trie does not * accept duplicates so it won't add it if already there and we just ignore the * return code as we don't care if it is there already. */ ruleList->add(ruleList, ruleParseStart, ANTLR3_HASH_TYPE_INT, stopIndex, NULL, 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 + -