《编译原理》实验指导书2016(5)

2019-03-03 10:44

《编译原理》实验指导书

k++;

} getchdo;

}

while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9'); a[k]=0; strcpy(id,a); i=0; j=norw-1;

do /* 搜索当前符号是否为保留字 */ { k=(i+j)/2;

if(strcmp(id,word[k])<=0)j=k-1; if(strcmp(id,word[k])>=0)i=k+1; }

while(i<=j);

if(i-1>j)sym=wsym[k]; else sym=ident; /* 搜索失败则,是名字或数字 */

} else { if(ch>='0'&&ch<='9') {

/* 检测是否为数字:以0..9开头 */

k=0; num=0; sym=number; do { num=10*num+ch-'0'; k++; getchdo;

}

while(ch>='0'&&ch<='9'); /* 获取数字的值 */ k--;

if(k>nmax)error(30);

} else { if(ch==':') /* 检测赋值符号 */

{ getchdo; if(ch=='=') { sym=becomes;

getchdo;

《编译原理》课程组 20 of 37

《编译原理》实验指导书

} else { }

if(ch=='<') { } else { }

if(ch=='>') { } else { }

sym=ssym[ch]; getchdo;

/* 当符号不满足上述条件时,全部按照单字符符号

getchdo; if(ch=='=') { } else { }

sym=gtr; sym=geq; getchdo;

/* 检测大于或大于等于符号 */

getchdo; if(ch=='=') { } else { }

sym=lss; sym=leq; getchdo;

/* 检测小于或小于等于符号 */

} else { }

sym=nul; /* 不能识别的符号 */

处理 */

《编译原理》课程组 21 of 37

《编译原理》实验指导书

}

/* 编译程序主体 */

int block(int lev, /* 当前分程序所在层 */ {

dx=3; tx0=tx;

/* 记录本层名字的初始位置 */

table[tx].adr=cx; gendo(jmp,0,0);

if(lev>levmax)error(32); do {

if(sym==constsym) /* 收到常量声明符号,开始处理常量声明 */ { {

}

while(sym==ident);

constdeclarationdo(&tx,lev,&dx); /* dx的值会被constdeclaration改变,使用指while(sym==comma) { }

if(sym==semicolon) { }

else error(5);

getsymdo; getsymdo;

constdeclarationdo(&tx,lev,&dx);

getsymdo; do

int i;

int dx; /* 名字分配到的相对地址 */ int tx0; /* 保留初始tx */ int cx0; /* 保留初始cx */

bool nxtlev[symnum]; /* 在下级函数的参数中,符号集合均为值参,但由于使用数租实现,

传递进来的是指针,为防止下级函数改变上级函数的集合,开辟新的空间 传递给下级函数,之后所有的nxtlev都是这样 */

int tx, /* 名字表当前尾指针 */ bool* fsys /* 当前模块后跟符号集合 */ ) } return 0;

}

针 */

《编译原理》课程组 22 of 37

《编译原理》实验指导书

}

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); 《编译原理》课程组 23 of 37

《编译原理》实验指导书

}

/* 初始化 */ void init() {

int i;

/* 设置单字符符号 */

for(i=0;i<=255;i++)ssym[i]=nul; ssym['+']=plus; ssym['-']=minus; ssym['*']=times; ssym['/']=slash; ssym['(']=lparen; ssym[')']=rparen; ssym['=']=eql; ssym[',']=comma; ssym['.']=period; ssym['#']=neq; ssym[';']=semicolon; /* 设置保留字名字 */ }

while(inset(sym,declbegsys));

/* 直到没有声明符号 */

code[table[tx0].adr].a=cx; /* 开始生成当前过程代码 */ table[tx0].adr=cx; /* 当前过程代码地址 */ table[tx0].size=dx; cx0=cx;

gendo(inte,0,dx); /* 生成分配内存代码 */

/* 语句后跟符号为分号或end */

memcpy(nxtlev,fsys,sizeof(bool)*symnum); /* 每个后跟符号集和都包含上层后跟符号集和,以nxtlev[semicolon]=true; nxtlev[endsym]=true;

statementdo(nxtlev,&tx,lev); gendo(opr,0,0);

/* 每个过程出口都要使用的释放数据段指令 */

memset(nxtlev,0,sizeof(bool)*symnum); /*分程序没有补救集合 */ testdo(fsys,nxtlev,8); /* 检测后跟符号正确性 */ listcode(cx0); return 0;

/* 输出代码 */

/* 声明部分中每增加一条声明都会给dx增加1,声明部分已经结束,dx就

}

memcpy(nxtlev,statbegsys,sizeof(bool)*symnum); nxtlev[ident]=true;

testdo(nxtlev,declbegsys,7);

}

else error(5);

/* 漏掉了分号 */

是当前过程数据的size */

便补救 */

《编译原理》课程组 24 of 37


《编译原理》实验指导书2016(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:教科版五年级科学下册全册教案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: