⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 antlr3collections.c

📁 ANTLR(ANother Tool for Language Recognition)它是这样的一种工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/** \file * Provides a number of useful functions that are roughly equivalent * to java HashTable and List for the purposes of Antlr 3 C runtime. * Also useable by the C programmer for things like symbol tables pointers * and so on. * */#include    <antlr3.h>/* Interface functions for hash table */static void		    antlr3HashDelete    (pANTLR3_HASH_TABLE table, void * key);static void *		    antlr3HashGet	(pANTLR3_HASH_TABLE table, void * key);static pANTLR3_HASH_ENTRY   antlr3HashRemove    (pANTLR3_HASH_TABLE table, void * key);static ANTLR3_INT32	    antlr3HashPut	(pANTLR3_HASH_TABLE table, void * key, void * element, void (*freeptr)(void *));static void		    antlr3HashFree	(pANTLR3_HASH_TABLE table);static ANTLR3_UINT64	    antlr3HashSize	(pANTLR3_HASH_TABLE table);/* Interface functions for enumeration */static int	    antlr3EnumNext	    (pANTLR3_HASH_ENUM en, void ** key, void ** data);static void	    antlr3EnumFree	    (pANTLR3_HASH_ENUM en);/* Interface functions for List */static void		antlr3ListFree	(pANTLR3_LIST list);static void		antlr3ListDelete(pANTLR3_LIST list, ANTLR3_UINT64 key);static void *		antlr3ListGet	(pANTLR3_LIST list, ANTLR3_UINT64 key);static ANTLR3_INT32	antlr3ListPut	(pANTLR3_LIST list, ANTLR3_UINT64 key, void * element, void (*freeptr)(void *));static ANTLR3_INT32	antlr3ListAdd   (pANTLR3_LIST list, void * element, void (*freeptr)(void *));static void *		antlr3ListRemove(pANTLR3_LIST list, ANTLR3_UINT64 key);static ANTLR3_UINT64	antlr3ListSize	(pANTLR3_LIST list);/* Interface functions for Stack */static void		antlr3StackFree	(pANTLR3_STACK  stack);static void		antlr3StackPop	(pANTLR3_STACK	stack);static void *		antlr3StackGet	(pANTLR3_STACK	stack, ANTLR3_UINT64 key);static ANTLR3_BOOLEAN	antlr3StackPush	(pANTLR3_STACK	stack, void * element, void (*freeptr)(void *));static ANTLR3_UINT64	antlr3StackSize	(pANTLR3_STACK	stack);static void *		antlr3StackPeek	(pANTLR3_STACK	stack);/* Interface functions for vectors */static	void		antlr3VectorFree    (pANTLR3_VECTOR vector);static	void		antlr3VectorDel	    (pANTLR3_VECTOR vector, ANTLR3_UINT64 entry);static	void *		antlr3VectorGet     (pANTLR3_VECTOR vector, ANTLR3_UINT64 entry);static	void *		antrl3VectorRemove  (pANTLR3_VECTOR vector, ANTLR3_UINT64 entry);static	ANTLR3_INT32    antlr3VectorAdd	    (pANTLR3_VECTOR vector, void * element, void (*freeptr)(void *));static	ANTLR3_INT32    antlr3VectorPut	    (pANTLR3_VECTOR vector, ANTLR3_UINT64 entry, void * element, void (*freeptr)(void *));static	ANTLR3_UINT64   antlr3VectorSize    (pANTLR3_VECTOR vector);static  void		closeVectorFactory  (pANTLR3_VECTOR_FACTORY factory);static	pANTLR3_VECTOR  newVector	    (pANTLR3_VECTOR_FACTORY factory);/* Local function to advance enumeration structure pointers */static void antlr3EnumNextEntry(pANTLR3_HASH_ENUM en);pANTLR3_HASH_TABLEantlr3HashTableNew(ANTLR3_UINT32 sizeHint){    /* All we have to do is create the hashtable tracking structure     * and allocate memory for the requested number of buckets.     */    pANTLR3_HASH_TABLE	table;        ANTLR3_UINT32	bucket;	/* Used to traverse the buckets	*/    table   = ANTLR3_MALLOC(sizeof(ANTLR3_HASH_TABLE));    /* Error out if no memory left */    if	(table	== NULL)    {	return	(pANTLR3_HASH_TABLE) ANTLR3_ERR_NOMEM;    }    /* Allocate memory for the buckets     */    table->buckets = (pANTLR3_HASH_BUCKET) ANTLR3_MALLOC((size_t) (sizeof(ANTLR3_HASH_BUCKET) * sizeHint));     if	(table->buckets == NULL)    {	ANTLR3_FREE((void *)table);	return	(pANTLR3_HASH_TABLE) ANTLR3_ERR_NOMEM;    }    /* Modulo of the table, (bucket count).     */    table->modulo   = sizeHint;    table->count    = 0;	    /* Nothing in there yet ( I hope)	*/    /* Initialize the buckets to empty     */    for	(bucket = 0; bucket < sizeHint; bucket++)    {	table->buckets[bucket].entries = NULL;    }    /* Exclude duplicate entries by default     */    table->allowDups	= ANTLR3_FALSE;    /* Install the interface     */    table->free		=  antlr3HashFree;    table->get		=  antlr3HashGet;    table->put		=  antlr3HashPut;    table->del		=  antlr3HashDelete;    table->size		=  antlr3HashSize;    table->remove	=  antlr3HashRemove;    return  table;}static voidantlr3HashFree(pANTLR3_HASH_TABLE table){    ANTLR3_UINT32	bucket;	/* Used to traverse the buckets	*/    pANTLR3_HASH_BUCKET	thisBucket;    pANTLR3_HASH_ENTRY	entry;    pANTLR3_HASH_ENTRY	nextEntry;    /* Free the table, all buckets and all entries, and all the     * keys and data (if the table exists)     */    if	(table	!= NULL)    {	for	(bucket = 0; bucket < table->modulo; bucket++)	{	    thisBucket	= &(table->buckets[bucket]);	    /* Allow sparse tables, though we don't create them as such at present	     */	    if	( thisBucket != NULL)	    {		entry	= thisBucket->entries;		/* Search all entries in the bucket and free them up		 */		while	(entry != NULL)		{		    /* Save next entry - we do not want to access memory in entry after we		     * have freed it.		     */		    nextEntry	= entry->nextEntry;		    /* Free any data pointer, this only happens if the user supplied		     * a pointer to a routine that knwos how to free the structure they		     * added to the table.		     */		    if	(entry->free != NULL)		    {			entry->free(entry->data);		    }		    /* Free the key memory - we know that we allocated this		     */		    if	(entry->key != NULL)		    {			ANTLR3_FREE(entry->key);		    }		    /* Free this entry		     */		    ANTLR3_FREE(entry);		    entry   = nextEntry;    /* Load next pointer to see if we shoud free it */		}		/* Invalidate the current pointer		 */		thisBucket->entries = NULL;	    }	}	/* Now we can free the bucket memory	 */	ANTLR3_FREE(table->buckets);    }    /* Now we free teh memory for the table itself     */    ANTLR3_FREE(table);}/** return the current size of the hash table */static ANTLR3_UINT64	antlr3HashSize	    (pANTLR3_HASH_TABLE table){    return  table->count;}/** Remove the element in the hash table for a particular *  key value, if it exists - no error if it does not. */static pANTLR3_HASH_ENTRYantlr3HashRemove(pANTLR3_HASH_TABLE table, void * key){    ANTLR3_UINT32	    hash;    pANTLR3_HASH_BUCKET	    bucket;    pANTLR3_HASH_ENTRY	    entry;    pANTLR3_HASH_ENTRY	    * nextPointer;    /* First we need to know the hash of the provided key     */    hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));    /* Knowing the hash, we can find the bucket     */    bucket  = table->buckets + (hash % table->modulo);    /* Now, we traverse the entries in the bucket until     * we find the key or the end of the entires in the bucket.      * We track the element prior to the one we are exmaining     * as we need to set its next pointer to the next pointer     * of the entry we are deleting (if we find it).     */    entry	    =   bucket->entries;    /* Entry to examine					    */    nextPointer	    = & bucket->entries;    /* Where to put the next pointer of the deleted entry   */    while   (entry != NULL)    {	/* See if this is the entry we wish to delete	 */	if  (strcmp((const char *)key, (const char *)entry->key) == 0)	{	    /* It was the correct entry, so we set the next pointer	     * of the previous entry to the next pointer of this	     * located one, which takes it out of the chain.	     */	    (*nextPointer)		= entry->nextEntry;	    /* Release the key - we allocated that	     */	    ANTLR3_FREE(entry->key);	    entry->key	= NULL;	    table->count--;	    return entry;	}	else	{	    /* We found an entry but it wasn't the one that was wanted, so	     * move to the next one, if any.	     */	    nextPointer	= & (entry->nextEntry);	    /* Address of the next pointer in the current entry	    */	    entry	= entry->nextEntry;	    /* Address of the next element in the bucket (if any)   */	}    }    return NULL;  /* Not found */}/** Takes the element with the supplied key out of the list, and deletes the data *  calling the supplied free() routine if any.  */static voidantlr3HashDelete    (pANTLR3_HASH_TABLE table, void * key){    pANTLR3_HASH_ENTRY	entry;    entry = antlr3HashRemove(table, key);	    /* Now we can free the elements and the entry in order     */    if	(entry != NULL && entry->free != NULL)    {	/* Call programmer supplied function to release this entry data	 */	entry->free(entry->data);	entry->data = NULL;    }    /* Finally release the space for this entry block.     */    ANTLR3_FREE(entry);}/** Return the element pointer in the hash table for a particular *  key value, or NULL if it don't exist (or was itself NULL). */static void *antlr3HashGet(pANTLR3_HASH_TABLE table, void * key){    ANTLR3_UINT32	    hash;    pANTLR3_HASH_BUCKET	    bucket;    pANTLR3_HASH_ENTRY	    entry;    /* First we need to know the hash of the provided key     */    hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));    /* Knowing the hash, we can find the bucket     */    bucket  = table->buckets + (hash % table->modulo);    /* Now we can inspect the key at each entry in the bucket     * and see if we have a match.     */    entry   = bucket->entries;    while   (entry != NULL)    {	if  (strcmp((const char *)key, (const char *)entry->key) == 0)	{	    /* Match was found, return the data pointer for this entry	     */	    return  entry->data;	}	entry = entry->nextEntry;    }    /* If we got here, then we did not find the key     */    return  NULL;}/** Add the element pointer in to the table, based upon the  *  hash of the provided key. */static	ANTLR3_INT32antlr3HashPut(pANTLR3_HASH_TABLE table, void * key, void * element, void (*freeptr)(void *)){    ANTLR3_UINT32	    hash;    pANTLR3_HASH_BUCKET	    bucket;    pANTLR3_HASH_ENTRY	    entry;    pANTLR3_HASH_ENTRY	    * newPointer;    /* First we need to know the hash of the provided key     */    hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));    /* Knowing the hash, we can find the bucket     */    bucket  = table->buckets + (hash % table->modulo);    /* Knowign the bucket, we can traverse the entries until we     * we find a NULL pointer ofr we find that this is already      * in the table and duplicates were not allowed.     */    newPointer	= &bucket->entries;    while   (*newPointer !=  NULL)    {	/* The value at new pointer is pointing to an existing entry.	 * If duplicates are allowed then we don't care what it is, but	 * must reject this add if the key is the same as the one we are	 * supplied with.	 */	if  (table->allowDups == ANTLR3_FALSE)	{	    if	(strcmp((const char*) key, (const char *)(*newPointer)->key) == 0)	    {		return	ANTLR3_ERR_HASHDUP;	    }	}	/* Point to the next entry pointer of the current entry we	 * are traversing, if it is NULL we will create our new	 * structure and point this to it.	 */	newPointer = &((*newPointer)->nextEntry);    }    /* newPointer is now poiting at the pointer where we need to     * add our new entry, so let's crate the entry and add it in.     */    entry   = (pANTLR3_HASH_ENTRY)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENTRY));    if	(entry == NULL)    {	return	ANTLR3_ERR_NOMEM;    }	    entry->data		= element;		/* Install the data element supplied		    */    entry->free		= freeptr;		/* Function that knows how to release the entry	    */    entry->key		= ANTLR3_STRDUP(key);	/* Record the key value				    */    entry->nextEntry	= NULL;			/* Ensure that the forward pointer ends the chain   */    *newPointer	= entry;    /* Install the next entry in this bucket	*/    table->count++;    return  ANTLR3_SUCCESS;}

⌨️ 快捷键说明

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