⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symtab.c

📁 浙江大学编译原理课程设计源代码,高等院校计算机专业
💻 C
字号:
#define   SYMTABC#include  <stdio.h>#include  <stdlib.h>#include  <string.h>#include  <ctype.h>#include  "common.h"#include  "error.h"#include  "symtab.h"#include  _YTAB_H_#define  SYMTAB_QUEUE_SIZE 128#define  SYMTAB_STACK_SIZE 64int const_index;int var_index;int arg_index;int cur_level;int routine_id;int last_symtab=0;int align(int);int symtab_tos = SYMTAB_STACK_SIZE - 1;symtab *symtab_queue[SYMTAB_QUEUE_SIZE];symtab *Global_symtab;symtab *System_symtab[MAX_SYS_ROUTINE];symtab *symtab_stack[SYMTAB_STACK_SIZE];extern int Keytable_size;int align(int bytes){    while (bytes % 2)        bytes++;    return bytes;}void enter_symtab_queue(symtab *tab){    if (last_symtab < SYMTAB_QUEUE_SIZE)        symtab_queue[last_symtab ++] = tab;}symtab *new_symtab(symtab *parent){    symtab *p;    /* p = (symtab *)malloc(sizeof(symtab)); */    NEW0(p, PERM);    if(!p)        internal_error("insufficient memory.");    p->parent = parent;    p->args_size = 0;    p->args = NULL;    p->localtab = NULL;    p->locals = NULL;    p->type_link = NULL;    if(parent)    {        p->level = parent->level+1;    }    else    {        routine_id = 0;        Global_symtab = p;        Cur_level = 0;        p->level = 0;    }    p->defn = DEF_UNKNOWN;    p->type = find_type_by_id(TYPE_VOID);    p->id = routine_id++;    p->local_size = 0;    enter_symtab_queue(p);    return p;}symbol *new_symbol(char *name, int defn, int typeid){    symbol *p;    static int imp_index = 0;    /* p = (symbol *)malloc(sizeof(symbol)); */    NEW0(p, PERM);    if(!p)        internal_error("insuffceent memory.");    if(!strcmp(name,"$$$"))        sprintf(p->name,"z%d",++imp_index);    else        strncpy(p->name, name, NAME_LEN);    p->rname[0]= '\0';    p->defn = defn;    p->type = find_type_by_id(typeid);    p->offset = 0;    p->next = NULL;    p->lchild = p->rchild = NULL;    p->tab = NULL;    p->type_link = NULL;    return p;}symbol *clone_symbol(symbol *origin){    symbol *p;    if(!origin)        return NULL;    /* p = (symbol *)malloc(sizeof(symbol)); */    NEW0(p, PERM);    if(!p)        internal_error("insuffident memory.");    strncpy(p->name,origin->name,NAME_LEN);    strncpy(p->name,origin->rname,LABEL_LEN);    p->defn = origin->defn;    p->type = origin->type;    p->offset = 0;    p->next = NULL;    p->tab = NULL;    if (p->type->type_id == TYPE_STRING)        p->v.s = strdup(origin->v.s);    else        p->v.f = origin->v.f;    return p;}symbol *clone_symbol_list(symbol *head){    symbol *new_list;    symbol *p;    symbol *q;    if(!head)        return NULL;    q = head;    new_list = p = clone_symbol(q);    q = p->next;    while(q)    {        p->next = clone_symbol(q);        p = p->next;        q = q->next;    }    p->next = NULL;    return new_list;}symbol *reverse_parameters(symtab *ptab){    symbol *p,*q;    symbol *new_list = NULL;    for(p = ptab->args;p;)    {        q = p;        p = p->next;        q->next = new_list;        new_list = q;    }    ptab->args = new_list;    return ptab->args;}void add_symbol_to_table(symtab*tab, symbol *sym){    switch(sym->defn)    {    case DEF_FUNCT:    case DEF_PROC:    case DEF_VAR:    case DEF_CONST:        add_local_to_table(tab, sym);        break;    case DEF_VARPARA:    case DEF_VALPARA:        add_args_to_table(tab,sym);        break;    case DEF_PROG:    default:        break;    }}void add_var_to_localtab(symtab *tab,symbol *sym){    symbol *p;    int i;    if (!tab || !sym)        return;    if(!tab->localtab)    {        tab->localtab = sym;        return;    }    p = tab->localtab;    while(1)    {        i = strcmp(sym->name, p->name);        if(i > 0)        {            if(p->rchild)                p = p->rchild;            else            {                p->rchild = sym;                break;            }        }        else if (i < 0)        {            if (p->lchild)                p = p->lchild;            else            {                p->lchild = sym;                break;            }        }        else        {            parse_error("Duplicate identifier.",                        sym->name);            break;        }    }}void add_local_to_table(symtab *tab,symbol *sym){    if(!tab|| !sym)        return;    if(sym->defn == DEF_CONST)        sprintf(sym->rname, "c%c_%03d",                sym->name[0],new_index(const));    else        sprintf(sym->rname, "v%c_%03d",                sym->name[0],new_index(var));    if(tab->level)    {        if(tab->defn == DEF_FUNCT                && sym->defn != DEF_FUNCT)        {            sym->offset = tab->local_size + 3 * IR->intmetric.size;            tab->local_size += align(get_symbol_size(sym));        }        else if (tab->defn == DEF_PROC                 && sym->defn != DEF_PROC)        {            sym->offset = tab->local_size + IR->intmetric.size;            tab->local_size += align(get_symbol_size(sym));        }    }    sym->next = tab->locals;    tab->locals=sym;    sym->tab = tab;    add_var_to_localtab(tab,sym);}void add_args_to_table(symtab *tab, symbol *sym){    symbol *p;    int var_size;    if(!tab|| !sym)        return;    sym->next = tab->args;    tab->args = sym;    sym->tab = tab;    sym->offset = 3 * IR->intmetric.size;    sprintf(sym->rname,"a%c_%03d",            sym->name[0],new_index(arg));    var_size = align(get_symbol_size(sym));    tab->args_size += var_size;    for(p = tab->args->next; p; p = p->next)        p->offset += var_size;    add_var_to_localtab(tab,sym);}extern KEYENTRY Keytable[];void make_system_symtab(){    int i,n;    symtab *ptab;    type *pt;    for(i = 0; i < MAX_SYS_ROUTINE; i++)        System_symtab[i] = NULL;    /* System_symtab[0]=    		(symtab*)malloc(sizeof(symtab));    */    NEW0(ptab, PERM);    System_symtab[0] = ptab;    if(!System_symtab)        internal_error("Insuflicent memory. ");    ptab = System_symtab[0];    sprintf(ptab->name,"system_table");    sprintf(ptab->rname, "null");    ptab->type_link=        new_system_type(TYPE_INTEGER);    pt = ptab->type_link;    pt->next = new_system_type(TYPE_CHAR);    pt = pt->next;    pt->next = new_system_type(TYPE_BOOLEAN);    pt = pt->next;    pt->next = new_system_type(TYPE_REAL);    pt = pt->next;    pt->next = new_system_type(TYPE_VOID);    pt = pt->next;    pt->next = new_system_type(TYPE_STRING);    pt = pt->next;    pt->next = new_system_type(TYPE_UNKNOWN);    pt = pt->next;    push_symtab_stack(ptab);    ptab->id=-1;    ptab->level=-1;    ptab->defn = DEF_UNKNOWN;    ptab->type = TYPE_UNKNOWN;    ptab->local_size = 0;    ptab->args_size = 0;    ptab->args = NULL;    ptab->parent = NULL;    ptab->locals = new_symbol("",DEF_UNKNOWN,                              TYPE_UNKNOWN);    n = 1;    /* for(i = 0 ; i < MAX_SYS_ROUTINE; i++){ */    for(i = 0 ; i < Keytable_size; i++)    {        if(Keytable[i].key == SYS_FUNCT ||                Keytable[i].key == SYS_PROC )        {            System_symtab[n]=                new_sys_symbol(Keytable[i]);            n++;        }        else if (Keytable[i].key == LAST_ENTRY)            break;    }    pop_symtab_stack();    ptab->local_size = n;}symtab* new_sys_symbol(KEYENTRY entry){    symtab *ptab;    symbol *p;    /* ptab = (symtab*)malloc(sizeof(symtab)); */    NEW0(ptab, PERM);    if(!ptab)        internal_error("Insufticent  memoy.");    strcpy(ptab->name, entry.name);    sprintf(ptab->rname, "_f_%s",entry.name);    ptab->id = -entry.attr;    ptab->level = -1;    ptab->defn = DEF_FUNCT;    ptab->type = find_type_by_id(entry.ret_type);    ptab->local_size = 0;    ptab->args_size = 0;    ptab->args = NULL;    ptab->localtab = NULL;    ptab->locals = NULL;    ptab->parent = System_symtab[0];    /* p = (symbol*)malloc(sizeof(symbol)); */    NEW0(p, PERM);    if(!p)        internal_error("Insufticent memory.");    strcpy(p->name, ptab->name);    strcpy(p->rname, ptab->rname);    p->defn = DEF_FUNCT;    p->type = find_type_by_id(entry.ret_type);    p->offset = 0;    p->next = NULL;    p->tab = ptab;    p->type_link = NULL;    ptab->locals = p;    if(entry.arg_type)    {        /* p = (symbol*)malloc(sizeof(symbol)); */        NEW0(p, PERM);        if(!p)            internal_error("Insufficent memory.");        strcpy(p->name, "arg");        p->defn =DEF_VALPARA;        p->type = find_type_by_id(entry.arg_type);        add_args_to_table(ptab,p);    }    return ptab;}int is_symbol(symbol*p,char*name){    if(strcmp(p->name,name))        return  0;    return 1;}int get_symbol_size(symbol*sym){    switch(sym->type->type_id)    {    case TYPE_INTEGER:        return  IR->intmetric.size;    case TYPE_CHAR   :        return  IR->charmetric.size;    case TYPE_BOOLEAN:        return  IR->intmetric.size;    case TYPE_REAL   :        return  IR->floatmetric.size;    case TYPE_STRING :        return size (CHAR)               *(strlen(sym->v.s) + 1);    case TYPE_ARRAY  :        return  get_type_size(                    sym->type_link);    case TYPE_RECORD  :        return get_type_size(                   sym->type_link);    case TYPE_UNKNOWN:        internal_error("Unknown type.");        break;    case  TYPE_VOID   :        return 0;    default:        break;    }    return 0;}symtab *pop_symtab_stack(){    if(symtab_tos == SYMTAB_STACK_SIZE)        internal_error("Symtab stack underflow.");    return symtab_stack[++symtab_tos];}void push_symtab_stack (symtab *tab){    if(symtab_tos== -1)        internal_error("Symtab stack overflow.");    else        symtab_stack[symtab_tos--] = tab;}symtab *top_symtab_stack(){    return symtab_stack[symtab_tos + 1];}symtab *find_routine(char *name){    int i;    symtab *ptab;    for(i=0;i<last_symtab;i++)    {        ptab = symtab_queue[i];        if(!strcmp(ptab->name,name))            return ptab;    }    return NULL;}symtab *find_sys_routine(int routine_id){    int i;    for(i = 1; i < System_symtab[0]->local_size; i++)        if(System_symtab[i]->id == -routine_id)            return System_symtab[i];    return NULL;}symbol *find_element(symtab *tab,char *name){    symbol *p;    symtab *ptab = tab;    type *pt;    while(ptab)    {        for(pt = ptab->type_link; pt; pt = pt->next)            for(p = pt->first; p; p = p->next)                if(is_symbol(p,name))                    return p;        ptab = ptab->parent;    }    return NULL;}symbol *find_field(symbol *p,char *name){    type *pt;    symbol *q;    if(!p || p->type->type_id != TYPE_RECORD)        return NULL;    pt = p->type_link;    for(q = pt->first; q; q = q->next)        if(is_symbol(q, name))            return q;    return NULL;}symbol *find_symbol(symtab *tab,char *name){    symbol *p;    symtab *ptab = tab;    type *pt;    if(!ptab)    {        p = System_symtab[0]->locals;        p->type = TYPE_UNKNOWN;        return p;    }    while(ptab)    {        p = find_local_symbol(ptab,name);        if(p)            return p;        for(pt = ptab->type_link; pt; pt=pt->next)            for(p = pt->first; p; p = p->next)                if(is_symbol(p,name))                    return p;        ptab = ptab->parent;    }    return NULL;}symbol *find_local_symbol(symtab *tab, char *name){    symbol *p;    symtab *ptab = tab;    int i;    if(!ptab)        return NULL;    if(!ptab->localtab)        return NULL;    p = ptab->localtab;    while(p)    {        i = strcmp(name, p->name);        if(i > 0)            p = p->rchild;        else if(i < 0)            p = p->lchild;        else            return p;    }    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -