www.pudn.com > bison.zip > symtab.c


/* Symbol table manager for Bison, 
   Copyright (C) 1984, 1989 Free Software Foundation, Inc. 
 
This file is part of Bison, the GNU Compiler Compiler. 
 
Bison is free software; you can redistribute it and/or modify 
it under the terms of the GNU General Public License as published by 
the Free Software Foundation; either version 2, or (at your option) 
any later version. 
 
Bison is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU General Public License for more details. 
 
You should have received a copy of the GNU General Public License 
along with Bison; see the file COPYING.  If not, write to 
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
 
 
#include  
#include "system.h" 
#include "new.h" 
#include "symtab.h" 
#include "gram.h" 
 
 
bucket **symtab; 
bucket *firstsymbol; 
bucket *lastsymbol; 
 
 
 
int 
hash(key) 
char *key; 
{ 
  register char *cp; 
  register int k; 
 
  cp = key; 
  k = 0; 
  while (*cp) 
    k = ((k << 1) ^ (*cp++)) & 0x3fff; 
 
  return (k % TABSIZE); 
} 
 
 
 
char * 
copys(s) 
char *s; 
{ 
  register int i; 
  register char *cp; 
  register char *result; 
 
  i = 1; 
  for (cp = s; *cp; cp++) 
    i++; 
 
  result = xmalloc((unsigned int)i); 
  strcpy(result, s); 
  return (result); 
} 
 
 
void 
tabinit() 
{ 
/*   register int i; JF unused */ 
 
  symtab = NEW2(TABSIZE, bucket *); 
 
  firstsymbol = NULL; 
  lastsymbol = NULL; 
} 
 
 
bucket * 
getsym(key) 
char *key; 
{ 
  register int hashval; 
  register bucket *bp; 
  register int found; 
 
  hashval = hash(key); 
  bp = symtab[hashval]; 
 
  found = 0; 
  while (bp != NULL && found == 0) 
    { 
      if (strcmp(key, bp->tag) == 0) 
	found = 1; 
      else 
	bp = bp->link; 
    } 
 
  if (found == 0) 
    { 
      nsyms++; 
 
      bp = NEW(bucket); 
      bp->link = symtab[hashval]; 
      bp->next = NULL; 
      bp->tag = copys(key); 
      bp->class = SUNKNOWN; 
 
      if (firstsymbol == NULL) 
	{ 
	  firstsymbol = bp; 
	  lastsymbol = bp; 
	} 
      else 
	{ 
	  lastsymbol->next = bp; 
	  lastsymbol = bp; 
	} 
 
      symtab[hashval] = bp; 
    } 
 
  return (bp); 
} 
 
 
void 
free_symtab() 
{ 
  register int i; 
  register bucket *bp,*bptmp;/* JF don't use ptr after free */ 
 
  for (i = 0; i < TABSIZE; i++) 
    { 
      bp = symtab[i]; 
      while (bp) 
	{ 
	  bptmp = bp->link; 
#if 0 /* This causes crashes because one string can appear more than once.  */ 
	  if (bp->type_name) 
	    FREE(bp->type_name); 
#endif 
	  FREE(bp); 
	  bp = bptmp; 
	} 
    } 
  FREE(symtab); 
}