/**符号表的构造过程**/ /** 解析外部声明 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; } }