#include #include #include #include "symtable.h" struct symbol *new_tab(void) { return SYMNULL; } struct symbol *clone_tab(struct symbol *tab) { struct symbol *elm; struct symbol *new_tabx; elm = tab; new_tabx = new_tab(); while(elm != SYMNULL) { new_tabx = tab_add_symbol(new_tabx, elm->ident, elm->type, 0); elm = elm->next; } return new_tabx; } struct symbol *tab_add_symbol(struct symbol *tab, char *ident, short type, short check) { struct symbol *elm; struct symbol *new_elm; if(tab_lookup(tab,ident) != SYMNULL) { if(check) { fprintf(stderr, "Feld doppelt vorhanden: \"%s\"\n", ident); exit(3); } tab = tab_remove_symbol(tab, ident); } new_elm = (struct symbol *) malloc(sizeof(struct symbol)); new_elm->next = SYMNULL; new_elm->ident = strdup(ident); new_elm->type = type; if(tab == SYMNULL) { return new_elm; } elm = tab; while(elm->next != SYMNULL) { elm = elm->next; } elm->next = new_elm; return tab; } struct symbol *tab_lookup(struct symbol *tab, char *ident) { struct symbol *elm = tab; if(tab == SYMNULL) { return SYMNULL; } if(strcmp(elm->ident, ident) == 0) { return elm; } while(elm->next != SYMNULL) { elm = elm->next; if(strcmp(elm->ident, ident) == 0) { return elm; } } return SYMNULL; } struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check) { struct symbol *elm = to_add; struct symbol *new_tab = clone_tab(tab); while(elm != SYMNULL) { new_tab = tab_add_symbol(new_tab, elm->ident, elm->type, check); elm = elm->next; } return new_tab; } struct symbol *tab_remove_symbol(struct symbol *tab, char *ident) { struct symbol *elm = tab; struct symbol *previous_elm = SYMNULL; struct symbol *new_elm; if(tab == SYMNULL) { return SYMNULL; } while(elm != SYMNULL) { if(strcmp(elm->ident, ident) == 0) { if(previous_elm == SYMNULL) { new_elm = elm->next; } else { previous_elm->next = elm->next; new_elm = tab; } (void)free(elm->ident); (void)free(elm); return new_elm; } previous_elm = elm; elm = elm->next; } return tab; } void check_variable(struct symbol *tab, char *ident) { struct symbol *elm = tab_lookup(tab, ident); if(elm != SYMNULL) { if(elm->type != S_VAR) { fprintf(stderr, "Identifier ist keine Variable: \"%s\"\n", ident); exit(3); } } else { fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident); exit(3); } } void check_field(struct symbol *tab, char *ident) { struct symbol *elm = tab_lookup(tab, ident); if(elm != SYMNULL) { if(elm->type != S_FIELD) { fprintf(stderr, "Identifier ist kein Feld: \"%s\"\n", ident); exit(3); } } else { fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident); exit(3); } }