antlr3rewritestreams.c

来自「antlr最新版本V3源代码」· C语言 代码 · 共 500 行

C
500
字号
/** \file * Implementation of token/tree streams that are used by the * tree re-write rules to manipulate the tokens and trees produced * by rules that are subject to rewrite directives. */#include    <antlr3rewritestreams.h>/* Static support function forward declarations for the stream types. */static    void			reset		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); static	  void			add		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *));static    void *		next		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static    void *		_next		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static	  void *		dupTok		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);static	  void *		dupTree		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);static	  pANTLR3_BASE_TREE	toTreeTree	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);static	  pANTLR3_BASE_TREE	toTreeToken	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);static    ANTLR3_BOOLEAN	hasNext		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static    pANTLR3_BASE_TREE	nextNode	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static    ANTLR3_UINT32		size		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static    pANTLR3_STRING	getDescription	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static	  void			freeRS		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);static voidfreeRS	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL)    {	stream->elements->free(stream->elements);    }    ANTLR3_FREE(stream);}/* 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_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;}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_ERR_NOMEM))    {	return stream;    }    /* Stream seems good so we need to add the supplied element     */    stream->add(stream, oneElement, NULL);    return stream;}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_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;}/* Token rewrite 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_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_TOKEN_STREAM antlr3RewriteRuleTokenStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, void * oneElement){    pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;    /* First job is to create the memory we need.     */    stream	= antlr3RewriteRuleElementStreamNewAEE(adaptor, description, oneElement);    /* 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_TOKEN_STREAM antlr3RewriteRuleTokenStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, pANTLR3_VECTOR vector){    pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;    /* First job is to create the memory we need.     */    stream	= antlr3RewriteRuleElementStreamNewAEV(adaptor, description, vector);    /* Install the token based overrides     */    stream->dup	    = dupTok;    stream->toTree  = toTreeToken;    /* No nextNode implementation for a token rewrite stream */    return stream;}/* Subtree rewrite stream */ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description){    pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;    /* First job is to create the memory we need.     */    stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, description);    if (stream == (pANTLR3_REWRITE_RULE_SUBTREE_STREAM)(ANTLR3_ERR_NOMEM))    {	return stream;    }    /* Install the token based overrides     */    stream->dup		= dupTree;    stream->toTree	= toTreeTree;    stream->nextNode	= nextNode;    return stream;}ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, void * oneElement){    pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;    /* First job is to create the memory we need.     */    stream	= antlr3RewriteRuleElementStreamNewAEE(adaptor, description, oneElement);    if (stream == (pANTLR3_REWRITE_RULE_SUBTREE_STREAM)(ANTLR3_ERR_NOMEM))    {	return stream;    }    /* Install the token based overrides     */    stream->dup		= dupTree;    stream->toTree	= toTreeTree;    stream->nextNode	= nextNode;    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_ERR_NOMEM))    {	return stream;    }    /* Install the token based overrides     */    stream->dup		= dupTree;    stream->toTree	= toTreeTree;    stream->nextNode	= nextNode;    return stream;}/* Static support functions *//* Reset the condition of this stream so that it appears we have * not consumed any of its elements.  Elements themselves are untouched. */static void		reset    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    stream->cursor = 0;}/* Add a new pANTLR3_BASE_TREE to this stream */static void		add	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *)){    if (el== NULL)    {	return;    }    if (stream->elements != NULL)    {	/* We have already started with a vector, which means we already have >1	 * entries in the stream. So we can just add this new element to the existing	 * collection. 	 */	stream->elements->add(stream->elements, el, freePtr);	return;    }    if (stream->singleElement == NULL)    {	stream->singleElement = el;	return;    }    /* If we got here then we ahd only the one element so far     * and we must now create a vector to hold a collection of them     */    stream->elements = antlr3VectorNew(0);  /* We will let the vector figure things out as it goes */    stream->elements->add(stream->elements, stream->singleElement, NULL);    stream->elements->add(stream->elements, el, NULL);    stream->singleElement = NULL;    return;}/* Return the next element in the stream.  If out of elements, throw * an exception unless size()==1.  If size is 1, then return elements[0]. */static void *	next	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    ANTLR3_UINT32   s;    s = stream->size(stream);    if (stream->cursor >= s && s == 1)    {	pANTLR3_BASE_TREE el;	el = stream->_next(stream);	return	stream->dup(stream, el);    }    return stream->_next(stream);}/** 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)-1;	// 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)(-2);	// Caller must cope with this    }    // Elements available either for duping or just available    //    if (stream->singleElement != NULL)    {	stream->cursor++;   // Cursor advances even for insgle 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));  // TODO: Why not just cursor++ ?    stream->cursor++;    return t;}/* When constructing trees, sometimes we need to dup a token or AST * subtree.  Dup'ing a token means just creating another AST node * around it.  For trees, you must call the adaptor.dupTree(). */static void *	dupTok	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el){    return stream->adaptor->create(stream->adaptor, (pANTLR3_COMMON_TOKEN)el);}/* When constructing trees, sometimes we need to dup a token or AST * subtree.  Dup'ing a token means just creating another AST node * around it.  For trees, you must call the adaptor.dupTree(). */static void *	dupTree	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element){    return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);}/* Ensure stream emits trees; tokens must be converted to AST nodes. * AST nodes can be passed through unmolested. */static pANTLR3_BASE_TREE	toTreeToken   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element){    return stream->adaptor->create(stream->adaptor, (pANTLR3_COMMON_TOKEN) element);}/* Ensure stream emits trees; tokens must be converted to AST nodes. * AST nodes can be passed through unmolested. */#ifdef WIN32#pragma warning(push)#pragma warning(disable : 4100)#endifstatic pANTLR3_BASE_TREE	toTreeTree   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element){    return (pANTLR3_BASE_TREE)element;}#ifdef WIN32#pragma warning(pop)#endif/* Returns ANTLR3_TRUE if there is a next element available */static ANTLR3_BOOLEAN	hasNext  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    if (   (stream->singleElement != NULL && stream->cursor < 1)	|| stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements))    {	return ANTLR3_TRUE;    }    else    {	return ANTLR3_FALSE;    }}/* Treat next element as a single node even if it's a subtree. * This is used instead of next() when the result has to be a * tree root node.  Also prevents us from duplicating recently-added * children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration * must dup the type node, but ID has been added. * * Referencing to a rule result twice is ok; dup entire tree as * we can't be adding trees; e.g., expr expr.  */static pANTLR3_BASE_TREE	nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    ANTLR3_UINT32	s;    pANTLR3_BASE_TREE	el = stream->_next(stream);    s = stream->size(stream);    if (stream->cursor > s && s == 1)    {	// We are out of elements and the size is 1, whihc means we just 	// dup the node that we have	//	return	stream->adaptor->dupNode(stream->adaptor, el);    }    // We were not out of nodes, so the one we received is the one to return    //    return  el;}/* Number of elements avaiable in the stream */static ANTLR3_UINT32	size	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    ANTLR3_UINT32   n = 0;    /* Should be a count of one if singleElement is set. I copied this     * logic from the java implementation, which I suspect is just guarding     * against someone setting singleElement and forgetting to NULL it out     */    if (stream->singleElement != NULL)    {	n = 1;    }    if (stream->elements != NULL)    {	return stream->elements->count;    }    return n;}/* Returns the description string if there is one available (check for NULL). */static pANTLR3_STRING	getDescription  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream){    if (stream->elementDescription == NULL)    {	stream->elementDescription = stream->adaptor->strFactory->newPtr8(stream->adaptor->strFactory, (pANTLR3_UINT8)"<unknown source>", 14);    }    return  stream->elementDescription;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?