您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) 2
武汉理工大学《编译原理》课程设计说明书1IF-ELSE条件语句的翻译程序设计1问题描述要求用LL(1)自顶向下分析方法及三地址中间代码,对IF-THEN-ELSE条件语句完成编译各阶段过程,包括词法、语法、语义等分析。2问题分析及编译系统的概要设计编译过程一般分为六个阶段的过程,可以由六个模块完成,它们称为词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成程序,此外,一个完整编译程序还必须包括“表格管理程序”和“出错处理程序”。这次实验涉及到词法分析、语法分析、语义分析及表格管理和出错管理。其中,词法分析至少要能识别关键字“if”、“then”和“else”,标识符(即自定义变量),数字,和运算符等等;语法分析要分析程序结构的合法性,即是否为文法的句子;语义分析要能够语法制导翻译出中间代码(三地址)并将其输出;表格管理是指符号表;出错处理是指在语法分析时,所有非文法句子的错误类型处理.3文法及属性文法的定义3.1文法:文法是用于描述语言的语法结构的形式规则(即语法规则)。这些规则必须是准确的、易于理解的以及有相当强的描述能力。由这种规则所产生的程序语言应有利于句子分析和翻译,而且,最好能通过这些规则自动产生有效的语法分析程序.IF-ELSE条件语句的文法如下所示:0.A-EB1.B-+EB|-EB|ε2.E-FT3.T-*FT|/FT|ε4.F-i|(E)或者能够更简洁一点:0.S-ifATHENBELSEC1.A-mropn2.B-x=maropn武汉理工大学《编译原理》课程设计说明书23.C-x=naropm4.rop-=||5.arop-+|-|*|/3.2属性文法:属性文法是在上下文无关文法的基础上,为每个文法符号(终结符或者非终结符)配备若干相关的“值”(与文法符号相关的属性)。在一个属性文法中,对应于每个产生式A→a都有一套与之相关联的语义规则,每规则的形式为:b:=f(c1,c2,…,ck)其中f是一个函数,而且或者①b是A的一个综合属性并且c1,c2,…,ck是产生式右边文法符号的属性或者②非终结符既可有综合属性也可有继属性,文法开始符号的所有继承属性作为属性计算前的初始值。属性文法为:if(VT[opr]=='=')//{=判断};{arr[d][1]=arr_i[opd];arr[d][0]='=';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(VT[opr]=='')//{判断};{arr[d][1]=arr_i[opd];arr[d][0]='';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}武汉理工大学《编译原理》课程设计说明书3elseif(VT[opr]=='')//{判断};{arr[d][1]=arr_i[opd];arr[d][0]='';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(VT[opr]=='+')//{+判断};{arr[d][1]=arr_i[opd];arr[d][0]='+';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(VT[opr]=='-')//{-判断};{arr[d][1]=arr_i[opd];arr[d][0]='-';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(VT[opr]=='*')//{*判断};{武汉理工大学《编译原理》课程设计说明书4arr[d][1]=arr_i[opd];arr[d][0]='*';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(VT[opr]=='/')//{/判断};{arr[d][1]=arr_i[opd];arr[d][0]='/';arr[d][2]=id;arr[d][3]='';arr[d][4]='';id++;}elseif(opr==-2)//{其他字符判断};{arr[d][1]=id-1;arr[d][0]='';arr[d][2]=arr_i[opd];arr[d][3]='';arr[d][4]='';}elseif(VT[opr]!=''&&VT[opr]!=''&&VT[opr]!='+'&&VT[opr]!='-'&&VT[opr]!='*'&&VT[opr]!='/')//{#结束符判断};arr[d][1]=id-1;{武汉理工大学《编译原理》课程设计说明书5d++;}4词法分析首先应该创建一个枚举类型的变量来存放一些关键字:charVN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};//产名生式头charVT[16]={'i','=','','','+','-','*','/','(',')','f','t','e',';','\0'};//特征字符集再创建一个结构体,用来存放词法分析的结果,共有两个域,一个关键字域,表明他是什么类型,以及它自身的内容。这个词法分析程序比较简单,因为本身的程序就局限在if-else语句,所以保留字的类型我就只写了if、then和else三个;碰到数字开头的除了关键字就是标识符;碰到数字开头的就是数字;碰到界限符和操作符(因为引入的类型也很少),所以也很容易区别。在词法分析结束之后,就应该把分析的结果输出来。输出的格式是【(单词,类型编号)类型名】源程序文件字符的分离单词的判断查找相应的表单词的类型的判断调用不同类型的单词处理函数进行单词的处理产生类型码将中间单词和其类型码存入数组处理完毕武汉理工大学《编译原理》课程设计说明书6词法分析程序如下:voidlexical(){//if{mn}theni=i+9elseb=b/3#是其一条特殊的例子inti,j,d;charch;j=d=0;for(i=0;var[i]!='#';i++){ch=var[i];if(ch=='i'&&var[i+1]=='f'){coutif'\t'keyword'\t''\t'[关键字]endl;queue[j++]='f';i+=1;}//{判断if关键字}elseif(ch=='t'){ch=var[i+1];if(ch=='h'){ch=var[i+2];if(ch=='e'){ch=var[i+3];if(ch=='n'){ch=var[i+4];}}}coutthen'\t'keyword'\t''\t'[关键字]endl;queue[j++]='t';i+=3;}//{判断then关键字}elseif(ch=='e'){ch=var[i+5];if(ch=='l'){ch=var[i+6];if(ch=='s'){ch=var[i+7];if(ch=='e')武汉理工大学《编译原理》课程设计说明书7{ch=var[i+8];}}}coutelse'\t'keyword'\t''\t'[关键字]endl;queue[j++]='e';i+=3;}//{判断else关键字}elseif(index(ch,VT)=0){if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')'){coutch'\t'variable:i[d++]'\t'[标示符]endl;arr_i[d-1]=ch;queue[j++]='i';}elsecoutch'\t'bound'\t''\t'[括号]endl;}elseif(index(ch,VT)0){coutch'\t'operator'\t'[运算符]endl;queue[j++]=ch;}}queue[j]='#';//{#就直接跳出}for(i=0;queue[i]!='#';i++)coutqueue[i];coutendl;}5语法分析主要的思想是设置一个分析栈和一个输入串队列,栈中最开始时存放的是文法开始符和“#”。因为我这个程序本身已经确定是以if语句开头,所以,就不再把if放在输入串中,而只是分析if以后的句子。在语法分析之前应该判定该文法是不是一个LL(1)文法。判别的主要方法是做出文法中所有产生式的select集,对于同一个非终结符的不同产生式,如果他们的select集合没有交集,则说明这个文法是LL(1)文法。这个文法的预测分析表也设计的比较简单,如下表所示:{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1},{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,-1},武汉理工大学《编译原理》课程设计说明书8{4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{5,-1,-1,-1,-1,-1,-1,-1,5,-1,-1,-1,-1,-1},{-1,-1,-1,-1,6,7,-1,-1,-1,-1,-1,8,8,8},{9,-1,-1,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,-1},{-1,-1,-1,-1,12,12,10,11,-1,-1,-1,12,12,12},{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},//预测分析表注:除了-1代表此处有产生式与之对应,具体的产生式在程序中给出。-1代表此处无产生式与之对应。voidsyntax(){intn;count++;print();X=stack[sp];a=queue[front];if(X=='#'&&a=='#')f=4;if(X'A'||X'Z')//{判断字符集不是大写字母集合}{if(X==a){sp--;front++;if(a!='i')//{i是特征字母}{if(a!='f'&&a!='t'&&a!='e'&&a!=';'&&a!='#'){opr=index(a,VT);武汉理工大学《编译原理》课程设计说明书9semantic();}elseif(a==';'||a=='e'||a=='t'||a=='#'){opr=-2;semantic();}cout'\t''\''a'匹配endl;}else{opd=c;//coutopd1opd2;cout'\t''\''arr_i[c++]'匹配endl;}}elsef=1;//字符不匹配,转去出错处理}else{inttx=index(X,VN);//{索引选择}intta=index(a,VT);//{索引选择}n=M[tx][ta];//{产生式选择}td[t++]=M[tx][ta];//{产生式选择}if(ta==-1){f=2;coutaendl;}//字符没有出现在产生式终结符集VT中,转去出错处理elseif(n==-1)f=3;//没有找到合适的候选产生式来做进一步推导,转去出错处理武汉理工大学《编译原理》课程设计说明书10else{//用产生式M[tx][ta]来做进一步推导sp--;cout'\t'X-;if(len(p[n])!=0){for(inti=len(p[n])-1;i=0;i--){stack[++sp]=p[n][i];coutp[n][len(p[n])-1-i];}coute
本文标题:IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) 2
链接地址:https://www.777doc.com/doc-4213874 .html