符号表的构造

来源:互联网 发布:重庆大学b区电信网络 编辑:程序博客网 时间:2024/05/16 13:45
/**符号表的构造过程**//**解析外部声明l:存储类型,局部的还是全局的**/void external_decartion(int l){    Type btype,type;    int v,has_init,r,addr;    Symbol *sym;    if(!type_specifier(&btype))     /**修改btype的t成员**/    {        expect("<类型区别符>");    }    if(btype.t==T_STRUCT&&token==TK_SEMICOLON)/**只有结构体类型定义的结尾加分号是合法的**/    {        get_token();        return;    }    while(1)        /*逐个分析声明或函数定义*/    {        type=btype;        declarator(&type,&v,NULL);       /**经过这个函数,v会变成token,如果是函数或数组,则type会发生变化,不然type还是原来的btype值,最后一个参数跟对齐有关**/        if(token==TK_BEGIN)              /**函数定义**/        {            if(l==SC_LOCAL)                error("不支持函数嵌套定义");            if(type.t&T_BTYPE!=T_FUNC)                expect("<函数定义>");            sym=sym_search(v);            if(sym)                     /**函数前面声明过,现在给出函数定义**/            {                if((sym->type.t&T_BTYPE)!=T_FUNC)/**标识符声明的时候不是函数类型,就会显示重定义错误**/                    error("'%s'重定义",get_tkstr(v));                sym->type=type;         /**type和sym->type的区别在于ref,type.ref经过declarator函数后有了值,sym->type.ref并没有赋值**/            }            else            {                sym=func_sym_push(v,&type);/**如果单词的identifier值还没有,就把插进去sym**/            }            sym->r=SC_SYM|SC_GLOBAL;        /**函数符号的r值设置为符号和全局**/            funcbody(sym);            break;        }        else                                /**声明**/        {            if((type.t&T_BTYPE)==T_FUNC)    //函数声明            {                if(sym_search(v)==NULL)                {                    sym=sym_push(v,&type,SC_GLOBAL|SC_SYM,0); /**函数符号的r值设置为符号和全局**/                }            }            else                            //变量声明            {                r=0;                if(!(type.t&T_ARRAY))       /**数组类型不能做左值**/                    r|=SC_LVAL;                r|=l;                       /**l表示是全局类型还是局部类型**/                has_init=(token==TK_ASSIGN);                if(has_init)                {                    get_token();                    initializer(&type);                }                sym=var_sym_put(&type,r,v,addr);/**局部变量 经过这函数r不变,全局变量,r|SC_SYM**/            }            if(token==TK_COMMA)            {                get_token();            }            else            {                syntax_state=SNTX_LF_HT;                skip(TK_SEMICOLON);                break;            }        }    }}/**功能:解析类型区分符返回值:是否发现合法的类型区分符<type_specifier>::=<KW_INT>    |<KW_CHAR>    |<KW_SHORT>    |<KW_VOID>    |<struct_specifier>**/int type_specifier(Type *type){    int t,type_found;    Type type1;    t=0;    int type_found=0;    switch(token)    {    case KW_CHAR:        t=T_CHAR;        type_found=1;        syntax_state=SNTX_SP;   /**空格**/        get_token();        break;    case KW_SHORT:        t=T_SHORT;        type_found=1;        syntax_state=SNTX_SP;        get_token();        break;    case KW_VOID:        t=T_VOID;        type_found=1;        syntax_state=SNTX_SP;        get_token();        break;    case KW_INT:        t=T_INT;        type_found=1;        syntax_state=SNTX_SP;        get_token();        break;    case KW_STRUCT:        struct_specifier(&type1);        type->ref=type1.ref;            /**ref改变**/        t=T_STRUCT;        type_found=1;        syntax_state=SNTX_SP;        break;    default:        break;    }    type->t=t;    return type_found;}/**结构区分符:<struct_specifier>::=<KW_STRUCT><IDENTIFIER><TK_BEGIN><struct_declaration_list><TK_END>    |<KW_STRUCT><IDENTIFIER>**/void struct_specifier(Type *type){    int v;    Symbol *s;    Type type1;    get_token();    v=token;    syntax_state=SNTX_DELAY;        /**延迟到取出下个单词后确定输出格式**/    get_token();    if(token==TK_BEGIN)     /*适用于结构体定义*/    syntax_state=SNTX_LF_HT;    else if(token==TK_CLOSEPA)  /*适用于sizeof(struct struct_name)*/    syntax_state=SNTX_NUL;    else                        /*适用于结构变量声明*/        syntax_state=SNTX_SP;    syntax_indent();    if(v<TK_IDENT)          /**关键字不能作为结构名称**/        expect("结构体名");    s=struct_search(v);     /**查找结构是否定义**/    if(!s)    {        type1.t=KW_STRUCT;  /**是KW_STRUCT 不是T_STRUCT**/        //-1赋值给s->c,标识结构体尚未定义        s=sym_push(v|SC_STRUCT,&type1,0,-1);        s->r=0;    }    type->ref=s;            /**ref引用**/    if(token==TK_BEGIN)    {        struct_declaration_list(type);    }}/**结构声明符表<struct_declaration_list>::=<struct_declaration>{<struct_declaration>}**/void struct_declaration_list(Type *type){    int maxalign,offset;    syntax_state=SNTX_LF_HT;    /**第一个结构体成员与{不写在同一行**/    syntax_level++;             /**结构体成员变量声明,缩进增加一级**/    Symbol *s,**ps;    s=type->ref;    get_token();    if(s->c!=-1)                /**s->c记录结构体尺寸**/        error("结构体已定义");    maxalign=1;    ps=&s->next;    offset=0;    while(token!=TK_END)    {        struct_declaration(&maxalign,&offset,&ps);    }    skip(TK_END);    syntax_state=SNTX_LF_HT;    s->c=calc_align(offset,maxalign);   /**结构体大小**/    s->r=maxalgin;                      /**结构体对齐**/}/**结构声明<struct_declaration::=    <type_specifier><declarator>{<TK_COMMA><declarator>}<TK_SEMICOLON>maxalign(输入,输出):成员最大对齐粒度offset(输入,输出):  偏移量ps(输出):            结构定义符号**/void struct_declaration(int* maxalign,int *offset,Symbol ***ps){    int v,size,align;    Symbol *ss;    Type type1,btype;    int force_align;    type_specifier(&btype);    while(1)        /**while循环很精妙呀**/    {        v=0;        type1=btype;        declarator(&type1,&v,&force_align);    /**force_align这个参数用来观察是否有强制对齐**/        size=type_size(&type1,&align);        if(force_align&ALIGN_SET)               /**如果有强制对齐就按强制对齐**/            align=force_align&~ALIGN_SET;       /** #define ALIGN_SET 0x100**/        *offset=calc_align(*offset,align);        if(align>*maxalign)            *maxalign=align;        ss=sym_push(v|SC_MEMBER,&type1,0,*offset);        *offset+=size;        **ps=ss;        *ps=&ss->next;                          /**next**/        if(token==TK_SEMICOLON)            break;        skip(TK_COMMA);    }    syntax_state=SNTX_LF_HT;/**又来了这不明所以的东西**/    skip(TK_SEMICOLON);}/**函数调用约定<function_calling_convention>::=<KW_CDECL>|<KW_STDCALL>用于函数声明上,用在数据声明上忽略掉fc(输出):调用约定**/void function_calling_convention(int *fc){    *fc=KW_CDECL;    if(token==KW_CDECL||token==KW_STDCALL)    {        syntax_state=SNTX_SP;        *fc=token;        get_token();    }}/**结构成员对齐<struct_member_alignment>::=<KW_ALIGN><TK_OPENPA><TK_CINT><TK_CLOSEPA>force_align(输出):强制对齐粒度**/void struct_member_alignment(int *force_align){    int align=1;    if(token==KW_ALIGN)             /**如果有强制对齐**/    {        get_token();        skip(TK_OPENPA);        if(token==TK_CINT)        {            get_token();            align=tkvalue;          /**align值为()里的数字值**/        }        else expect("整数常量");        skip(TK_CLOSEPA);        if(align!=1&&align!=2&&align!=4)            align=1;        align|=ALIGN_SET;           /**|=ALIGN_SET 说明要强制对齐**/        *force_align=align;    }    else        *force_align=1;}/**声明符<declarator>::={<pointer>}[<function_calling_convention>]    [<struct_member_alignment>]<direct_declarator><pointer>::=<TK_STAR>type:   数据类型v(输出): 单词编号force_align(输出): 强制对齐粒度**/void declarator(Type *type,int *v,int *force_align){    int fc;    while(token==TK_STAR)    {        mk_pointer(type);        get_token();    }    function_calling_convention(&fc);    if(force_align)        struct_member_alignment(force_align);    direct_declarator(type,v,fc);}/**功能:生成指针类型t:原数据类型**/void mk_pointer(Type *t){Symbol *s;    s = sym_push(SC_ANOM, t, 0, -1);    t->t = T_PTR ;    t->ref = s;}/**直接声明符<direct_declarator>::=<IDENTIFIER><direct_declarator_postfix>type(输入,输出):数据类型v(输出):单词编号func_call:函数调用约定**/void direct_declarator(Type *type,int *v,int func_call){    if(token>=TK_IDENT)    {        *v=token;        get_token();    }    else    {        expect("标识符");    }    direct_declarator_postfix(type,func_call);}/**直接声明符后缀<direct_declarator_postfix>::={<TK_OPENBR><TK_CINT><TK_CLOSEBR>    |<TK_OPENBR><TK_CLOSEBR>    |<TK_OPENPA><parameter_type_list><TK_CLOSEPA>    |<TK_OPENPA><TK_CLOSEPA>}type(输入,输出):数据类型func_call:函数调用约定**/void direct_declarator_postfix(Type*type,int func_call){    int n;    Symbol *s;    if(token==TK_OPENPA)    {        parameter_type_list(type,func_call);/**函数需要func_call参数,变量不用**/    }    else if(token==TK_OPENBR)    {        get_token();        n=-1;        if(token==TK_CINT)        {            get_token();            n=tkvalue;        }        skip(TK_CLOSEBR);        direct_declarator_postfix(type,func_call);        s=sym_push(SC_ANOM,type,0,n);        type->t=T_ARRAY|T_PTR;        type->ref=s;    }}/**形参类型表功能:解析形参类型表func_call:函数调用约定<parameter_type_list>::=<parameter_list>    |<parameter_list><TK_COMMA><TK_ELLIPSIS><parameter_list>::=<parameter_declaration>    {<TK_COMMA><parameter_declaration}<parameter_declaration>::=<type_specifier>{<declarator>}等价转换后文法:<parameter_type_list>::=<type_specifier>{<declarator>}    {<TK_COMMA><type_specifier>{<declarator>}}<TK_COMMA><TK_ELLIPSIS>**/void parameter_type_list(Type *type,int func_call){    int n;    Symbol **plast,*s,*first;    Type pt;    get_token();    first=NULL;    plast=&first;    while(token!=TK_CLOSEPA)    {        if(!type_specifier(&pt))        {            error("无效类型标识符");        }        declarator(&pt,&n,NULL);        s=sym_push(n|SC_PARAMS,&pt,0,0);/**SC_PARAMS表函数参数**/        *plast=s;        plast=&s->next;                 /**next显示作用**/        if(token==TK_CLOSEPA)            break;        skip(TK_COMMA);        if(token==TK_ELLIPSIS)        {            func_call=KW_CDECL;            get_token();            break;        }    }    syntax_state=SNTX_DELAY;    skip(TK_CLOSEPA);    if(token==TK_BEGIN)     //函数定义        syntax_state=SNTX_LF_HT;    else                    //函数声明        syntax_state=SNTX_NUL;    syntax_indent();    /**此处将函数返回类型存储,然后指向参数,最后将type设为函数类型,引用相关信息,放在ref中**/    s=sym_push(SC_ANOM,type,func_call,0);    s->next=first;    type->t=T_FUNC;    type->ref=s;}/**函数体<funcbody>::=<compound_statement>sym:函数符号**/void funcbody(Symbol *sym){    /**放一匿名符号在局部符号表**/    sym_direct_push(&local_sym_stack,SC_ANOM,&int_type,0);    compound_statement(NULL,NULL);    /**清空局部符号栈**/    sym_pop(&local_sym_stack,NULL);}/**初值符<initializer>::=<assignment_expression>**/void initializer(Type *type){    if(type->t&T_ARRAY)        get_token();    else        assignment_expression();}/**复合语句<compound_statement>::=<TK_BEGIN>{<declaration>}{<statement>}<TK_END>bsym:break跳转位置csym:continue跳转位置**/void compound_statement(int *bsym,int *csym){    syntax_state=SNTX_LF_HT;    syntax_level++;         //复合语句,缩进加一级    Symbol *s;    s=(Symbol*)stack_get_top(&local_sym_stack);/**去局部栈顶元素为坐标**/    get_token();    while(is_type_specifier(token))             /**判断是否是声明**/    {        external_decartion(SC_LOCAL);    }    while(token!=TK_END)    {        statement(bsym,csym);    }    sym_pop(&local_sym_stack,s);              /**根据这个坐标把复合语句的符号清空**/    syntax_state=SNTX_LF_HT;    get_token();}/**<sizeof_expression>::=    <KW_SIZEOF><TK_OPENPA><type_specifier><TK_CLOSEPA>**/void sizeof_expression(){    int align,size;    Type type;    get_token();    skip(TK_OPENPA);    type_specifier(&type);    skip(TK_CLOSEPA);    size=type_size(&type,&align);    if(size<0)        error("sizeof计算类型尺寸失败")}/**返回类型长度t:数据类型指针a:对齐值**/int type_size(Type *t,int *a){    Symbol *s;    int bt;    //指针类型长度4字节    int PTR_SIZE=4;    bt=t->t&T_BTYPE;    switch(bt)    {    case T_STRUCT:        s=t->ref;        *a=s->r;            /**结构体的r纪录对齐粒度**/        return s->c;        /**结构体的c纪录结构体大小**/    case T_PTR:             /**指针类型**/        if(t->t&T_ARRAY)    /**数组**/        {            s=t->ref;            return type_size(&s->type,a)*s->c;/**引用的大小*数量**/        }        else        {            *a=PTR_SIZE;            return PTR_SIZE;        }    case T_INT:        *a=4;        return 4;    case T_SHORT:        *a=2;        return 2;    default:        //char ,void ,function        *a=1;        return 1;    }}/**初值表达式<primary_expression>::=<IDENTIFIER>    |<TK_CINT>    |<TK_CSTR>    |<TK_CCHAR>    |<TK_OPENPA><expression><TK_CLOSEPA>***/void primary_expression(){    int t,addr;    Type type;    Symbol *s;    switch(token)    {    case TK_CINT:    case TK_CCHAR:        get_token();        break;    case TK_CSTR:        t=T_CHAR;        type.t=t;        mk_pointer(&type);                  /**常量字符串设置为一个指针类型**/        type.t|=T_ARRAY;        var_sym_put(&type,SC_GLOBAL,0,addr);        initializer(&type);        break;    case TK_OPENPA:        get_token();        expression();        skip(TK_CLOSEPA);        break;    default:        t=token;        get_token();        if(t<TK_IDENT)            expect("标识符或常量");        s=sym_search(t);        if(!s)        {            if(token!=TK_OPENPA)                error("'%s'未声明\n",get_tkstr(t));            s=func_sym_push(t,&default_func_type); //允许函数不声明,直接引用            s->r=SC_GLOBAL|SC_SYM;        }        break;    }}

0 0