/* 语法、语义分析程序 */
int block(int lev, /* 当前分程序所在层 */
int tx, /* 名字表当前尾指针 */
bool* fsys /* 当前模块后跟符号集合 */
)
{
int i;
int dx; /* 名字分配到的相对地址 */
int tx0; /* 保留初始tx */
int cx0; /* 保留初始cx */
bool nxtlev[symnum]; /* 在下级函数的参数中,
符号集合均为值参,但由于使用数租实现,
传递进来的是指针,为防止下级函数改变
上级函数的集合,开辟新的空间传递给
下级函数,之后所有的nxtlev都是这样 */
dx=3;
tx0=tx; /* 记录本层名字的初始位置 */
table[tx].adr=cx;
gendo(jmp,0,0);
if(lev>levmax)error(32);
do
{
if(sym==constsym) /*常量声明符号,开始处理常量声明 */
{
getsymdo;
do
{
constdeclarationdo(&tx,lev,&dx); /* dx的值会被constdeclaration改变,使用指针
*/
while(sym==comma)
{
getsymdo;
constdeclarationdo(&tx,lev,&dx);
}
if(sym==semicolon)
{
getsymdo;
}
else error(5);
}
while(sym==ident);
}
if(sym==varsym) /*变量声明符号,开始处理变量声明 */
{
getsymdo;
do
{
vardeclarationdo(&tx,lev,&dx);
while(sym==comma)
{
getsymdo;
vardeclarationdo(&tx,lev,&dx);
}
if(sym==semicolon)
{
getsymdo;
}
else error(5);
}
while(sym==ident);
}
while(sym==procsym) /*过程声明符号,开始处理过程声明 */
{
getsymdo;
if(sym==ident)
{
enter(procedur,&tx,lev,&dx); /* 记录过程名字 */
getsymdo;
}
else error(4); /* procedure后应为标识符 */
if(sym==semicolon)
{
getsymdo;
}
else error(5); /* 漏掉了分号 */
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[semicolon]=true;
if(-1==block(lev+1,tx,nxtlev))return -1; /* 又进入一层分程序 */
if(sym==semicolon)
{
getsymdo;
memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);
nxtlev[ident]=true;
nxtlev[procsym]=true;
testdo(nxtlev,fsys,6);
}
else error(5); /* 漏掉了分号 */
}
memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);
nxtlev[ident]=true;
testdo(nxtlev,declbegsys,7);
}
while(inset(sym,declbegsys)); /* 直到没有声明符号 */
code[table[tx0].adr].a=cx; /* 开始生成当前过程代码 */
table[tx0].adr=cx; /* 当前过程代码地址 */
table[tx0].size=dx; /* 声明部分中每增加一条声明都会给dx增加1,
声明部分已经结束,dx就是当前过程数据的size */
cx0=cx;
gendo(inte,0,dx); /* 开辟数据段 */
if(tableswitch) /* 输出名字表 */
{
printf("TABLE:\n");
if(tx0+1>tx)printf(" NULL\n");
for(i=tx0+1;i<=tx;i++)
{
switch(table[i].kind)
{
case constant:
printf(" %d const %s ",i,table[i].name);
printf("val=%d\n",table[i].val);
fprintf(fas," %d const %s ",i,table[i].name);
fprintf(fas,"val=%d\n",table[i].val);
break;
case variable:
printf(" %d var %s ",i,table[i].name);
printf("lev=%d addr=%d\n",table[i].level,table[i].adr);
fprintf(fas," %d var %s ",i,table[i].name);
fprintf(fas,"lev=%d addr=%d\n",table[i].level,table[i].adr);
break;
case procedur:
printf(" %d proc %s ",i,table[i].name);
printf("lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
fprintf(fas," %d proc %s ",i,table[i].name);
fprintf(fas,"lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
break;
}
}
printf("\n");
}
|