小型编译程序的设计与实现_第1页
小型编译程序的设计与实现_第2页
小型编译程序的设计与实现_第3页
小型编译程序的设计与实现_第4页
小型编译程序的设计与实现_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

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

文档简介

小型编译程序的设计与实现本实验设计的小型编译程序涉及到编译前端的三个阶段:词法分析、语法分析和语义分析生成中间代码(四元式),编译程序的重点放在中间代码生成阶段。编译程序的输出结果包括词法分析后的二元式序列、变量名表;语法分析后的状态栈分析过程显示;语义分析生成中间代码后的四元式程序。整个程序分为三个部分:(1) 词法分析部分(2) 语法分析、语义分析及四元式生成部分(3) 输出显示部分1•词法分析器设计词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别编码,单词自身的值)由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查。1.1单词符号的内部定义及在编译程序中的定义我们对常量、变量、临时变量、保留关键字(if、while、begin、end、else、then、dobegin、号、括号等,规定其内部定义如下:符号 种别编码 说明sy」f0保留字ifsy_then1保留字thensy_else2彳保留字elsesy_while3彳保留字whilesy_begin4彳保留字beginsy_do5保留字dosy_end6保留字enda7赋值语句semicoIon8a. »Je9布尔表达式Jinghao10“#”S11语句L12复合语句Tempsy 15Tempsy 15EA 18EO 19Plus 34Times 36Becomes 38Op_and 39Op_or 40Op_not 41Rop 42Lparent 48Rparent 49Ident 56Intconst 57临时变量Band(即布尔表达式中的BABor(即布尔表达式中的BV“+”“*”“:=”赋值“1»and°or»not关系运算符“(”a»变量变量整常量

#inelude"stdio.h"/*#include"string.h"如果使用#inelude"stdio.h"/*#include"string.h"如果使用TC的话,需要配置头文件路径*/#defineACC-2/************************/#definesy_if0#definesy_then1#definesy_else2#definesy_while3#definesy_begin4#definesy_do5#definesy_end6#definea7#definesemicoIon8#definee9#definejinghao10#defineS11#defineL12#definetempsy15#defineEA18/*Eand*/#defineE019/Eor*/#defineplus34#definetimes36#definebecomes38#defineop_and39#defineop_or40#defineop_not41#definerop42#defineIparent48#definerparent49#defineident56#defineintconst5712变量及数据结构说明编译程序中涉及到的变量及数据结构说明如下:charch='\0:/*从字符缓冲区读取当前字符*/intcount=O;/*词法分析结果缓冲区计数器*/staticcharspelling[10]={""};/* 存放识别的字*/staticcharline[81]={""};/* 一行字符缓冲区,最多 80个字符*/char*pline;/* 字符缓冲区指针*/staticcharntab1[100][10];/* 变量名表,共 100项,每项长度10*/structntab{inttc;/* 真值*/intfc;/* 假值*/}ntab2[200];/*在布尔表达式E中保存有关布尔变量的真、假值*/intlabel=0;/*指向ntab2的指针*/structrwords(charsp[10];intsy;};/*保留字表的结构,用来与输入缓冲区中的单词进行匹配 */structrwordsreswords[10]={{"if",sy_if},{"do”,sy_do},{"else",sy_else},{"while",sy_while},{"then",sy_then},{"begin",sy_begin},{"end",sy_end},{"and",op_and},{"or",op_or},{"not”,op_not}};/* 保留字表初始化,大小为10*/structaa{intsy1;/* 存放单词的种别编码*/intpos;/* 存放单词自身的值*/}buf[1000],/*词法分析结果缓冲区*/n,/*读取二元式的当前字符*/n1,/*当前表达式中的字符*/E,/*非终结符*/sstack[100],/*算术或布尔表达式加工处理使用的符号栈*/ibuf[100],/*算术或布尔表达式使用的缓冲区*/stack[1000];/* 语法分析加工处理使用的符号栈*/structaaoth;/* 四元式中的空白位置*/structfourexp(charop[10];structaaargl;structaaarg2;intresult;}fexp[200];/* 四元式的结构定义*/intssp=0;/*指向sstack栈指针*/structaa*pbuf=buf;/* 指向词法分析缓冲区的指针*/intnlength=0;/* 词法分析中记录单词的长度*/inttt1=0;/*变量名表指针*/char*cfile;/* 源程序文件,~为结束符*/intInum=0;/* 源程序行数记数*/intsign=0; /*sign=1为赋值语句;=2为while语句;=3为if语句*//*******************************************************/intnewt=0;/*临时变量计数器*/intnxq=100;/*nxq 总是指向下一个将要形成的四元式地址,*//*每次执行gen()时,地址自动增1*/intlr;/*扫描LR分析表1过程中保存的当前状态值*/intlr1;/*扫描LR分析表2或表3所保存的当前状态值*/intsp=0;/*查找LR分析表时状态栈的栈顶指针*/intstack1[100];/*状态栈1定义*/intsp仁0;/*状态栈1的栈顶指针*/intnum=O;/*算术或布尔表达式缓冲区指针*/struct11(intnxql;/* 记录下一条四元式的地址*/inttc1;/* 真值链*/intfc1;/* 假值链*/}labelmark[10];/* 记录语句嵌套层次的数组,*//*即记录嵌套中每层的布尔表达式 E的首地址*/intlabeltemp[10];/* 记录语句嵌套层次的数组,*//*即记录每层else之前的四元式地址*/intpointmark=-1,/*labelmark数组指针*/pointtemp=-1;/*labeltemp数组指针*/1.3主函数main()voidmain((cfile=fopen("pas.dat","r";/* 打开C语言源文件*/readch(;/*从源文件读一个字符*/scan(;/*词法分析*/disp1(;disp3(;stack[sp].pos=0;stack[sp].sy1=-1;/* 初始化状态栈*/stack1[sp1]=0;/* 初始化状态栈1*/oth.sy1=-1;printf(岫*************** 状态栈变化过程以及归约顺序 ************树*readnu(;/*从二元式读入一个符号*/lrparse(;/* 语法语义分析产生四兀式*/getch(;disp2(;printf("\n 程序运行结束!\n";getch(;1.4词法分析函数说明(1)读取函数readline(、readch(词法分析包含从源文件读取字符的操作,但频繁的读文件会影响程序执行效率,故实际上是从源程序文件“pas.dat”中读取一行到输入缓)中区,而词法分析过程中每次读取一个字符时则是通过执行 readch()从输入缓)中区获得的;若缓冲区已被读空,则再执行readline()从pas.dat中读取下一行至输入缓)中区。忡 从文件读一行到缓)中区 “/readline((charchi;pline=line;ch1=getc(cfile;while(ch1!='\n'&&!feof(cfile{*pline=ch1;pline++;ch1=getc(cfile;pline='\O';pline=line;尸* 从缓)中区读取一个字符 *7readch((if(ch=='\O'{readline(;Inum++;}ch=*pline;pline++;}(2)扫描函数scan(扫描函数scan()的功能是滤除多余空格并对主要单词进行分析处理,将分析得到的二元式存入二元式结果缓)中区。广 扫描主函数 “/scan({inti;while(ch!=''/* ''是源程序结束符号*/{switch(ch{case'':break;case'a':case'b':case'c':case'd':case'e':casef:case'g':case'h':case'i':case'j':case'k':caseT:case'm':case'n':case'o':case'p':case'q':case'r':case's':case't':case'u':case'v':case'w':case'x':case'y':case'z':/*保留字和标识符中的字母只能是小写字母*/identifier(;/* 识别保留字和标识符*/break;case'O':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case9:number(;/*识别整常数*/break;case'<':readch(;if(ch=='='{buf[count].pos=0;/*识别'<='*/elseelse{buf[count].pos=1;/* 识别'<'*/pline--;}}buf[count].sy1=rop; 识别关系运算符*//*count++;break;case'>':readch(;if(ch=='='{ 识别'>=*/buf[count].pos=2;/*}else{ 识别'>'*/buf[count].pos=3;/*pline--;} 识别关系运算符*/buf[count].sy1=rop;/*count++;breake'(':count++;break;case”:buf[count].sy仁rparent;/* 识别''*/count++;break;case'#':buf[count].sy1=jinghao;/* 识别'#'*/count++;break;case'+':buf[count].sy仁plus;/* 识别'+'*/count++;break;casebuf[count].sy仁times;/*识别'*'*/count++;break;readch(;if(ch=='='buf[count].sy1=becomes;/*识别’:='*/count++;break;buf[count].sy仁rop;buf[count].pos=5;/*识别’=',关系算符*/count++;break;case';':buf[count].sy1=semicoIon;/* 识别’;’*/count++;break;}readch(;}buf[count].sy1=-1;/* 不可识别的符号*/}(3)变量处理及变量名表find(变量处理中首先把以字胃开头的字胃数字串存到 spelling[10]数组中,然后进行识别。识别过程是先让它与保留关键字表中的所有关键字进行匹配,若获得成功则说明它为保留关键字,即将其内码值写入二元式结果缓)中区;否则说明其为变量,这时让它与变量名表中的变量进行匹配(变量匹配函数 find()),如果成功,则说明该变量已存在并在二元式结果缓)中区中标记为此变量(单词自身值填为该变量在变量名表中的位置),否则将该变量登记到变量名表中,再将这个新变量存入二元式缓存数组中。********************/******************* **/变量匹配,查找变量名表find(charspel[](intss1=0;intii=0;while((ss1==0&&(ii(if(!strcmp(spel,ntab1[ii]ss仁1;/* 查找,匹配*/ii++;}if(ss仁=1returnii-1;/*查找到*/elsereturn-1;/* 没查找到*/}............. 标识符和保留字的识另寸******************//**identifier((intiii=0,j,k;intss=0;k=0;do(spelling[k]=ch;k++;readch(;}while(((ch>='a'&&(ch<='z'||((ch>='0'&&(ch<='9:pline--;spelling[k]='\O';while((ss==O&&(iii<10(if(!strcmp(spelling,reswords[iii].sp ss=1;/* 保留字匹配*/...iii++;if(ss==1(buf[count].sy仁reswords[iii-1].sy;/*是保留字*/}else{buf[count].sy仁ident;/*是标识符,变量名*/j=find(spelling;if(j==-1/*没有在变量名表中则添加*/{buf[count].pos=tt1;/*tt1 是变量名表指针*/strcpy(ntab1[tt1],spelling;tt1++;nlength++;elsebuf[count].pos=j;/* 获得变量名自身的值*/count++;for(k=0;k<10;k++spelling[k]=” 清空单词符号缓)中区*/}(5)数字识别number(数字识别将识别出的数字转换为等值的十进制数值并填入二元式结果缓存数组。户 数字识别 **/number((intivalue=0;intdigit;do{digit=ch-'0';ivalue=ivalue*10+digit;/*readch(;}while((ch>='0'&&(ch<=9;buf[co数字字符转换为十进制整常数*/unt].sy1=intconst;/*buf[count].pos=ivalue;count++;Pline--; 整常数单词符号二元式*/(6)显示函数显示函数的功能是在屏幕上输出词法分析的结果(即二元式序列和变量名表),同时给出二元式个数及源程序行数统计。户 显示词法分析结果:单词符号二元式—*1disp1({inttemp1=0;printf("\n*********词法分析结果************************、n,,;for(temp1=0;temp1{printf("%d\t%d\n",buf[temp1].sy1,buf[temp1].pos;if(temp1==20{printf("Pressanykeytocontinue..…\n";getch(;))getch(;)/** 打印变量名表 **/voiddisp3({inttttt;getch(;r尸;r**************变量名表printf("\n\n程序总共%4行,产生了getch(;r尸;r**************变量名表*******************一一**\n";for(tttt=0;ttttprintf("%d\t%s\n",tttt,ntab1[tttt];getch(;}2.语法语义分析器设计语法语义分析器的核心是描述程序语句、算术表达式、布尔表达式语法分析的三张LR分析表以及针对这三张LR分析表进行语义加工的语义动作。编译程序中语法分析处理及四元式生成部分主要是以二元式作为输入,并且通过 LR分析表对语法分析处理过程进行控制,使四元式翻译的工作有条不紊的进行,同时识别语法分析中的语法错误。在处理if和while语句时,需要进行真值或假值的拉链和回填工作,以便转移目标的正确填入。2.1LR分析表及实现(1)程序语句的文法及LR分析表实现程序语句的文法G[S]如下:4ifethenSelseS|whileedoS|beginLend|aL—S;L|S在本小型编译程序的设计与实现中,我们将赋值语句与算术表达式归为一类处理,故在此处将赋值语句仅看作为程序语句文法中的一个终结符号 a,将布尔表达式也看作终结符号e。将文法G[S]拓广为G[S']:(0S'—S(1S—ifethenSelseS(2S—whileedoS(3S—beginLend(4Sa(5L—S(6L—S;L由此得到程序语句LR分析的SLR(1)分析表如下:ACTIGONOTOthenelsewhiles2begindoendas3s4s2s10r4Is3 s4r4;e#SLs5 1accs6s7s5 9 8s2s3s4s11s12r5s5s1314状态if01234567891011s2s3s412r313s2s3s414s1715r21617s2s3s4r118staticintaction[19][13]=r3s5r3r3伟s5 69 1r2r2 r2r6s5 18r1 r1 r1在小型编译程序中程序语句的 SLR(1)分析表设计如下:/** 程序语句的LR分析表 **//*0*/{{2,-1,-1,3,4,-1,-1,5,-1,-1,10,1,-1},/*1*/{-1,-1, -1,-1, -1,-1, -1, -1, -1, -1,ACC,-1,-1},/*2*/{-1, -1, -1,-1, -1,-1, -1, -1, -1,6,-1,-1,-1},/*3*/{-1, -1, -1,-1, -1,-1, -1, -1, -1,7,-1,-1,-1},/*4*/{2, -1, -1,3,4,-1,-1,5, -1, -1, -1,9,8},/*5*/{-1,-1,104,-1,-1,-1,104,-1,104,-1,104,-1,-1},/*6*/{-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*7*/{-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1},/*8*/{-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1},/*9*/{-1,-1,-1,-1,-1,-1,105,-1,13,-1,-1,-1,-1},1*10*1{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,14,-1},/*11*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,15,-1},/*12*/{-1,-1,103,-1,-1,-1,103,-1,103,-1,103,-1,-1},/*13*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,16},/*14*/{-1,-1,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*15*/{-1,-1,102,-1,-1,-1,102,-1,102,-1,102,-1,-1},/*16*/{-1,-1,-1,-1,-1,-1,106,-1,-1,-1,-1,-1,-1},/*17*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,18,-1},/*18*/{-1,-1,101,-1,-1,-1,101,-1,101,-1,101,-1,-1}};其中前11列为action值,后2列为goto值;018表示19个移进状态(即Sj);-1表示出错;acc表示分析成功;而100106对应7个归约产生式:100:S'—S101:S—ifethenSelseSe是布尔表达式,看作终结符号102:S—whileedoS103:S—beginLend104:S—aa是赋值语句,看作终结符号105:L—S106:L—S;L算术表达式的文法G[E]如下:E—E+E|E*E|(E)|i状 状 ACTION态0 +。2 S3S3S3将文法G[E]拓广为G[S'](0S'—E(1E—E+E(2E—E*E(3E—(E(4E—i由此得到算术表达式LR分析的SLR(1)分析表如下:GOTOTOC\o"1-5"\h\z* ( ) #EIs2 1s4s5 accs2 6r4 r4 r4 r4s2 7s2 8s4 s5 s9r1 s5 r1 r1编译程序中算术表达式的SLR(1分析表设计如下:尸 算术表达式的LR分析表 ***********************staticintaction1[10][7]=/©/{{3,T,-1,2,T,T,1},/*1*/{-1,4,5,-1,-1,ACC,-1},/*2*/{3,-1,-1,2,-1,-1,6},/*3*/{-1,104,104,-1,104,104,-1},/*4*/{3,-1,-1,2,-1,-1,7},/*5*/{3,-1,-1,2,-1,-1,8},/*6*/{-1,4,5,-1,9,-1,-1},/*7*/{-1,101,5,-1,101,101,-1},/*8*/{-1,102,102,-1,102,102,-1},/*9*/{-1,103,103,-1,103,103,-1}};其中前6列为action值,后1列为goto值;09表示10个移进状态(即Sj);-1表示出错;ACCv示分析成功;而100104对应5个归约产生式:100:S'—E101:E—E+E102:E—E*E103:E—(E布尔表达式的文法G[B]如下:4BAB|BVB|B|(B|iropi|i为了便于语法分析时的加工处理,将上述文法改写为文法 G[S]:BAB/AB|BOB|B|(B|iropi|ibAfbAbOfBV将文法G[S]拓广为文法G[S'](0S'fB(1Bfi(2Bfiropi(3Bf(B(4BfnotB(5AfBand(6BfAB(7OfBor(8BfOB由此得到算术表达式LR分析的SLR(1)分析表如下:状ACTION GOTO态ropnotandor#BAOropcozzzcoz二 9(N 兰O史 新史 %gsg gs s(XI 二寸 寸s sCO COCOOOOoOOsCOss6SCO6S6SCMSCOOL COs s。Lc\jcoCMco15r8s9s10r8编译程序中布尔表达式LR分析的SLR(1分析表设计如下:尸* 布尔表达式的LR分析表 **/staticintaction2[16][11]=1*0*1{{1,-1,4,-1,5,-1,-1,-1,13,7,8},/*1*/{-1,2,-1,101,-1,101,101,101,-1,-1,-1},/*2*/{3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*3*/{-1,-1,-1,102,-1,102,102,102,-1,-1,-1},/*4*/{1,-1,4,-1,5,-1,-1,-1,11,7,8},/*5*/{1,-1,4,-1,5,-1,-1,-1,6,7,8},/*6*/{-1,-1,-1,104,-1,9,10,104,-1,-1,-1},/*7*/{1,-1,4,-1,5,-1,-1,-1, 14,7,8},/*8*/{1,-1,4,-1,5,-1,-1,-1, 15,7,8},/*9*/{105,-1,105,-1,105,-1,-1,-1,-1,-1,-1},/*10*/{107,-1,107,-1,107,-1,-1,-1,-1,-1,-1},/*11*/{-1,-1,-1, 12,-1,9,10, -1, -1, -1, -1 }, /*12*/ {-1, -1, -1,103,-1,103,103,103,-1,-1,-1},/*13*/{-1,-1, -1, -1, -1,9,10,acc,-1, -1, -1 },/*14*/{-1,-1,-1,106,-1,9,10,106,-1,-1,-1},/*15*/{-1,-1,-1,108,-1,9,10,108,-1,-1,-1}};其中前8列为action值,后3列为goto值;015表示16个移进状态(即Sj);-1表示出错;acc表示分析成功;而100108对应9个归约产生式:100:S'—B101:B102:B—iropi103:B-(B104:B—notB105:A—Band106:B—AB107:O—Bor108:B—OB2.2算术表达式处理的语义加工程序根据算术表达式文法中产生式对应的语义动作,相应的加工处理程序如下:*****************赋值语句和算术表达式的分析********************/*****************Irparse1(intnum(intIr1;lr仁action1[stack1[sp1]][change1(nl.syl];if(lr1==-1{printf("\n 算术表示式或赋值语句出错!! \n";getch(;exit(0;}if((lr1<10&&(lr1>=0/*当前查找LR分析表中的状态为移进状态*/sp1++;stack1[sp1]=lr1;if(n1.sy1!=tempsy(ssp++;num++;sstack[ssp].sy仁n1.sy1;/*将变量名压栈*/sstack[ssp].pos=nl.pos;/*将变量名地址压栈*/)n1.sy1=ibuf[num].sy1;n1.pos=ibuf[num].pos;lrparse1(num;}if((lr1>=100&&(lr1,105/* 当前查找LR分析表中的状态为归约状态*/{switch(lr1{case100:/*SE*/break;case101:/*E—E+E*/E.pos=newtemp(;gen(H+"5sstack[ssp-2]5sstack[ssp]5E.pos+100;ssp=ssp-2;sstack[ssp].sy1=tempsy;sstack[ssp].pos=E.pos;sp1=sp1-3;break;E.pos=newtemp(;gen("*",sstack[ssp-2],sstack[sspLE.pos+100;ssp=ssp-2;sstack[ssp].sy仁tempsy;sstack[ssp].pos=E.pos;sp仁sp1-3;/*E—E+E产生式右部长度为3,故归约后栈指针减3*/break;case103:/*E—(E)*/E.pos=sstack[ssp-1].pos;ssp=ssp-2;sstack[ssp].sy1=tempsy;sstack[ssp].pos=E.pos;sp1=sp1-3;break;case104:/*E—i*/E.pos=sstack[ssp].pos;sp1--;break;}n1.sy仁tempsy;/*归约后为非终结符*/n1.pos=E.pos;lrparse1(num;if((lri==ACC&&(stack1[sp1]==1/* 赋值语句A"i:=E的归约*/(gen(":二",sstack[ssp],oth,ibuf[0].pos;ssp=ssp-3;sp1=sp1-3;)}2.3布尔表达式处理的语义加工程序根据布尔表达式文法中产生式对应的语义动作,相应的加工处理程序如下:lrparse2(intnum{inttemplabel;lr仁action2[stack1[sp1]][change2(n1.sy1];if(lr1==-1{if(sign==2printf("\nwhile语句出错!\n";if(sign==3printf("\nif语句出错!\n";getch(;exit(0;}if((lr1<16&&(Ir1>=0/*当前查找LR分析表中的状态为移进状态*/{sp1++;stack1[sp1]=lr1;ssp++;sstack[ssp].sy1=nl.syl;sstack[ssp].pos=nl.pos;if((n1.sy1!=tempsy&&(n1.sy1!=EA&&(n1.sy1!=E0num++;n1.sy1=ibuf[num].sy1;n1.pos=ibuf[num].pos;lrparse2(num;}if((lr1>=100&&(Ir1<109/*当前查找LR分析表中的状态为归约状态*/{switch(lr1{case100:/*SB*/break;case101:/*B—i*/ntab2[label].tc=nxq;ntab2[label].fc=nxq+1;gen("jnz",sstack[ssp],oth,0;gen("j",oth,oth,0;sp1--;ssp--;label++;n1.sy1=tempsy;break;case102:/* 4iropi*/ntab2[label].tc=nxq;ntab2[label].fc=nxq+1;switch(sstack[ssp-1].pos{case0:gen(Hjv=",sstack[ssp-2],sstack[ssp],0;break;case1:gen(Hjv",sstack[ssp-2],sstack[ssp],0;break;case2:gen(Hj>=",sstack[ssp-2],sstack[ssp],0;break;case3:gen(Hj>",sstack[ssp-2],sstack[ssp],0;break;case4:gen(Hjv>",sstack[ssp-2],sstack[ssp],0;break;case5:gen(Hj=",sstack[ssp-2],sstack[ssp],0;break;}gen("j",oth,oth,0;ssp=ssp-3;sp仁sp1-3;label++;n1.sy仁tempsy;break;label=label-1;ssp=ssp-3;sp1=sp1-3;label++;n1.sy1=tempsy;break;case104:/*B—notB*/label=label-1;templabel=ntab2[label].tc;ntab2[label].tc=ntab2[label].fc;ntab2[label].fc=templabel;ssp=ssp-2;sp1=sp1-2;label++;n1.sy1=tempsy;break;case105:/*A—Band*/backpatch(ntab2[label-1].tc,nxq;label=label-1;ssp=ssp-2;sp仁sp1-2;label++;n1.sy1=EA;break;label=label-2;ntab2[label].tc=ntab2[label+1].tc;ntab2[label].fc=merg(ntab2[label].fc,ntab2[label+1].fc;ssp=ssp-2;sp1=sp1-2;label++;n1.sy仁tempsy;break;case107:/*O—Bor*/backpatch(ntab2[label-1].fc,nxq;label=label-1;ssp=ssp-2;sp1=sp1-2;label++;n1.sy1=E0;break;case108:/*B—0B*/label=label-2;ntab2[label].fc=ntab2[label+1].fc;ntab2[label].tc=merg(ntab2[label].tc,ntab2[label+1].tc;ssp=ssp-2;sp1=sp1-2;label++;n1.sy仁tempsy;break;}lrparse2(num;}if(lr1==ACCreturn1;}2.4程序语句的语义加工程序程呈序语句处壬理——***/程呈序语句处壬理——***//**********************lrparse({inti1=0;intnum=0;/*指向算术或布尔表达式缓冲区指针初始化 */if(test(n.sy1{if(stack[sp].sy1==sy_whilesign=2;elseif(stack[sp].sy1==sy_ifsign=3;elsesign=1;}doibuf[i1].sy1=n.syl;ibuf[i1].pos=n.pos;readnu(;i1++;}while(test(n.sy1;/* 把算术或布尔表达式放入缓冲区*/ibuf[i1].sy1=jinghao;pbuf--;/*词法分析缓冲区指针减1*/sstack[0].sy1=jinghao;ssp=0;/*符号栈初始化*/if(sign==1/* 处理赋值语句中的算术表达式*/{sp仁0;stack1[sp1]=0;/*状态栈1初始化*/num=2;n1.sy仁ibuf[num].sy1;/*指向:=*/n1.pos=ibuf[num].pos;lrparse1(num;/*处理赋值语句*/n.sy仁a;/*当前文法符号置为a(赋值语句)*/if((sign==2||(sign==3/*处理while或if语句中的布尔表达式*/{pointmark++;labelmark[pointmark].nxq1=nxq;sp仁0;stack1[sp1]=0;num=0;n1.sy1=ibuf[num].sy1;n1.pos=ibuf[num].pos;lrparse2(num;labelmark[pointmark].tc1=ntab2[label-1].tc;labelmark[pointmark].fc1=ntab2[label-1].fc;/*处理布尔表达式e(此处的e即为布尔表达式文法中的B)*/backpatch(labelmark[pointmark].tc1,nxq;/*处理完e后回填真值链*/n.sy仁e;/*当前文法符号置为e(布尔表达式)*/}}lr=action[stack[sp].pos][n.sy1];printf("stack[%d]=%d\t\tn=5d\t\tlr=%d\n",sp,stack[sp].pos,n.sy1,lr;/*输出状态栈信息*/if((lr<19&&(lr>=0/*程序语句LR分析表中的移进状态处理*/{sp++;stack[sp].pos=lr;stack[sp].sy1=n.sy1;readnu(;Irparse(;}if((lr<=106&&(lr>=100/* 程序语句LR分析表中的归约状态处理*/{switch(lr{case100:/*S'—S*/break;case101:/*S—ifethenSelseS*/printf("S->ifethenSelseS归约\n";sp=sp-6;n.sy仁S;/*归约完if后,填then后面的无条件转移语句*/fexp[labeltemp[pointtemp]].result=nxq;pointtemp--;if(stack[sp].sy1==sy_then{gen("j",oth,oth,0;backpatch(labelmark[pointmark].fc1,nxq;pointtemp++;labeltemp[pointtemp]=nxq-1;}pointmark--;if(stack[sp].sy1==sy_do{gen("j",oth,oth,labelmark[pointmark].nxq1;backpatch(labelmark[pointmark].fc1,nxq;}break;case102:/*S—whileedoS*/printf("S->whileedoSsp=sp-4;归约\n";n.sy仁S;/*归约完后,填doS后面的无条件转移语句*/pointmark--;if(stack[sp].sy1==sy_do(gen("j",oth,oth,labelmark[pointmark].nxql;backpatch(labelmark[pointmark].fc1,nxq;}fexp[labeltemp[pointtemp]].result=nxq;if(stack[sp].sy1==sy_then(gen("j",oth,oth,0;fexp[labelmark[pointmark].fc1].result=nxq;pointtemp++;labeltemp[pointtemp]=nxq-1;}break;case103:/*S—beginLend*/printf("S->beginLend归约\n";sp=sp-3;n.sy仁S;if(stack[sp].sy1==sy_then{gen("j",oth,oth,0;backpatch(labelmark[pointmark].fc1,nxq;pointtemp++;labeltemp[pointtemp]=nxq-1;}if(stack[sp].sy1==sy_do{gen("j",oth,oth,labelmark[pointmark].nxq1;backpatch(labelmark[pointmark].fc1,nxq;}getch(;break;case104:/*S—a*/printf("S->a归约\n";sp=sp-1;n.sy仁S;if(stack[sp].sy1==sy_then{gen("j",oth,oth,0;backpatch(labelmark[pointmark].fc1,nxq;pointtemp++;labeltemp[pointtemp]=nxq-1;if(stack[sp].sy1==sy_dogen("j",oth,oth,labelmark[pointmark].nxql;backpatch(labelmark[pointmark].fc1,nxq;}break;case105:/*L—S*/printf("L->S归约\n";sp=sp-1;n.sy1=L;break;case106:/*L—S;L*/printf("L->S;L归约\n";sp=sp-3;n.sy1=L;break;}getch(;pbuf--;lrparse(;}if(lr==ACCreturnACC;}上机实验内容实验一词法分析程序的设计、分析与验证⑴实验目的:学习设计词法分析程序,验证词法分析的方法⑵实验准备:阅读与本次实验有关的内容小型语言关于单词的内部定义;小型编译程序中关于词法分析的程序说明。⑶实验内容:设计、输入、调试一个小型语言的词法分析程序输入PAS.DAT 源程序,输出单词符号二元式⑷实验检查:机上检查,提问,要求读懂程序,会分析输出的结果。单词符号的定义,一般来说。不论用什么语言实现编译器,都要使用整型的常量来定义各种单词符号。词法分析程序的基本数据结构:ch、spelling[10]、structaa{intsyl;intpos;}buf[1000]3•词法分析程序的初始化,用readline(把输入流中的字符读到内存的缓冲区中,预置当前字符的位置,并且调用readch(预读一个字符到ch中。扫描下一个字符,需要移动字符指针找到下一个字符并把它赋给ch,注意维护当前字符所在的位置信息。扫描下一个符号,根据当前的字符ch来判断下面的符号可能是什么,然后调用scan(处理。⑸问题:1•词法分析器的功能是什么?输入是什么?输出是什么?程序语言的单词符号一般分为几类?小型编译程序定义了哪些单词?单词符号的内部表示是什么?单词符号二元式由哪两部分组成?5•词法分析程序的结构?会分析输出的结果。6•输出的变量名表与单词符号二元式结果的关系,起什么作用?小型编译程序如何识别标识符和保留字、数值常量、关系运算符?如何过滤空白字符?解释几个函数:identifier(、number(、find(charspel[]。解释几个数据结构:扩充:若源程序可以有注释"/*……*/”,那么如何对注释进行过滤处理?实验二小型编译程序的分析与验证⑴实验目的:学习并验证语法分析(LR方法、语义分析产生中间代码(四元式的方法⑵实验准备:阅读与本次实验有关的内容关于小型编译程序的说明;源程序文本。⑶实验内容:输入、调试小型编译程序PAS.C用源程序PAS.DAT予以验证⑷实验检查:机上检查,提问,要求读懂程序,会分析输出的结果。⑸问题:源程序语句的结构。源程序与输出的四元式程序的对应:源程序的哪部分对应哪些四元式?3读懂并会分析四元式程序。序号为106、111、116的四元式起什么作用?解释语法分析过程中,输出的状态栈的变化情况,理解移进和归约。会不会手工翻译源程序为四元式。解释几个函数。解释几个数据结构。对各种语言成分的分析。实验三小型编译程序的扩充(算术表达式扩充)⑴实验目的:学习LR分析表的设计方法和语义加工程序的扩充⑵实验准备:阅读与本次实验有关的内容关于小型编译程序的说明;源程序文本。算术表达式文法扩充为:E=E+E|E-E|E*E|E/E|(E)|i⑶实验内容:参照算术表达式LR分析表的设计方法,设计扩充后的算术表达式的LR分析表,并对原语义加工程序进行修改,验证修改的结果⑷实验检查:机上检查,提问,要求读懂程序,会分析输出的结果。⑸问题:构造扩充算术表达式文法的LR(0项目集规范族,构造其SLR(1分析表。指出对程序作出了哪些修改。验证结果。编译程序运行实例实例-待编译的pas.dat源程序如下:while(a>bdobeginifm>=nthena:=a+1elsewhilek=hdox:=x+2;m:=n+x*(m+yend#~经编译程序运行后得到的输出结果如下:*******词法分析结果*******/*注释:查单词内部定义和下面的变量名表 */0/*(sy_while,0)*/480/*(”(”,0*/423/*(rop,“>”*/561/*(变量,b)*/490/*(”)”,0*/50/*(sy_do,0)*/0/*(sy_begin,0)*/00/*(sy_if,0)*/562/*(变量,m)*/422/*(rop, “>=”*/563/*(变量,n)*/0/*(sy_then,0)*/560/*(变量,a)*/380/*(”:=”),070/*(变量,a)*/340/*(”+”),0*/1/*(整常量,1)*/0/*(sy_else,0*/0/*(sy_while,0)*/564/*(变量,k)*/565/*(变量,h)*/0/*(sy_do,0)*/566/*(变量,x)*/380/*(”:=”),076/*(变量,x)*/340/*(”+”),0*/2/*(整常量,2)*/80/*(”;”),07562/*(变量,m)*/380/*(”:=”),07563/*(变量,n)*/340/*(”+”),0*/566/*(变量,x)*/360/*(”*”),0*/0/*(”(”,0*/562/*(变量,m)*/340/*(”+”),0*/567/*(变量,y)*/0/*(”)”,)*/0/*(sy_end,0*/100/*(”时),0*/程序共9行,产生43个二元式!****

温馨提示

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

评论

0/150

提交评论