|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)hash.c 1.1 8/27/80"; ! 4: ! 5: #include "whoami.h" ! 6: #include "0.h" ! 7: #include "yy.h" ! 8: ! 9: /* ! 10: * The definition for the segmented hash tables. ! 11: */ ! 12: struct ht { ! 13: int *ht_low; ! 14: int *ht_high; ! 15: int ht_used; ! 16: } htab[MAXHASH]; ! 17: ! 18: /* ! 19: * This is the array of keywords and their ! 20: * token values, which are hashed into the table ! 21: * by inithash. ! 22: */ ! 23: struct kwtab yykey[] = { ! 24: "and", YAND, ! 25: "array", YARRAY, ! 26: "assert", YASSERT, ! 27: "begin", YBEGIN, ! 28: "case", YCASE, ! 29: "const", YCONST, ! 30: "div", YDIV, ! 31: "do", YDO, ! 32: "downto", YDOWNTO, ! 33: "else", YELSE, ! 34: "end", YEND, ! 35: "file", YFILE, ! 36: "for", YFOR, ! 37: "forward", YFORWARD, ! 38: "function", YFUNCTION, ! 39: "goto", YGOTO, ! 40: "if", YIF, ! 41: "in", YIN, ! 42: "label", YLABEL, ! 43: "mod", YMOD, ! 44: "nil", YNIL, ! 45: "not", YNOT, ! 46: "of", YOF, ! 47: "or", YOR, ! 48: "packed", YPACKED, ! 49: "procedure", YPROCEDURE, ! 50: "program", YPROG, ! 51: "record", YRECORD, ! 52: "repeat", YREPEAT, ! 53: "set", YSET, ! 54: "then", YTHEN, ! 55: "to", YTO, ! 56: "type", YTYPE, ! 57: "until", YUNTIL, ! 58: "var", YVAR, ! 59: "while", YWHILE, ! 60: "with", YWITH, ! 61: "oct", YOCT, /* non-standard Pascal */ ! 62: "hex", YHEX, /* non-standard Pascal */ ! 63: "external", YEXTERN, /* non-standard Pascal */ ! 64: 0 ! 65: }; ! 66: ! 67: char *lastkey = &yykey[sizeof yykey/sizeof yykey[0]]; ! 68: ! 69: /* ! 70: * Inithash initializes the hash table routines ! 71: * by allocating the first hash table segment using ! 72: * an already existing memory slot. ! 73: */ ! 74: #ifndef PI0 ! 75: inithash() ! 76: #else ! 77: inithash(hshtab) ! 78: int *hshtab; ! 79: #endif ! 80: { ! 81: register int *ip; ! 82: #ifndef PI0 ! 83: static int hshtab[HASHINC]; ! 84: #endif ! 85: ! 86: htab[0].ht_low = hshtab; ! 87: htab[0].ht_high = &hshtab[HASHINC]; ! 88: for (ip = yykey; *ip; ip += 2) ! 89: hash(ip[0], 0)[0] = ip; ! 90: } ! 91: ! 92: /* ! 93: * Hash looks up the s(ymbol) argument ! 94: * in the string table, entering it if ! 95: * it is not found. If save is 0, then ! 96: * the argument string is already in ! 97: * a safe place. Otherwise, if hash is ! 98: * entering the symbol for the first time ! 99: * it will save the symbol in the string ! 100: * table using savestr. ! 101: */ ! 102: int *hash(s, save) ! 103: char *s; ! 104: int save; ! 105: { ! 106: register int *h; ! 107: register i; ! 108: register char *cp; ! 109: int *sym; ! 110: struct ht *htp; ! 111: int sh; ! 112: ! 113: /* ! 114: * The hash function is a modular hash of ! 115: * the sum of the characters with the sum ! 116: * doubled before each successive character ! 117: * is added. ! 118: */ ! 119: cp = s; ! 120: if (cp == NIL) ! 121: cp = token; /* default symbol to be hashed */ ! 122: i = 0; ! 123: while (*cp) ! 124: i = i*2 + *cp++; ! 125: sh = (i&077777) % HASHINC; ! 126: cp = s; ! 127: if (cp == NIL) ! 128: cp = token; ! 129: /* ! 130: * There are as many as MAXHASH active ! 131: * hash tables at any given point in time. ! 132: * The search starts with the first table ! 133: * and continues through the active tables ! 134: * as necessary. ! 135: */ ! 136: for (htp = htab; htp < &htab[MAXHASH]; htp++) { ! 137: if (htp->ht_low == NIL) { ! 138: cp = (char *) calloc(sizeof ( int * ), HASHINC); ! 139: if (cp == -1) { ! 140: yerror("Ran out of memory (hash)"); ! 141: pexit(DIED); ! 142: } ! 143: htp->ht_low = cp; ! 144: htp->ht_high = htp->ht_low + HASHINC; ! 145: cp = s; ! 146: if (cp == NIL) ! 147: cp = token; ! 148: } ! 149: h = htp->ht_low + sh; ! 150: /* ! 151: * quadratic rehash increment ! 152: * starts at 1 and incremented ! 153: * by two each rehash. ! 154: */ ! 155: i = 1; ! 156: do { ! 157: if (*h == 0) { ! 158: if (htp->ht_used > (HASHINC * 3)/4) ! 159: break; ! 160: htp->ht_used++; ! 161: if (save != 0) { ! 162: *h = (int) savestr(cp); ! 163: } else ! 164: *h = s; ! 165: return (h); ! 166: } ! 167: sym = *h; ! 168: if (sym < lastkey && sym >= yykey) ! 169: sym = *sym; ! 170: if (sym->pchar == *cp && strcmp(sym, cp) == 0) ! 171: return (h); ! 172: h += i; ! 173: i += 2; ! 174: if (h >= htp->ht_high) ! 175: h -= HASHINC; ! 176: } while (i < HASHINC); ! 177: } ! 178: yerror("Ran out of hash tables"); ! 179: pexit(DIED); ! 180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.