/* (C) Copyright 2008 Nick Mudge * This code can be freely copied and modified. */ #include #include #include typedef enum {FALSE=0, TRUE=1} bool; typedef struct entry { char *str; int type; bool keyword; struct entry *next; } Entry; typedef struct symbol_table { int size; /* the size of the table */ Entry **table; /* the table elements */ } Symbol_table; Symbol_table *symbol_table; Symbol_table *create_symbol_table(int size); static unsigned int hash(char *str); Entry *add_to_symbol_table(char *str); Entry *look_up_symbol_table(char *str); int delete_from_symbol_table(char *str); void free_symbol_table(void); /* int main(void) { Entry *entry; symbol_table = create_symbol_table(5000); entry = add_to_symbol_table("testinghere"); printf("%s\n", entry->str); return 0; } */ Symbol_table *create_symbol_table(int size) { Symbol_table *new_table; int i; if (size<1) return NULL; if ((new_table = malloc(sizeof(Symbol_table))) == NULL) { return NULL; } if ((new_table->table = malloc(sizeof(Entry *) * size)) == NULL) { return NULL; } for(i=0; itable[i] = NULL; new_table->size = size; return new_table; } Entry *look_up_symbol_table(char *str) { Entry *entry; unsigned int hashval = hash(str); for(entry = symbol_table->table[hashval]; entry != NULL; entry = entry->next) { if (strcmp(str, entry->str) == 0) return entry; } return NULL; } Entry *add_to_symbol_table(char *str) { Entry *new_entry; Entry *current_entry; unsigned int hashval = hash(str); current_entry = look_up_symbol_table(str); if (current_entry != NULL) return current_entry; if ((new_entry = malloc(sizeof(Entry))) == NULL) return NULL; new_entry->str = malloc(sizeof(char) * (strlen(str) + 1)); strcpy(new_entry->str, str); new_entry->type = 0; new_entry->keyword = FALSE; new_entry->next = symbol_table->table[hashval]; symbol_table->table[hashval] = new_entry; return new_entry; } void add_keyword_to_symbol_table(char *str) { Entry *keyword_entry; keyword_entry = add_to_symbol_table(str); keyword_entry->keyword = TRUE; } int delete_from_symbol_table(char *str) { Entry *entry; Entry *prior_entry = NULL; unsigned int hashval = hash(str); for(entry = symbol_table->table[hashval]; entry != NULL; entry = entry->next) { if (strcmp(str, entry->str) == 0) { if(entry->next == NULL) { if(prior_entry == NULL) symbol_table->table[hashval] = NULL; else prior_entry->next = NULL; } else { if(prior_entry == NULL) symbol_table->table[hashval] = entry->next; else prior_entry->next = entry->next; } free(entry->str); free(entry); return 0; } prior_entry = entry; } return 1; } void free_symbol_table() { Entry *entry, *temp; int i; if (symbol_table==NULL) return; for(i=0; isize; i++) { entry = symbol_table->table[i]; while(entry!=NULL) { temp = entry; entry = entry->next; free(temp->str); free(temp); } } free(symbol_table->table); free(symbol_table); } static unsigned int hash(char *str) { unsigned int hash = 0; int c; while ((c = *str++)) hash = c + (hash << 6) + (hash << 16) - hash; return hash % symbol_table->size; }