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

2019-03-03 10:44

《编译原理》实验指导书

getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[rparen]=true; nxtlev[comma]=true;

/* write的后跟符号为) or , */

/* 调用表达式处理,此处与read不

expressiondo(nxtlev,ptx,lev);

同,read为给变量赋值 */

gendo(opr,0,14); /* 生成输出指令,输出栈顶的值 */

}

while(sym==comma);

if(sym!=rparen)error(33); /* write()中应为完整表达式 */ else { getsymdo; }

}

gendo(opr,0,15); /* 输出换行 */

} else { if(sym==callsym) /* 准备按照call语句处理 */ { getsymdo;

if(sym!=ident)error(14); /* call后应为标识符 */

else { i=postion(id,*ptx);

if(i==0)error(11); /* 过程未找到 */ else { if(table[i].kind==procedur) { gendo(cal,lev-table[i].level,table[i].adr);

call指令 */

}

else error(15);

/* call后标识符应为过程 */

}

getsymdo;

}

} else { if(sym==ifsym) /* 准备按照if语句处理 */

{

getsymdo;

《编译原理》课程组 /* 生成

30 of 37

《编译原理》实验指导书

} else {

/* 循环调用语句处理函数,直到下一个符号不是语句开始符号或收statementdo(nxtlev,ptx,lev);

while(inset(sym,statbegsys)||sym==semicolon) { }

if(sym==endsym) { }

else error(17);

/* 缺少end或; */

getsymdo;

if(sym==semicolon) { }

else error(10);

/* 缺少; */

statementdo(nxtlev,ptx,lev);

getsymdo;

到end */

} else {

if(sym==beginsym) /* 准备按照复合语句处理 */ {

getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;

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

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[thensym]=true; nxtlev[dosym]=true; if(sym==thensym) { }

else error(16); gendo(jpc,0,0); code[cx1].a=cx;

/* 缺少then */

/* 生成条件跳转指令,跳转地址未知,暂时写0 */ /* 经statement处理后,cx为then后语句执行完的位

cx1=cx; /* 保存当前指令地址 */

statementdo(fsys,ptx,lev); /* 处理then后的语句 */

getsymdo;

/* 后跟符号为then或do */

conditiondo(nxtlev,ptx,lev); /* 调用条件处理(逻辑运算)函数 */

置,它正是前面未定的跳转地址 */

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

《编译原理》实验指导书

*/ */ }

/* 表达式处理 */

int expression(bool* fsys,int* ptx,int lev) {

if(sym==plus||sym==minus) /* 开头的正负号,此时当前表达式被看作一个正的或负的项 */ {

addop=sym; getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true;

/* 保存开头的正负号 */

enum symbol addop; /* 用于保存正负号 */ bool nxtlev[symnum];

/* 参数意义见block和enter函数 */

} return 0;

}

}

}

}

}

testdo(fsys,nxtlev,19); /* 检测语句结束的正确性 */

}

memset(nxtlev,0,sizeof(bool)*symnum); /* 语句结束无补救集合

if(sym==dosym) { }

else error(18);

/* 缺少do */

statementdo(fsys,ptx,lev); /* 循环体 */ gendo(jmp,0,cx1); /* 回头重新判断条件 */ code[cx2].a=cx;

/* 反填跳出循环的地址,与if类似 */

getsymdo;

if(sym==whilesym) /* 准备按照while语句处理 */ {

cx1=cx; /* 保存判断条件操作的位置 */ getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[dosym]=true;

/* 后跟符号为do */

/* 调用条件处理 */

conditiondo(nxtlev,ptx,lev); gendo(jpc,0,0);

cx2=cx; /* 保存循环体的结束的下一个位置 */

/* 生成条件跳转,但跳出循环的地址未知

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

《编译原理》实验指导书

termdo(nxtlev,ptx,lev); /* 处理项 */

if(addop==minus)gendo(opr,0,1); /* 如果开头为负号生成取负指令 */

}

else /* 此时表达式被看作项的加减 */ { memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true;

termdo(nxtlev,ptx,lev); /* 处理项 */ }

while(sym==plus||sym==minus) { addop=sym; getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true;

termdo(nxtlev,ptx,lev); /* 处理项 */ if(addop==plus) { gendo(opr,0,2);

/* 生成加法指令 */

}

else gendo(opr,0,3);

/* 生成减法指令 */

} return 0;

}

/* 条件处理 */

int condition(bool* fsys,int* ptx,int lev) /* 参数意义见block和enter函数 */

{ enum symbol relop; bool nxtlev[symnum]; if(sym==oddsym) /* 准备按照odd运算处理 */

{ getsymdo;

expressiondo(fsys,ptx,lev); gendo(opr,0,6);

/* 生成odd指令 */ } else { /* 逻辑表达式处理 */

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[eql]=true;nxtlev[neq]=true; nxtlev[lss]=true;nxtlev[leq]=true;

nxtlev[gtr]=true;nxtlev[geq]=true; 《编译原理》课程组 33 of 37

《编译原理》实验指导书

expressiondo(nxtlev,ptx,lev);

if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)error(20); else { relop=sym; getsymdo;

expressiondo(fsys,ptx,lev); switch(relop) { case eql: gendo(opr,0,8); break;

case neq:

gendo(opr,0,9); break;

case lss:

gendo(opr,0,10); break;

case geq:

gendo(opr,0,11); break;

case gtr:

gendo(opr,0,12); break;

case leq:

gendo(opr,0,13);

break;

}

}

} return 0;

}

/* 项处理 */

int term(bool* fsys,int* ptx,int lev) /* 参数意义见block和enter函数 */ { enum symbol mulop; /* 用于保存乘除法符号 */ bool nxtlev[symnum]; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[times]=true; nxtlev[slash]=true;

factordo(nxtlev,ptx,lev); /* 处理因子 */ while(sym==times||sym==slash)

{

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


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

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

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

马上注册会员

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