hash.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:5k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * hash.c
  3.  *
  4.  * Manage hash tables.
  5.  *
  6.  * The following functions are visible:
  7.  *
  8.  * char *mystrdup(char *); Make space and copy string
  9.  * Entry  **newHashTable(); Create and return initialized hash table
  10.  * Entry *hash_add(Entry **, char *, Entry *)
  11.  * Entry *hash_get(Entry **, char *)
  12.  *
  13.  * SOFTWARE RIGHTS
  14.  *
  15.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  16.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  17.  * company may do whatever they wish with source code distributed with
  18.  * PCCTS or the code generated by PCCTS, including the incorporation of
  19.  * PCCTS, or its output, into commerical software.
  20.  *
  21.  * We encourage users to develop software with PCCTS.  However, we do ask
  22.  * that credit is given to us for developing PCCTS.  By "credit",
  23.  * we mean that if you incorporate our source code into one of your
  24.  * programs (commercial product, research project, or otherwise) that you
  25.  * acknowledge this fact somewhere in the documentation, research report,
  26.  * etc...  If you like PCCTS and have developed a nice tool with the
  27.  * output, please mention that you developed it using PCCTS.  In
  28.  * addition, we ask that this header remain intact in our source code.
  29.  * As long as these guidelines are kept, we expect to continue enhancing
  30.  * this system and expect to make other tools available as they are
  31.  * completed.
  32.  *
  33.  * ANTLR 1.33
  34.  * Terence Parr
  35.  * Parr Research Corporation
  36.  * with Purdue University and AHPCRC, University of Minnesota
  37.  * 1989-1998
  38.  */
  39. #include <stdio.h>
  40. #include "pcctscfg.h"
  41. #ifdef __cplusplus
  42. #ifndef __STDC__
  43. #define __STDC__
  44. #endif
  45. #endif
  46. #include "hash.h"
  47. #ifdef __STDC__
  48. #include <stdlib.h>
  49. #else
  50. #ifdef VAXC
  51. #include <stdlib.h>
  52. #else
  53. #include <malloc.h>
  54. #endif
  55. #endif
  56. #include <string.h>
  57. #define StrSame 0
  58. #define fatal(err)
  59. {fprintf(stderr, "%s(%d):", __FILE__, __LINE__);
  60. fprintf(stderr, " %sn", err); exit(PCCTS_EXIT_FAILURE);}
  61. #define require(expr, err) {if ( !(expr) ) fatal(err);}
  62. static unsigned size = HashTableSize;
  63. static char *strings = NULL;
  64. static char *strp;
  65. static unsigned strsize = StrTableSize;
  66. /* create the hash table and string table for terminals (string table only once) */
  67. Entry **
  68. #ifdef __STDC__
  69. newHashTable( void )
  70. #else
  71. newHashTable( )
  72. #endif
  73. {
  74. Entry **table;
  75. table = (Entry **) calloc(size, sizeof(Entry *));
  76. require( table != NULL, "cannot allocate hash table");
  77. if ( strings == NULL )
  78. {
  79. strings = (char *) calloc(strsize, sizeof(char));
  80. require( strings != NULL, "cannot allocate string table");
  81. strp = strings;
  82. }
  83. return table;
  84. }
  85. void
  86. #ifdef __STDC__
  87. killHashTable( Entry **table )
  88. #else
  89. killHashTable( table )
  90. Entry **table;
  91. #endif
  92. {
  93. /* for now, just free table, forget entries */
  94. free( (char *) table );     /* MR10 cast */
  95. }
  96. /* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */
  97. Entry *
  98. #ifdef __STDC__
  99. hash_add( Entry **table, char *key, Entry *rec )
  100. #else
  101. hash_add( table, key, rec )
  102. Entry **table;
  103. char *key;
  104. Entry *rec;
  105. #endif
  106. {
  107. unsigned h=0;
  108. char *p=key;
  109. extern Entry *Globals;
  110. require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition");
  111. Hash(p,h,size);
  112. rec->next = table[h]; /* Add to singly-linked list */
  113. table[h] = rec;
  114. return rec;
  115. }
  116. /* Return ptr to 1st entry found in table under key (return NULL if none found) */
  117. Entry *
  118. #ifdef __STDC__
  119. hash_get( Entry **table, char *key )
  120. #else
  121. hash_get( table, key )
  122. Entry **table;
  123. char *key;
  124. #endif
  125. {
  126. unsigned h=0;
  127. char *p=key;
  128. Entry *q;
  129. /* require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/
  130. if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3;
  131. Hash(p,h,size);
  132. for (q = table[h]; q != NULL; q = q->next)
  133. {
  134. if ( strcmp(key, q->str) == StrSame ) return( q );
  135. }
  136. return( NULL );
  137. }
  138. #ifdef DEBUG_HASH
  139. void
  140. #ifdef __STDC__
  141. hashStat( Entry **table )
  142. #else
  143. hashStat( table )
  144. Entry **table;
  145. #endif
  146. {
  147. static unsigned short count[20];
  148. int i,n=0,low=0, hi=0;
  149. Entry **p;
  150. float avg=0.0;
  151. for (i=0; i<20; i++) count[i] = 0;
  152. for (p=table; p<&(table[size]); p++)
  153. {
  154. Entry *q = *p;
  155. int len;
  156. if ( q != NULL && low==0 ) low = p-table;
  157. len = 0;
  158. if ( q != NULL ) fprintf(stderr, "[%d]", p-table);
  159. while ( q != NULL )
  160. {
  161. len++;
  162. n++;
  163. fprintf(stderr, " %s", q->str);
  164. q = q->next;
  165. if ( q == NULL ) fprintf(stderr, "n");
  166. }
  167. count[len]++;
  168. if ( *p != NULL ) hi = p-table;
  169. }
  170. fprintf(stderr, "Storing %d recs used %d hash positions out of %dn",
  171. n, size-count[0], size);
  172. fprintf(stderr, "%f %% utilizationn",
  173. ((float)(size-count[0]))/((float)size));
  174. for (i=0; i<20; i++)
  175. {
  176. if ( count[i] != 0 )
  177. {
  178. avg += (((float)(i*count[i]))/((float)n)) * i;
  179. fprintf(stderr, "Bucket len %d == %d (%f %% of recs)n",
  180. i, count[i], ((float)(i*count[i]))/((float)n));
  181. }
  182. }
  183. fprintf(stderr, "Avg bucket length %fn", avg);
  184. fprintf(stderr, "Range of hash function: %d..%dn", low, hi);
  185. }
  186. #endif
  187. /* Add a string to the string table and return a pointer to it.
  188.  * Bump the pointer into the string table to next avail position.
  189.  */
  190. char *
  191. #ifdef __STDC__
  192. mystrdup( char *s )
  193. #else
  194. mystrdup( s )
  195. char *s;
  196. #endif
  197. {
  198. char *start=strp;
  199. require(s!=NULL, "mystrdup: NULL string");
  200. while ( *s != '' )
  201. {
  202. require( strp <= &(strings[strsize-2]),
  203.  "string table overflownIncrease StrTableSize in hash.h and recompile hash.cn");
  204. *strp++ = *s++;
  205. }
  206. *strp++ = '';
  207. return( start );
  208. }