?? cdecl.c
字號:
init_ident(e1, EiC_work_tab); new_var(e1); EiC_work_tab = h; if (EiC_lexan() == '{') { enum_list(e1); EiC_match('}', " }"); e1->Type = e1->Val.sym->type; } else retractlexan(); break; } else if (t == t_enum) { EiC_freetype(e1->Type); e1->Type = EiC_copytype(token->Val.sym->type); } else EiC_error("Enumeration declaration error"); break; case '{': EiC_work_tab = h; enum_list(e1); EiC_match('}', " }"); break; default: EiC_error("Enumeration declaration error"); retractlexan(); } EiC_work_tab = h;}static void enum_list(token_t * e1){ int ENUMVAL = 0; token_t e2; token_t e3; do { EiC_inittoken(&e2); /* * now do enumerator part */ if (EiC_lexan() == ID) { e2.Type = EiC_addtype(t_int, NULL); setConst(e2.Type); EiC_setAsBaseType(e2.Type); e2.Sclass = c_enum; init_ident(&e2, EiC_work_tab); new_var(&e2); if (EiC_lexan() == ASS) { EiC_inittoken(&e3); cond_expr(&e3); if (isconst(e3.Type) && EiC_gettype(e3.Type) == t_int) ENUMVAL = e3.Val.ival; else { EiC_freetoken(&e3); EiC_error("Assignment must be constant"); break; } EiC_freetoken(&e3); } else retractlexan(); e2.Sym->val.ival = ENUMVAL++; } else { EiC_error("Expected identifier in enumeration"); break; } } while (EiC_lexan() == ','); retractlexan();}static void array_decl(token_t * e1){ int t; token_t e2; EiC_inittoken(&e2); EiC_assign_expr(&e2); if (isconst(e2.Type)) { if ((t=EiC_gettype(e2.Type)) != t_int && t != t_uint) { if(sizeof(int) != sizeof(long) || t != t_ulong) { EiC_error("Constant int expression needed"); e2.Val.ival = 0; } } } else { if(!ABSDECL && /*((t == t_void && EiC_INFUNC) || */ EiC_gettype(e2.Type) != t_void ) EiC_error("Constant int expression needed"); e2.Val.ival = 0; } e1->Type = EiC_addtype(t_array, e1->Type); setNumElems(e1->Type,e2.Val.ival); EiC_freetoken(&e2); EiC_match(']', " ] ");}static void st_un_spec(token_t * e1, int t){ switch (t) { case structsym: e1->Type = EiC_addtype(t_struct, e1->Type); break; case unionsym: e1->Type = EiC_addtype(t_union, e1->Type); break; } f_st_un_spec(e1);}static eicstack_t stun;static void f_st_un_spec(token_t * e1){ val_t val; int t,nxtt; symentry_t *sym; int h = EiC_work_tab; EiC_work_tab = tag_tab; val.p.p = INSTUN; INSTUN = e1; EiC_eicpush(&stun,val); switch (EiC_lexan()) { case ID: /* struct or union tag */ EiC_work_tab = h; sym = token->Val.sym; t = EiC_gettype(sym->type); nxtt = EiC_lexan(); retractlexan(); if(t==ID || (nxtt == '{' && token->Val.sym->level<EiC_S_LEVEL)) { init_ident(e1, tag_tab); new_var(e1); setInf(e1->Type,xcalloc(1, sizeof(struct_t))); if(nxtt == '{') { EiC_lexan(); EiC_S_LEVEL++; s_decl_list(e1); EiC_match('}', " }"); EiC_S_LEVEL--; if(EiC_lexan() == ';' && EiC_S_LEVEL == 1) e1->Type = NULL; retractlexan(); } } else { if (t == t_struct || t == t_union) { EiC_freetype(e1->Type); e1->Type = EiC_copytype(sym->type); } else { init_ident(e1, tag_tab); new_var(e1); setInf(e1->Type,xcalloc(1, sizeof(struct_t))); } if(nxtt == '{') { EiC_lexan(); EiC_S_LEVEL++; s_decl_list(e1); EiC_match('}', " }"); EiC_S_LEVEL--; if(EiC_lexan() == ';' && EiC_S_LEVEL == 1) { EiC_freetype(e1->Type); e1->Type = NULL; } retractlexan(); } } break; case '{': EiC_work_tab = h; EiC_S_LEVEL++; s_decl_list(e1); EiC_match('}', " }"); EiC_S_LEVEL--; break; } EiC_work_tab = h; EiC_eicpop(&stun,&val); INSTUN = val.p.p;}static void s_decl_list(token_t * e1){ int f = 0, bp = EiC_ENV->lsp; struct_t *S; if(!EiC_getInf(e1->Type)) setInf(e1->Type,xcalloc(1, sizeof(struct_t))); /* if(((struct_t*)EiC_getInf(e1->Type))->cl) { EiC_error("Illegal use of struct/union"); return; } */ while (1) { switch (EiC_lexan()) { TYPESPEC: TYPEQUAL: f = 1; st_decl(e1, token->Tok); break; default: if (!f) EiC_error("Struct/Union list declaration error"); S = EiC_getInf(e1->Type); S->cl = 1; /* * determine structure alignment. */ S->tsize = RoundUp(S->tsize,S->align); retractlexan(); EiC_reset_env_pointers(e1, bp); return; } }}static void st_decl(token_t * e1, int t){ token_t e2; EiC_inittoken(&e2); spec_qual_list(&e2, t); EiC_setAsBaseType(e2.Type); spec_declor_list(e1, &e2); EiC_freetype(e2.Type); EiC_match(';', " ; ");}static void spec_qual_list(token_t * e1, int t){ /*type_spec(e1, t);*/ specifier(e1,t,NULL); r_spec_qual_list(e1);}static void r_spec_qual_list(token_t * e1){ switch (EiC_lexan()) { TYPESPEC: spec_qual_list(e1, token->Tok); break; default: retractlexan(); }}void EiC_free_un_mem(type_expr * e){ struct_t *S = EiC_getInf(e); if (S) { int i; if(S->n) { for (i = 0; i < S->n; i++) { xfree(S->id[i]); EiC_freetype(S->type[i]); } xfree(S->offset); xfree(S->id); xfree(S->type); } if(S->ntags) { for(i=0;i<S->ntags;++i) EiC_freetype(S->tag[i]); xfree(S->tag); } xfree(S); }}static void addst_un_tag(symentry_t *sym){ struct_t *S; S = EiC_getInf(INSTUN->Val.sym->type); S->ntags++; if(S->ntags == 1) S->tag = (type_expr**)xmalloc(sizeof(type_expr*)); else S->tag = (type_expr**)xrealloc(S->tag, sizeof(type_expr*)*S->ntags); S->tag[S->ntags - 1] = EiC_transtype(sym->type); EiC_setaliases(sym->type,1);} static void addst_un_mem(token_t * e1, token_t * e2){ struct_t *S; int off, s; S = EiC_getInf(e1->Type); if (S->n == 0) { S->id = (char **) xcalloc(1, sizeof(char *)); S->offset = (int *) xcalloc(1, sizeof(int)); S->type = (type_expr **) xcalloc(1, sizeof(type_expr *)); } else { /* * first check for duplication of names */ int i; for(i=0;i<S->n;++i) if(strcmp(S->id[i], e2->Val.sym->id) == 0) EiC_error("Duplication of identifier in struct/union"); S->id = (char **) xrealloc(S->id, (S->n + 1) * sizeof(char *)); S->offset = (int *) xrealloc(S->offset, (S->n + 1) * sizeof(int)); S->type = (type_expr **) xrealloc(S->type, (S->n + 1) * sizeof(type_expr *)); } if(isconst(e2->Type)) { unsetConst(e2->Type); setConstp(e2->Type); } if(EiC_gettype(e2->Type) == t_enum) cast_t_enum(e2); S->id[S->n] = (char *) EiC_strsave(e2->Val.sym->id); S->type[S->n] = EiC_transtype(e2->Type); if(!(s = EiC_get_sizeof(S->type[S->n]))) { EiC_error("Incomplete data type for struct/union member %s",S->id[S->n]); } off = EiC_get_align(e2->Type); if (EiC_gettype(e1->Type) == t_struct) { S->offset[S->n] = RoundUp(S->tsize,off); S->tsize += s + S->offset[S->n] - S->tsize; } else { /* handle union */ S->offset[S->n] = 0; S->tsize = S->tsize > s ? S->tsize : s; } /* * structure alignment is equal to the * maximum alignment of its members. */ if(S->align < off) S->align = off; S->n++;}static void spec_declor_list(token_t * e1, token_t * e2){ int ftime = 1, cl; token_t e3; cl = ((struct_t*)EiC_getInf(e1->Type))->cl; do { switch (EiC_lexan()) { case '*': case ID: case '(': case ':': EiC_inittoken(&e3); e3.Type = EiC_transtype(e2->Type); st_declor(&e3, token->Tok); if (EiC_gettype(e3.Type) == t_struct || EiC_gettype(e3.Type) == t_union) { struct_t *S; S = EiC_getInf(e3.Type); if (!S->cl) /* check for closure */ EiC_error("Illegal Struct/Union member"); } /* if structure/union is already closed, * then assume structure is being re-entered. */ if (e3.Val.sym && !cl) { e3.Type = EiC_revtype(e3.Type); if (ftime) EiC_setaliases(e2->Type, 1); addst_un_mem(e1, &e3); if (ftime) { EiC_setaliases(e3.Type, 1); ftime = 0; } } EiC_freetype(e3.Type); EiC_remsym(e3.Val.sym); break; default: retractlexan(); EiC_error("Struct/Union member declaration error"); } } while (EiC_lexan() == ','); retractlexan();}static void st_declor(token_t * e1, int t){ switch (t) { case '*': case ID: case '(': decl(e1, t); /*setBoundaryLimits(e1);*/ f_st_declor(); establish_id(e1); break; case ':': EiC_error("Bit fields not supported"); break; }}static void f_st_declor(){ if (EiC_lexan() == ':') EiC_error("Bit fields not supported"); else retractlexan();}int EiC_type_name(token_t * e1){ switch (EiC_lexan()) { TYPEQUAL: TYPESPEC: spec_qual_list(e1, token->Tok); EiC_setAsBaseType(e1->Type); switch (EiC_lexan()) { case '*': case '(': case '[': abs_decl(e1, token->Tok); e1->Type = EiC_revtype(e1->Type); break; default: retractlexan(); } break; default: retractlexan(); return 0; } return 1;}static void abs_decl(token_t * e1, int t){ type_expr *P = NULL; ABSDECL++; switch (t) { case '*': P = pointer(); f_abs_decl(e1); if(P) e1->Type = EiC_catTypes(P,e1->Type); break; case '(': case '[': dir_abs_decl(e1, t); break; case ID: EiC_error("extraneous identifier `%s'",token->Val.sym->id); break; } ABSDECL--;}static void f_abs_decl(token_t * e1){ switch (EiC_lexan()) { case '(': case '[': dir_abs_decl(e1, token->Tok); break; case ID: EiC_error("extraneous identifier `%s'",token->Val.sym->id); break; default: retractlexan(); }}static void dir_abs_decl(token_t * e1, int t){ switch (t) { case '(': f1_dir_abs(e1); EiC_f2_dir_abs(e1); break; case '[': array_decl(e1); EiC_f2_dir_abs(e1); break; }}static void f1_dir_abs(token_t * e1){ switch (EiC_lexan()) { case ')': TYPEQUAL: STORECLASS: TYPESPEC: retractlexan(); ff_dir_decl(e1); EiC_remlevel(EiC_S_LEVEL+1); break; case '*': case '(': case '[': abs_decl(e1, token->Tok); EiC_match(')', " )"); break; default: EiC_error("Abstract declaration error"); }}static void EiC_f2_dir_abs(token_t * e1){ switch (EiC_lexan()) { case '[': array_decl(e1); EiC_f2_dir_abs(e1); break; case '(': ff_dir_decl(e1); EiC_remlevel(EiC_S_LEVEL+1); EiC_f2_dir_abs(e1); break; default: retractlexan(); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -