?? 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 + -