符号表的基本操作

来源:互联网 发布:淘宝乒乓球店 编辑:程序博客网 时间:2024/04/30 14:47
/**符号存储结构定义**/typedef struct Symbol{    int v;                  //符号的单词编码    int r;                  //符号关联的寄存器    int c;                  //符号关联值    Type type;              //符号数据类型    struct Symbol*next;     //关联的其他符号    struct Symbol*prev_tok; //指向前一定义的同名符号}Symbol;/**类型结构定义**/typedef struct typedef{    int t;                  //数据类型    struct Symbol *ref;     //引用符号}Type;/**数据类型编码**/enum e_TypeCode{    T_INT   =0,         //整型    T_CHAR  =1,         //字符型    T_SHORT =2,         //短整型    T_VOID  =3,        //空类型    T_PTR   =4,         //指针    T_FUNC  =5,         //函数    T_STRUCT=6,         //结构体    T_BTYPE =0x000f,    //基本类型掩码    T_ARRAY =0x0010,    //数组};/**存储类型**/enum e_StorageClass{    SC_GLOBAL   =0x00f0,    //包括整型常量,字符常量,字符串常量,全局变量,函数定义    SC_LOCAL    =0x00f1,    //栈中变量    SC_LLOCAL   =0x00f2,    //寄存器溢出存放栈中    SC_CMP      =0x00f3,    //使用标志寄存器    SC_VALMASK  =0x00ff,    //存储类型掩码    SC_LVAL     =0x0100,    //左值    SC_SYM      =0x0200,    //符号    SC_ANOM     =0x10000000,//匿名符号    SC_STRUCT   =0x20000000,//结构体符号    SC_MEMBER   =0x40000000,//结构成员变量    SC_PARAMS   =0x80000000,//函数参数};Type char_pointer_type,     //字符串指针int_type,                   //int类型default_func_type;          //缺省函数类型Stack global_sym_stack,     //全局符号栈      local_sym_stack;      //局部符号栈/**符号的登录**//**将符号放在符号栈里v:      符号编号type:   符号数据类型c:      符号关联值**/Symbol *sym_direct_push(Stack*ss,int v,Type *type,int c){    Symbol s,*p;    s.v=v;    s.type.t=type->t;    s.type.ref=type->ref;    s.c=c;    s.next=NULL;    p=(Symbol*)stack_push(ss,&s,sizeof(Symbol));    return p;}/**将符号放在符号栈中,动态判断是放入全局符号栈还是局部符号栈v:      符号编号type:   符号数据类型r:      符号存储类型c:      符号关联值**/Symbol *sym_push(int v,Type *type,int r,int c){    Symbol *ps,**pps;    TkWord *ts;    Stack *ss;    if(stack_is_empty(&local_sym_stack)==0)     /**只有当局部符号栈非空的时候是局部符号栈**/        ss=&local_sym_stack;    else        ss=&global_sym_stack;    ps=sym_direct_push(ss,v,type,c);    ps->r=r;    /**不记录结构体成员及匿名符号**/    if((v&SC_STRUCT)||v<SC_ANOM)                /**结构体v 是v|SC_STRUCT,结构体成员是v|SC_MEMBER,匿名符号设置为v=SC_ANOM**/    {        /**更新单词sym_struct或sym_identifier字段**/        ts=(TkWord*)tktable.data[(v&~SC_STRUCT)];/**得到在tktable中编号为v的单词**/        if(v&SC_STRUCT)                          /**v是结构体**/            pps=&ts->sym_struct;        else            pps=&ts->sym_identifier;        ps->prev_tok=*pps;                        /**更新ps的prev_tok成员**/        *pps=ps;                                  /**结构体类型更新sym_struct 其他类型更新sym_identifier字段**/    }    return ps;}/**将函数符号放入全局符号表中v:      符号编号type:   符号数据类型**/Symbol *func_sym_push(int v,Type *type){    Symbol *s,**ps;    s=sym_direct_push(&global_sym_stack,v,type,0);/**函数符号都是放入全局符号表**/    ps=&((TkWord*)tktable.data[v])->sym_identifier;    /**同名符号,函数符号放在最后->->...s**/    while(*ps!=NULL)        ps=&(*ps)->prev_tok;    s->prev_tok=NULL;    *ps=s;    return s;}/**变量符号插入**/Symbol *var_sym_put(Type *type,int r,int v,int addr){    Symbol *sym=NULL;    if((r&SC_VALMASK)==SC_LOCAL)            //局部变量,SC_VALMASK是基本类型掩码    {        sym=sym_push(v,type,r,addr);    }    else if(v&&(r&SC_VALMASK)==SC_GLOBAL)   //全局变量    {        sym=sym_search(v);                          if(sym)                              //如果标识符已经定义,就会显示重定义错误            error("%s重定义\n",((TkWord*)tktable.data[v])->spelling);        else            sym=sym_push(v,type,r|SC_SYM,0); /**SC_SYM表符号**/    }    //字符串常量符号    return sym;}/**将节名称放入全局符号表sec:节名称c:  符号关联值**/Symbol *sec_sym_put(char *sec ,int c){    TkWord *tp;    Symbol *s;    Type type;    type.t=T_INT;    tp=tkword_insert(sec);    token=tp->tkcode;    s=sym_push(token,&type,SC_GLOBAL,c);    return s;}/**符号的删除弹出栈中符号直到栈顶符号为'b'ptop:符号栈栈顶b:   符号指针**/void sym_pop(Stack *ptop,Symbol *b){    Symbol *s,**ps;    TkWord *ts;    int v;    s=(Symbol *)stack_get_top(ptop);            while(s!=b)    {        v=s->v;                                     /**根据符号的v值找到单词表中单词**/        /**更新单词表中sym_struct sym_identifier**/        if((v&SC_STRUCT)||v<SC_ANOM)                /**不记录结构体成员及匿名符号**/        {            ts=(TkWord *)tktable.data[(v&~SC_STRUCT)];            if(v&SC_STRUCT)                ps=&ts->sym_struct;            else                ps=&ts->sym_identifier;            *ps=s->prev_tok;                        /**相当于把s删除,然后连接上s->prev_tok**/        }        stack_pop(ptop);        s=(Symbol *)stack_get_top(ptop);    }}/**符号的查找**//**查找结构定义v:符号编号**/Symbol *struct_search(int v){    if(v>=tktable.count)        return NULL;    else        return ((TkWord*)tktable.data[v])->sym_struct;}/**查找标识符v:符号编号**/Symbol *sym_search(int v){    if(v>=tktable.count)        return NULL;    else        return ((TkWord*)tktable.data[v])->sym_identifier;}

0 0
原创粉丝点击