编译原理(PL0编译程序源代码)_第1页
编译原理(PL0编译程序源代码)_第2页
编译原理(PL0编译程序源代码)_第3页
编译原理(PL0编译程序源代码)_第4页
编译原理(PL0编译程序源代码)_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

下载可编辑/*PL/0编译程序(C语言版)*编译和运行环境 :*VisualC++6.0*WinXP/7*使用方法:*运行后输入 PL/0源程序文件名*回答是否将虚拟机代码写入文件*回答是否将符号表写入文件*执行成功会产生四个文件 (词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址 .txt)*/#include<stdio.h>#include"pl0.h"#include"string"#definestacksize500// 解释执行时使用的栈intmain(){boolnxtlev[symnum];printf("请输入源程序文件名 :");scanf("%s",fname);fin=fopen(fname,"r");// 以只读方式打开 pl0源程序文件cifa=fopen(" 词法分析结果.txt","w");fa1=fopen(" 源程序和地址 .txt","w");// 输出源文件 及各行对应的首地址fprintf(fa1," 输入pl0源程序文件名:");fprintf(fa1,"%s\n",fname);if(fin){printf("是否将虚拟机代码写入文件 ?(Y/N)");//是否输出虚拟机代码scanf("%s",fname);listswitch=(fname[0]=='y'||fname[0]=='Y');printf(" 是否将符号表写入文件 ?(Y/N)");//是否输出符号表scanf("%s",fname);tableswitch=(fname[0]=='y'||fname[0]=='Y');init();//初始化err=0;cc=cx=ll=0;ch='';if(-1!=getsym()){fa=fopen(" 虚拟代码.txt","w");fas=fopen(" 符号表.txt","w");.专业.整理.下载可编辑addset(nxtlev,declbegsys,statbegsys,symnum);nxtlev[period]=true;if(-1==block(0,0,nxtlev)){// 调用编译程序fclose(fa);fclose(fa1);fclose(fas);fclose(fin);return0;}if(sym!=period){error(9);// 结尾丢失了句号}if(err!=0){printf("pl0 源程序出现错误 ,退出编译!!!请从第一个错误处开始修改.\n\n");fprintf(cifa," 源程序出现错误 ,请检查!!!");fprintf(fa1," 源程序出现错误 ,请检查!!!");fprintf(fa," 源程序出现错误 ,请检查!!!");fprintf(fas," 源程序出现错误 ,请检查!!!");}fclose(fa);fclose(fa1);fclose(fas);}fclose(fin);}else{printf("Can'topenfile!\n");}fclose(cifa);//printf("\n");return0;}voidinit(){// 初始化inti;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;strcpy(&(word[0][0]),"begin");// 保留字设置,以字母顺序排列 便于折半查找strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"const");strcpy(&(word[3][0]),"do");strcpy(&(word[4][0]),"end");strcpy(&(word[5][0]),"if");strcpy(&(word[6][0]),"odd");strcpy(&(word[7][0]),"procedure");strcpy(&(word[8][0]),"read");strcpy(&(word[9][0]),"then");strcpy(&(word[10][0]),"var");strcpy(&(word[11][0]),"while");strcpy(&(word[12][0]),"write");wsym[0]=beginsym;// 设置保留字类别 一字即一类wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=endsym;wsym[5]=ifsym;wsym[6]=oddsym;wsym[7]=procsym;wsym[8]=readsym;wsym[9]=thensym;wsym[10]=varsym;wsym[11]=whilesym;wsym[12]=writesym;strcpy(&(mnemonic[lit][0]),"lit");// 设置指令名称strcpy(&(mnemonic[opr][0]),"opr");strcpy(&(mnemonic[lod][0]),"lod");strcpy(&(mnemonic[sto][0]),"sto");strcpy(&(mnemonic[cal][0]),"cal");strcpy(&(mnemonic[inte][0]),"int");.专业.整理.下载可编辑strcpy(&(mnemonic[jmp][0]),"jmp");strcpy(&(mnemonic[jpc][0]),"jpc");for(i=0;i<symnum;i++){// 设置符号集declbegsys[i]=false;statbegsys[i]=false;facbegsys[i]=false;}declbegsys[constsym]=true;// 设置声明开始符号集declbegsys[varsym]=true;declbegsys[procsym]=true;statbegsys[beginsym]=true;// 设置语句开始符号集statbegsys[callsym]=true;statbegsys[ifsym]=true;statbegsys[whilesym]=true;facbegsys[ident]=true;// 设置因子开始符号集facbegsys[number]=true;facbegsys[lparen]=true;}//用数组实现集合的集合运算intinset(inte,bool*s){returns[e];}intaddset(bool*sr,bool*s1,bool*s2,intn){inti;for(i=0;i<n;i++)sr[i]=s1[i]||s2[i];return0;}voiderror(intn){// 出错处理,打印出错位置和错误编码charspace[81];memset(space,32,81);space[cc-1]=0;printf("error(%d)",n);fprintf(fa1,"error(%d)",n);switch(n){.专业.整理.下载可编辑case1:printf("\t\t 常量说明中的“=”写成“:=”\n");fprintf(fa1,"\t\t 常量说明中的 “=”写成“:=”\n");break;case2:printf("\t\t 常量说明中的=后应该是数字\n");fprintf(fa1,"\t\t 常量说明中的 =后应该是数字\n");break;case3:printf("\t\t 常量说明符中的表示符应该是 =\n");fprintf(fa1,"\t\t 常量说明符中的表示符应该是 =\n");break;case4:printf("\t\tconst,var,procedure 后应为标识符 \n");fprintf(fa1,"\t\tconst,var,procedure 后应为标识符\n");break;case5:printf("\t\t 漏掉了“,”或“;”\n");fprintf(fa1,"\t\t 漏掉了“,”或“;”\n");break;case6:printf("\t\t 过程说明后的符号不正确 \n");fprintf(fa1,"\t\t 过程说明后的符号不正确 \n");break;case7:printf("\t\t 应是语句开始符 \n");fprintf(fa1,"\t\t 应是语句开始符 \n");break;case8:printf("\t\t 程序体内语句部分的后跟符不正确 \n");fprintf(fa1,"\t\t程序体内语句部分的后跟符不正确\n");break;case9:printf("\t\t 程序结尾丢了句号 “.”\n\n");fprintf(fa1,"\t\t 程序结尾丢了句号 “.”\n");break;case10:printf("\t\t 语句之间漏了“;”\n");.专业.整理.下载可编辑fprintf(fa1,"\t\t 语句之间漏了 “;”\n");break;case11:printf("\t\t 标识符拼写错误或未说明 \n");fprintf(fa1,"\t\t 标识符拼写错误或未说明 \n");break;case12:printf("\t\t 赋值语句中,赋值号左部标识符属性应是变量 \n");fprintf(fa1,"\t\t 赋值语句中,赋值号左部标识符属性应是变量\n");break;case13:printf("\t\t 赋值语句左部标识符后应是复制号 “:=”\n");fprintf(fa1,"\t\t 赋值语句左部标识符后应是复制号 “:=”\n");break;case14:printf("\t\tcall 后应为标识符 \n");fprintf(fa1,"\t\tcall 后应为标识符 \n");break;case15:printf("\t\tcall 后标识符属性应为过程 \n");fprintf(fa1,"\t\tcall 后标识符属性应为过程 \n");break;case16:printf("\t\t 条件语句中丢了 then\n");fprintf(fa1,"\t\t 条件语句中丢了 then\n");break;case17:printf("\t\t 丢了“end”或“;”\n");fprintf(fa1,"\t\t 丢了“end”或“;”\n");break;case18:printf("\t\twhile 型循环语句中丢了 “do”\n");fprintf(fa1,"\t\twhile 型循环语句中丢了 “do”\n");break;case19:printf("\t\t 语句后的符号不正确 \n");fprintf(fa1,"\t\t 语句后的符号不正确 \n");.专业.整理.下载可编辑break;case20:printf("\t\t 应为关系运算符 \n");fprintf(fa1,"\t\t 应为关系运算符 \n");break;case21:printf("\t\t 表达式内标示符属性不能是过程 \n");fprintf(fa1,"\t\t 表达式内标示符属性不能是过程 \n");break;case22:printf("\t\t 表达式漏掉了右括号 \n");fprintf(fa1,"\t\t 表达式漏掉了右括号 \n");break;case23:printf("\t\t 因子后的非法符号 \n");fprintf(fa1,"\t\t 因子后的非法符号 \n");break;case24:printf("\t\t 表达式的开始符不能是此符号 \n");fprintf(fa1,"\t\t 表达式的开始符不能是此符号 \n");break;case25:printf("\t\t 标识符越界\n");fprintf(fa1,"\t\t 标识符越界\n");break;case26:printf("\t\t 非法字符\n");fprintf(fa1,"\t\t 非法字符\n");break;case31:printf("\t\t 数越界\n");fprintf(fa1,"\t\t 数越界\n");break;case32:printf("\t\tread 语句括号中的标识符不是变量 \n");fprintf(fa1,"\t\tread语句括号中的标识符不是变量\n");break;case33:.专业.整理.下载可编辑printf("\t\twrite() 或read()中应为完整表达式 \n");fprintf(fa1,"\t\twrite() 或read()中应为完整表达式 \n");break;default:printf("\t\t 出现未知错误 \n");fprintf(fa1,"\t\t 出现未知错误 \n");}err++;}漏掉空格,读取一个字符,每次读一行,存入line缓冲区,line被getsym取空后再读一行,被函数getsym调用intgetch(){if(cc==ll){if(feof(fin)){printf("programincomplete");return-1;}ll=0;cc=0;printf("\n%d",cx);fprintf(fa1,"\n%d",cx);ch='';while(ch!=10){if(EOF==fscanf(fin,"%c",&ch)){line[ll]=0;break;}printf("%c",ch);fprintf(fa1,"%c",ch);line[ll]=ch;ll++;}fprintf(cifa,"\n");}ch=line[cc];cc++;return0;}intgetsym(){// 词法分析inti,j,k,l;.专业.整理.下载可编辑while(ch==''||ch==10||ch==9)// 忽略空格 换行TABgetchdo;if(ch>='a'&&ch<='z'){// 以字母开头的为保留字或者标识符k=0,l=1;do{if(k<al){//al 为标识符或保留字最大长度a[k]=ch;k++;}if(k==al&&l==1){error(25);l=0;}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];fprintf(cifa,"%s\t\t%ssym\n",id,id);//printf("%s\t\t%ssym\n",id,id);}else{//否则为标识符或数字sym=ident;fprintf(cifa,"%s\t\tident\n",id);//printf("%s\t\tident\n",id);}}else{.专业.整理.下载可编辑if(ch>='0'&&ch<='9'){k=0;num=0;sym=number;do{num=10*num+ch-'0';// 数字的数位处理k++;getchdo;}while(ch>='0'&&ch<='9');k--;if(k>nmax){// 数字的长度限制fprintf(cifa,"0\t\tnumber\n");num=0;error(31);}elsefprintf(cifa,"%d\t\tnumber\n",num);//printf("%d\t\tnumber\n",num);}else{if(ch==':'){//检测赋值符号,:只能和=匹配,否则不能识别getchdo;if(ch=='='){sym=becomes;fprintf(cifa,":=\t\tbecomes\n");getchdo;}else{sym=nul;}}else{if(ch=='<'){getchdo;if(ch=='='){sym=leq;// 小于等于fprintf(cifa,"<=\t\tleq\n");getchdo;}else{sym=lss;//小于fprintf(cifa,"<\t\tlss\n");}.专业.整理.下载可编辑}else{if(ch=='>'){getchdo;if(ch=='='){sym=geq;// 大于等于fprintf(cifa,">=\t\tgeq\n");getchdo;}else{sym=gtr;// 大于fprintf(cifa,">\t\tgtr\n");}}else{sym=ssym[ch];// 不满足上述条件时 按单字//符处理switch(ch){case'+':fprintf(cifa,"%c\t\tplus\n",ch);break;case'-':fprintf(cifa,"%c\t\tminus\n",ch);break;case'*':fprintf(cifa,"%c\t\ttimes\n",ch);break;case'/':fprintf(cifa,"%c\t\tslash\n",ch);break;case'(':fprintf(cifa,"%c\t\tlparen\n",ch);break;case')':fprintf(cifa,"%c\t\trparen\n",ch);break;case'=':fprintf(cifa,"%c\t\teql\n",ch);break;case',':fprintf(cifa,"%c\t\tcomma\n",ch);.专业.整理.下载可编辑break;case'#':fprintf(cifa,"%c\t\tneq\n",ch);break;case';':fprintf(cifa,"%c\t\tsemicolon\n",ch);break;case'.':break;default:error(26);}if(sym!=period){// 判断是否结束getchdo;}else{printf("\n");fprintf(cifa,".\t\tperiod\n");}}}}}}return0;}生成目标代码//目标代码的功能码,层差和位移量intgen(enumfctx,inty,intz){if(cx>=cxmax){// 如果目标代码索引过大 ,报错printf("Programtoolong");return-1;}code[cx].f=x;code[cx].l=y;code[cx].a=z;cx++;return0;}测试字符串.专业.整理.下载可编辑inttest(bool*s1,bool*s2,intn){if(!inset(sym,s1)){// 测试sym是否属于 s1,不属于则报错 nerror(n);while((!inset(sym,s1))&&(!inset(sym,s2))){// 检测不通过时 ,不停获得符号 ,直到它属于需要或补救的集合getsymdo;}}return0;}编译程序主体//lev:当前分程序所在层,tx:名字表当前尾指针fsys:当前模块后跟符号集合intblock(intlev,inttx,bool*fsys){inti;intdx;// 名字分配到的相对地址inttx0;// 保留初始 txintcx0;// 保留初始 cxboolnxtlev[symnum];dx=3;//相对地址从 3开始,前3个单元即 0、1、2单元分别为 SL:静态链;//DL:动态链;RA:返回地址tx0=tx;// 记录本层的初始位置table[tx].adr=cx;gendo(jmp,0,0);if(lev>levmax){// 层数超过 3error(32);}do{if(sym==constsym){// 收到常量声明printf("该语句为常量定义语句 \n");getsymdo;do{constdeclarationdo(&tx,lev,&dx);// 常量声明处理,dx会改变所以使用指针while(sym==comma){// 处理一次多常量定义getsymdo;constdeclarationdo(&tx,lev,&dx);}if(sym==semicolon){// 常量声明处理结束.专业.整理.下载可编辑getsymdo;}else{error(5);// 漏掉了逗号或者分号 (一般是分号)}}while(sym==ident);}if(sym==varsym){// 收到变量声明printf("该语句为变量声明语句 \n");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){// 收到过程声明printf("该语句为过程声明语句 \n");getsymdo;if(sym==ident){enter(procedur,&tx,lev,&dx);// 记录过程名getsymdo;}else{error(4);// 过程声明后应为标识符}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;nxtlev[period]=true;testdo(nxtlev,declbegsys,7);}while(inset(sym,declbegsys));// 直到没有声明符号code[table[tx0].adr].a=cx;// 开始生成当前过程代码table[tx0].adr=cx;// 当前过程代码地址table[tx0].size=dx;cx0=cx;gendo(inte,0,dx);// 生成分配内存代码if(tableswitch){// 输出符号表if(tx0+1<tx){fprintf(fas,"TABLE:\n");//printf("NULL\n");}for(i=tx0+1;i<=tx;i++){switch(table[i].kind){caseconstant:fprintf(fas,"%dconst%s",i,table[i].name);fprintf(fas,"val=%d\n",table[i].val);break;casevariable:fprintf(fas,"%dvar%s",i,table[i].name);fprintf(fas,"lev=%daddr=%d\n",table[i].level,table[i].adr);break;caseprocedur:.专业.整理.下载可编辑fprintf(fas,"%dproc%s",i,table[i].name);fprintf(fas,"lev=%daddr=%dsize=%d\n",table[i].level,table[i].adr,table[i].size);break;}}}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);// 输出代码return0;}//k:constvarprocedure//ptx:符号表尾的指针//pdx:dx 为当前应分配变量的相对地址//lev:符号名字所在的层次 //往符号表中添加voidenter(enumobjectk,int*ptx,intlev,int*pdx){(*ptx)++;strcpy(table[(*ptx)].name,id);table[(*ptx)].kind=k;switch(k){caseconstant:if(num>amax){error(31);num=0;}table[(*ptx)].val=num;break;casevariable:table[(*ptx)].level=lev;table[(*ptx)].adr=(*pdx);(*pdx)++;.专业.整理.下载可编辑break;caseprocedur:table[(*ptx)].level=lev;break;}}寻找符号在符号表中的地址intposition(char*idt,inttx){inti;strcpy(table[0].name,idt);i=tx;//符号表尾while(strcmp(table[i].name,idt)!=0){i--;}returni;}常量声明处理intconstdeclaration(int*ptx,intlev,int*pdx){if(sym==ident){getsymdo;if(sym==eql||sym==becomes){if(sym==becomes){error(1);}getsymdo;if(sym==number){enter(constant,ptx,lev,pdx);getsymdo;}else{error(2);}}else{error(3);}}else{error(4);}return0;}变量声明处理.专业.整理.下载可编辑intvardeclaration(int*ptx,intlev,int*pdx){if(sym==ident){enter(variable,ptx,lev,pdx);getsymdo;}else{error(4);}return0;}输出目标代码清单voidlistcode(intcx0){inti;if(listswitch){for(i=cx0;i<cx;i++){fprintf(fa,"%d%s%d%d\n",i,mnemonic[code[i].f],code[i].l,code[i],a);}}}语句处理intstatement(bool*fsys,int*ptx,intlev){inti,cx1,cx2;boolnxtlev[symnum];if(sym==ident){i=position(id,*ptx);if(i==0){error(11);}else{if(table[i].kind!=variable){error(12);i=0;}else{getsymdo;if(sym==becomes){getsymdo;printf("该语句为赋值语句 。\n");}else{error(13);.专业.整理.下载可编辑}memcpy(nxtlev,fsys,sizeof(bool)*symnum);expressiondo(nxtlev,ptx,lev);if(i!=0){gendo(sto,lev-table[i].level,table[i].adr);}}}//if(i==0)}else{//保留字匹配if(sym==readsym){printf("该语句为读语句 \n");getsymdo;if(sym!=lparen){error(34);}else{do{getsymdo;if(sym==ident){i=position(id,*ptx);}else{i=0;}if(i==0){error(35);}else{gendo(opr,0,16);gendo(sto,lev-table[i].level,table[i].adr);}getsymdo;}while(sym==comma);}if(sym!=rparen){error(33);while(!inset(sym,fsys)){getsymdo;}}else{.专业.整理.下载可编辑getsymdo;}}else{if(sym==writesym){printf("该语句为写语句 \n");getsymdo;if(sym==lparen){do{getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[rparen]=true;nxtlev[comma]=true;expressiondo(nxtlev,ptx,lev);gendo(opr,0,14);}while(sym==comma);if(sym!=rparen){error(33);}else{getsymdo;}}gendo(opr,0,15);}else{if(sym==callsym){printf("该语句为调用语句 \n");getsymdo;if(sym!=ident){error(14);}else{i=position(id,*ptx);if(i==0){error(11);}else{if(table[i].kind==procedur){gendo(cal,lev-table[i].level,table[i].adr);}else{error(15);}}getsymdo; }.专业.整理.下载可编辑}else{if(sym==ifsym){printf("该语句为if条件语句\n");getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[rparen]=true;nxtlev[comma]=true;conditiondo(nxtlev,ptx,lev);if(sym==thensym){getsymdo;}else{error(16);}cx1=cx;gendo(jpc,0,0);statementdo(fsys,ptx,lev);code[cx1].a=cx;}else{if(sym==beginsym){getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[rparen]=true;nxtlev[comma]=true;statementdo(nxtlev,ptx,lev);while(inset(sym,statbegsys)||sym==semicolon){if(sym==semicolon){getsymdo;}else{error(10);}statementdo(nxtlev,ptx,lev);}if(sym==endsym){getsymdo;}else{error(17);}}else{.专业.整理.下载可编辑if(sym==whilesym){printf("该语句为 while循环语句\n");cx1=cx;getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[dosym]=true;conditiondo(nxtlev,ptx,lev);cx2=cx;gendo(jpc,0,0);if(sym==dosym){getsymdo;}else{error(18);}statementdo(fsys,ptx,lev);gendo(jmp,0,cx1);code[cx2].a=cx;}else{memset(nxtlev,0,sizeof(bool)*symnum);testdo(fsys,nxtlev,19);}}}}}}}return0;}intexpression(bool*fsys,int*ptx,intlev){enumsymboladdop;boolnxtlev[symnum];if(sym==plus||sym==minus){addop=sym;getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[plus]=true;nxtlev[minus]=true;termdo(fsys,ptx,lev);.专业.整理.下载可编辑if(addop==minus)gendo(opr,0,1);}else{memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[plus]=true;nxtlev[minus]=true;termdo(fsys,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);}}return0;}intterm(bool*fsys,int*ptx,intlev){enumsymbolmulop;boolnxtlev[symnum];memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[times]=true;nxtlev[slash]=true;factordo(nxtlev,ptx,lev);while(sym==times||sym==slash){mulop=sym;getsymdo;factordo(nxtlev,ptx,lev);if(mulop==times){gendo(opr,0,4);}else{gendo(opr,0,5);}.专业.整理.下载可编辑}return0;}intfactor(bool*fsys,int*ptx,intlev){inti;boolnxtlev[symnum];testdo(facbegsys,fsys,24);while(inset(sym,facbegsys)){if(sym==ident){i=position(id,*ptx);if(i==0){error(11);}else{switch(table[i].kind){caseconstant:gendo(lit,0,table[i].val);break;casevariable:gendo(lod,lev-table[i].level,table[i].adr);break;caseprocedur:error(21);break;}}getsymdo;}else{if(sym==number){if(num>amax){error(31);num=0;}gendo(lit,0,num);getsymdo;}else{if(sym==lparen){getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[rparen]=true;expressiondo(nxtlev,ptx,lev);if(sym==rparen){.专业.整理.下载可编辑getsymdo;}else{error(22);}}testdo(fsys,facbegsys,23);}}}return0;}intcondition(bool*fsys,int*ptx,intlev){enumsymbolrelop;boolnxtlev[symnum];if(sym==oddsym){getsymdo;expressiondo(fsys,ptx,lev);gendo(opr,0,6);}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;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){caseeql:gendo(opr,0,8);break;caseneq:gendo(opr,0,9);break;.专业.整理.下载可编辑caselss:gendo(opr,0,10);break;casegeq:gendo(opr,0,11);break;casegtr:gendo(opr,0,12);break;caseleq:gendo(opr,0,13);break;}}}return0;}//pl0 头文件#definenorw13#definetxmax100#definenmax14#defineal10#defineamax2047#definelevmax3#definecxmax200enumsymbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym,};#definesymnum32enumobject{.专业.整理.constant,variable,procedur,};enumfct{lit, opr,sto, cal,jmp, jpc,};#definefctnum8structinstruction{enumfctf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论