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