/** Do the work of getting the next element, making sure that it's * a tree node or subtree. Deal with the optimization of single- * element list versus list of size > 1. Throw an exception (or something similar) * if the stream is empty or we're out of elements and size>1. * You can override in a subclass if necessary. */ static void * _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) { ANTLR3_UINT32 s; pANTLR3_BASE_TREE t; s = stream->size(stream); if (s == 0) { // This means that the stream is empty // return (pANTLR3_BASE_TREE)ANTLR3_FUNC_PTR(NULL); // Caller must cope with this } // Traversed all the available elements already? // if (stream->cursor >= s) { if (s == 1) { // Special case when size is single element, it will just dup a lot // return stream->singleElement; } // OUt of elements and the size is not 1, so we cannot assume // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+) // THis means we ran out of elements earlier than was expected. // return (pANTLR3_BASE_TREE)ANTLR3_FUNC_PTR(NULL); // Caller must cope with this } // Elements available either for duping or just available // if (stream->singleElement != NULL) { stream->cursor++; // Cursor advances even for single element as this tells us to dup() return stream->toTree(stream, stream->singleElement); } // More than just a single element so we extract it from the // vector. // t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor+1)); // TODO: Why not just cursor++ ? stream->cursor++; return t; }
/* Functions for creating streams */ static pANTLR3_REWRITE_RULE_ELEMENT_STREAM antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description) { pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; /* First job is to create the memory we need. */ stream = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM))); if (stream == NULL) { return (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); } /* Populate the generic interface */ stream->reset = reset; stream->add = add; stream->next = next; stream->_next = _next; stream->hasNext = hasNext; stream->size = size; stream->getDescription = getDescription; stream->free = freeRS; /* Install the description */ stream->elementDescription = adaptor->strFactory->newStr8(adaptor->strFactory, description); /* Install the adaptor */ stream->adaptor = adaptor; return stream; }
/** \brief Rewind the lexer input to the state specified by the supplied mark. * * \param[in] input Input stream context pointer * * \remark * Assumes ASCII (or at least, 8 Bit) input stream. */ static void antlr3AsciiSeek (pANTLR3_INT_STREAM is, ANTLR3_MARKER seekPoint) { ANTLR3_INT32 count; pANTLR3_INPUT_STREAM input; input = ANTLR3_FUNC_PTR(((pANTLR3_INPUT_STREAM) is->super)); /* If the requested seek point is less than the current * input point, then we assume that we are resetting from a mark * and do not need to scan, but can just set to there. */ if (seekPoint <= (ANTLR3_MARKER)(input->nextChar)) { input->nextChar = ((pANTLR3_UINT8) seekPoint); } else { count = (ANTLR3_UINT32)(seekPoint - (ANTLR3_MARKER)(input->nextChar)); while (count--) { is->consume(is); } } }
/** * \brief * Creates a new ANTLR3 exception structure * * \param[in] exception * One of the ANTLR3_xxx_EXCEPTION indicators such as #ANTLR3_RECOGNITION_EXCEPTION * * \param[in] message * Pointer to message string * * \param[in] freeMessage * Set to ANTLR3_TRUE if the message parameter should be freed by a call to * ANTLR3_FREE() when the exception is destroyed. * * \returns * Pointer to newly initialized exception structure, or an ANTLR3_ERR_xx defined value * upon failure. * * An exception is 'thrown' by a recognizer when input is seen that is not predicted by * the grammar productions or when some other error condition occurs. In C we do not have * the luxury of try and catch blocks, so exceptions are added in the order they occur to * a list in the baserecognizer structure. The last one to be thrown is inserted at the head of * the list and the one currently installed is pointed to by the newly installed exception. * * \remarks * After an exception is created, you may add a pointer to your own structure and a pointer * to a function to free this structure when the exception is destroyed. * * \see * ANTLR3_EXCEPTION */ pANTLR3_EXCEPTION antlr3ExceptionNew(ANTLR3_UINT32 exception, void * name, void * message, ANTLR3_BOOLEAN freeMessage) { pANTLR3_EXCEPTION ex; /* Allocate memory for the structure */ ex = (pANTLR3_EXCEPTION) ANTLR3_MALLOC(sizeof(ANTLR3_EXCEPTION)); /* Check for memory allocation */ if (ex == NULL) { return (pANTLR3_EXCEPTION)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); } ex->name = name; /* Install exception name */ ex->type = exception; /* Install the exception number */ ex->message = message; /* Install message string */ /* Indicate whether the string should be freed if exception is destroyed */ ex->freeMessage = freeMessage; /* Install the API */ ex->print = antlr3ExceptionPrint; ex->freeEx = antlr3ExceptionFree; return ex; }
/** \brief Return the input element assuming an 8 bit ascii input * * \param[in] input Input stream context pointer * \param[in] lt 1 based offset of next input stream element * * \return Next input character in internal ANTLR3 encoding (UTF32) */ static void * antlr3AsciiLT(pANTLR3_INPUT_STREAM input, ANTLR3_INT32 lt) { /* Casting is horrible but it means no warnings and LT should never be called * on a character stream anyway I think. If it is then, the void * will need to be * cast back in a similar manner. Yuck! But this means that LT for Token streams and * tree streams is correct. */ return (ANTLR3_FUNC_PTR(input->istream->_LA(input->istream, lt))); }
/** A simple filter mechanism whereby you can tell this token stream * to force all tokens of type ttype to be on channel. For example, * when interpreting, we cannot execute actions so we need to tell * the stream to force all WS and NEWLINE to be a different, ignored, * channel. */ static void setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel) { if (tokenStream->channelOverrides == NULL) { tokenStream->channelOverrides = antlr3ListNew(10); } /* We add one to the channel so we can distinguish NULL as being no entry in the * table for a particular token type. */ tokenStream->channelOverrides->put(tokenStream->channelOverrides, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)channel + 1), NULL); }
static void discardTokenType (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 ttype) { if (tokenStream->discardSet == NULL) { tokenStream->discardSet = antlr3ListNew(31); } /* We add one to the channel so we can distinguish NULL as being no entry in the * table for a particular token type. We could use bitsets for this I suppose too. */ tokenStream->discardSet->put(tokenStream->discardSet, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)ttype + 1), NULL); }
ANTLR3_API pANTLR3_COMMON_TOKEN antlr3CommonTokenNew(ANTLR3_UINT32 ttype) { pANTLR3_COMMON_TOKEN token; /* Create a raw token with the interface installed */ token = newToken(); if (token != (pANTLR3_COMMON_TOKEN)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) { token->setType(token, ttype); } /* All good */ return token; }
static pANTLR3_REWRITE_RULE_ELEMENT_STREAM antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, void * oneElement) { pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; /* First job is to create the memory we need. */ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, description); if (stream == (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) { return stream; } /* Stream seems good so we need to add the supplied element */ stream->add(stream, oneElement, NULL); return stream; }
/** \brief Use the contents of an operating system file as the input * for an input stream. * * \param fileName Name of operating system file to read. * \return * - Pointer to new input stream context upon success * - One of the ANTLR3_ERR_ defines on error. */ ANTLR3_API pANTLR3_INPUT_STREAM antlr3AsciiFileStreamNew(pANTLR3_UINT8 fileName) { /* Pointer to the input stream we are going to create */ pANTLR3_INPUT_STREAM input; ANTLR3_UINT64 status; /* Allocate memory for the input stream structure */ input = (pANTLR3_INPUT_STREAM) ANTLR3_MALLOC(sizeof(ANTLR3_INPUT_STREAM)); if (input == NULL) { return (pANTLR3_INPUT_STREAM) ANTLR3_ERR_NOMEM; } input->fileName = ANTLR3_STRDUP(fileName); /* Structure was allocated correctly, now we can read the file. */ status = antlr3readAscii(input); if (status != ANTLR3_SUCCESS) { ANTLR3_FREE(input->fileName); ANTLR3_FREE(input); return ANTLR3_FUNC_PTR(status); } /* Call the common 8 bit ASCII input stream handler * intializer type thingy doobry function. */ antlr3AsciiSetupStream(input, ANTLR3_CHARSTREAM); return input; }
static pANTLR3_COMMON_TOKEN newToken(void) { pANTLR3_COMMON_TOKEN token; /* Allocate memory for this */ token = (pANTLR3_COMMON_TOKEN) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_COMMON_TOKEN))); if (token == NULL) { return (pANTLR3_COMMON_TOKEN)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); } /* Install the API */ antlr3SetTokenAPI(token); token->factoryMade = ANTLR3_FALSE; return token; }
ANTLR3_API pANTLR3_TOKEN_FACTORY antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input) { pANTLR3_TOKEN_FACTORY factory; /* allocate memory */ factory = (pANTLR3_TOKEN_FACTORY) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_TOKEN_FACTORY)); if (factory == NULL) { return (pANTLR3_TOKEN_FACTORY)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); } /* Install factory API */ factory->newToken = newPoolToken; factory->close = factoryClose; factory->setInputStream = setInputStream; /* Allocate the initial pool */ factory->thisPool = -1; factory->pools = NULL; newPool(factory); /* Factory space is good, we now want to initialize our cheating token * which one it is initialized is the model for all tokens we manufacture */ antlr3SetTokenAPI(&factory->unTruc); /* Set some initial variables for future copying */ factory->unTruc.factoryMade = ANTLR3_TRUE; setInputStream(factory, input); return factory; }
static pANTLR3_REWRITE_RULE_ELEMENT_STREAM antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) { pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; /* First job is to create the memory we need. */ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, description); if (stream == (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) { return stream; } /* Stream seems good so we need to install the vector we were * given. We assume that someone else is going to free the * vector. */ stream->elements = vector; return stream; }
ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM antlr3RewriteRuleTokenStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description) { pANTLR3_REWRITE_RULE_TOKEN_STREAM stream; /* First job is to create the memory we need. */ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, description); if (stream == (pANTLR3_REWRITE_RULE_TOKEN_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) { return stream; } /* Install the token based overrides */ stream->dup = dupTok; stream->toTree = toTreeToken; /* No nextNode implementation for a token rewrite stream */ return stream; }
ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) { pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream; /* First job is to create the memory we need. */ stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, description, vector); if (stream == (pANTLR3_REWRITE_RULE_SUBTREE_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) { return stream; } /* Install the token based overrides */ stream->dup = dupTree; stream->toTree = toTreeTree; stream->nextNode = nextNode; return stream; }
static void push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index) { ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL); // Save current index ctns->tnstream->istream->seek(ctns->tnstream->istream, index); }
/** 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; }