X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=ag%2Fsymbol_table.c;fp=ag%2Fsymbol_table.c;h=b28687fe6c4e58c1f63d997611badc1ef763da2a;hb=3512b27e407d7972f7ea0e17dc62b4cb9207a15a;hp=0000000000000000000000000000000000000000;hpb=39eefa2a8655d811052c518741fd92a08bcfd055;p=uebersetzerbau-ss10.git diff --git a/ag/symbol_table.c b/ag/symbol_table.c new file mode 100755 index 0000000..b28687f --- /dev/null +++ b/ag/symbol_table.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include "symbol_table.h" + +struct symbol_t *new_table(void) { + return (struct symbol_t *)NULL; +} + +struct symbol_t *clone_table(struct symbol_t *table) { + struct symbol_t *element; + struct symbol_t *new_tablex; + + element=table; + new_tablex=new_table(); + while((struct symbol_t *)NULL!=element) { + /* check return value */ + new_tablex=table_add_symbol(new_tablex,element->identifier,element->type,0); + element=element->next; + } + + return new_tablex; +} + +struct symbol_t *table_add_symbol(struct symbol_t *table, char *identifier, short type, short check) { + struct symbol_t *element; + struct symbol_t *new_element; + + if(table_lookup(table,identifier)!=(struct symbol_t *)NULL) { + if(check) { + fprintf(stderr,"Duplicate field %s.\n",identifier); + exit(3); + } + + table=table_remove_symbol(table,identifier); + } + + new_element=(struct symbol_t *)malloc(sizeof(struct symbol_t)); + new_element->next=(struct symbol_t *)NULL; + new_element->identifier=strdup(identifier); + new_element->type=type; + + if((struct symbol_t *)NULL==table) { + return new_element; + } + element=table; + + while((struct symbol_t *)NULL!=element->next) { + element=element->next; + } + + element->next=new_element; + + return table; +} + +struct symbol_t *table_lookup(struct symbol_t *table, char *identifier) { + struct symbol_t *element; + + element=table; + + if((struct symbol_t *)NULL==table) { + return (struct symbol_t *)NULL; + } + + if(strcmp(element->identifier,identifier)==0) { + return element; + } + + while((struct symbol_t *)NULL!=element->next) { + element=element->next; + if(strcmp(element->identifier,identifier)==0) { + return element; + } + } + + return (struct symbol_t *)NULL; +} + +struct symbol_t *table_merge(struct symbol_t *table, struct symbol_t *to_add, short check) { + struct symbol_t *element; + struct symbol_t *new_table=clone_table(table); + + element=to_add; + while(element!=(struct symbol_t *)NULL) { + new_table=table_add_symbol(new_table,element->identifier,element->type,check); + element=element->next; + } + + return new_table; +} + +struct symbol_t *table_remove_symbol(struct symbol_t *table, char *identifier) { + struct symbol_t *element; + struct symbol_t *previous_element; + struct symbol_t *new_element; + + if((struct symbol_t *)NULL==table) { + return table; + } + + previous_element=(struct symbol_t *)NULL; + element=table; + + while((struct symbol_t *)NULL!=element) { + if(strcmp(element->identifier,identifier)==0) { + if((struct symbol_t *)NULL==previous_element) { + new_element=element->next; + } + else { + previous_element->next=element->next; + new_element=table; + } + (void)free(element->identifier); + (void)free(element); + return new_element; + } + previous_element=element; + element=element->next; + } + + return table; +} + +void check_variable(struct symbol_t *table, char *identifier) { + struct symbol_t *element=table_lookup(table,identifier); + if(element!=(struct symbol_t *)NULL) { + if(element->type!=SYMBOL_TYPE_VAR) { + fprintf(stderr,"Identifier %s not a variable.\n",identifier); + exit(3); + } + } + else { + fprintf(stderr,"Unknown identifier %s.\n",identifier); + exit(3); + } +} + +void check_field(struct symbol_t *table, char *identifier) { + struct symbol_t *element=table_lookup(table,identifier); + if(element!=(struct symbol_t *)NULL) { + if(element->type!=SYMBOL_TYPE_FIELD) { + fprintf(stderr,"Identifier %s not a variable.\n",identifier); + exit(3); + } + } + else { + fprintf(stderr,"Unknown identifier %s.\n",identifier); + exit(3); + } +} +