IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) 2
更新时间:2024-06-09 00:59:01 阅读量: 综合文库 文档下载
武汉理工大学《编译原理》课程设计说明书
IF-ELSE条件语句的翻译程序设计
1 问题描述
要求用LL(1)自顶向下分析方法及三地址中间代码,对IF-THEN-ELSE条件语句完成编译各阶段过程,包括词法、语法、语义等分析。
2 问题分析及编译系统的概要设计
编译过程一般分为六个阶段的过程,可以由六个模块完成,它们称为词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成程序,此外,一个完整编译程序还必须包括“表格管理程序”和“出错处理程序”。
这次实验涉及到词法分析、语法分析、语义分析及表格管理和出错管理。其中,词法分析至少要能识别关键字“if”、“then”和“else”,标识符(即自定义变量),数字,和运算符等等;语法分析要分析程序结构的合法性,即是否为文法的句子;语义分析要能够语法制导翻译出中间代码(三地址)并将其输出;表格管理是指符号表;出错处理是指在语法分析时,所有非文法句子的错误类型处理.
3 文法及属性文法的定义 3.1 文法:
文法是用于描述语言的语法结构的形式规则(即语法规则)。这些规则必须是准确的、易于理解的以及有相当强的描述能力。由这种规则所产生的程序语言应有利于句子分析和翻译,而且,最好能通过这些规则自动产生有效的语法分析程序.
IF-ELSE条件语句的文法如下所示:
0.A->EB
1.B->+EB|-EB|ε 2.E->FT 3.T->*FT|/FT|ε 4.F->i|(E) 或者能够更简洁一点:
0.S->if A THEN B ELSE C 1.A->m rop n 2.B->x=m arop n
1
武汉理工大学《编译原理》课程设计说明书
3.C->x=n arop m 4.rop->=|<|> 5.arop->+|-|*|/
3.2 属性文法:
属性文法是在上下文无关文法的基础上,为每个文法符号(终结符或者非终结符)
配备若干相关的“值”(与文法符号相关的属性)。
在一个属性文法中,对应于每个产生式A→a都有一套与之相关联的语义规则,每规则的形式为:b:=f(c1,c2,?,ck)其中f是一个函数,而且或者①b是A的一个综合属性并且c1,c2,?,ck是产生式右边文法符号的属性或者②非终结符既可有综合属性也可有继属性,文法开始符号的所有继承属性作为属性计算前的初始值。
属性文法为:
if(VT[opr]=='=') //{\判断}; { }
else if(VT[opr]=='>') //{\判断}; { }
2
arr[d][1]=arr_i[opd]; arr[d][0]='='; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
arr[d][1]=arr_i[opd]; arr[d][0]='>'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
武汉理工大学《编译原理》课程设计说明书
else if(VT[opr]=='<') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='<'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
}
else if(VT[opr]=='+') { arr[d][1]=arr_i[opd]; arr[d][0]='+'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
}
else if(VT[opr]=='-') { arr[d][1]=arr_i[opd]; arr[d][0]='-'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
}
else if(VT[opr]=='*') {
//{\判断}; //{\判断}; //{\判断}; 3
武汉理工大学《编译原理》课程设计说明书
}
arr[d][1]=arr_i[opd]; arr[d][0]='*'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
else if(VT[opr]=='/') //{\判断}; { }
else if(opr==-2) //{其他字符判断}; {
arr[d][1]=id-1; arr[d][1]=arr_i[opd]; arr[d][0]='/'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++;
arr[d][0]=' '; } else
if(VT[opr]!='<'&&VT[opr]!='>'&&VT[opr]!='+'&&VT[opr]!='-'&&VT[opr]!='*'&&VT[opr]!='/')//{\结束符判断};
{
4
arr[d][2]=arr_i[opd]; arr[d][3]=' '; arr[d][4]=' ';
arr[d][1]=id-1;
武汉理工大学《编译原理》课程设计说明书
d++; }
4 词法分析
首先应该创建一个枚举类型的变量来存放一些关键字:
char VN[11]={'K','L','P','S','E','G','T','R','F','Q','\\0'}; //产名生式头 char VT[16]={'i','=','<','>','+','-','*','/','(',')','f','t','e',';','\\0'}; //特征字符集
再创建一个结构体,用来存放词法分析的结果,共有两个域,一个关键字域,表明
他是什么类型,以及它自身的内容。
这个词法分析程序比较简单,因为本身的程序就局限在if-else语句,所以保留字
的类型我就只写了if、then和else三个;碰到数字开头的除了关键字就是标识符;碰到数字开头的就是数字;碰到界限符和操作符(因为引入的类型也很少),所以也很容易区别。
在词法分析结束之后,就应该把分析的结果输出来。输出的格式是【(单词,类型
编号) 类型名】
源程序文件
字符的分离
单词的判断
查找相应的表
单词的类型的判断
调用不同类型的单词处
理函数进行单词的处理
产生类型码
将中间单词和其类型码存入数组
处理完毕
5
武汉理工大学《编译原理》课程设计说明书
词法分析程序如下: void lexical()
{ //\是其一条特殊的例子 int i,j,d; char ch; j=d=0; for(i=0;var[i]!='#';i++) { ch=var[i]; if(ch=='i'&&var[i+1]=='f') { cout<<\关键字]\ queue[j++]='f';i+=1; }//{判断\关键字} else if(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]; } } } cout<<\关键字]\ queue[j++]='t';i+=3; }//{判断\关键字} else if(ch=='e') { ch=var[i+5]; if(ch=='l') { ch=var[i+6]; if(ch=='s') { ch=var[i+7]; if(ch=='e')
6
武汉理工大学《编译原理》课程设计说明书
{ ch=var[i+8]; } } } cout<<\关键字]\ queue[j++]='e';i+=3; }//{判断\关键字} else if(index(ch,VT)<=0) { if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')') { cout< 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}, 7 武汉理工大学《编译原理》课程设计说明书 {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代表此处无 产生式与之对应。 void syntax() { int n; 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') //{\是特征字母} { if(a!='f'&&a!='t'&&a!='e'&&a!=';'&&a!='#') { opr=index(a,VT); 8 武汉理工大学《编译原理》课程设计说明书 } semantic(); else if(a==';'||a=='e'||a=='t'||a=='#') { opr=-2; } else f=1; //字符不匹配,转去出错处理 } else { int tx=index(X,VN);//{索引选择} int ta=index(a,VT);//{索引选择} n=M[tx][ta]; //{产生式选择} td[t++]=M[tx][ta]; //{产生式选择} if(ta==-1) { f=2;cout< opd=c; //cout< cout<<'\\t'<<'\\''< cout<<'\\t'<<'\\''< semantic(); } //字符没有出现在产生式终结符集VT中,转去出错处理 else if(n==-1)f=3; //没有找到合适的候选产生式来做进一步推导,转去出错处理 9 武汉理工大学《编译原理》课程设计说明书 } else { //用产生式M[tx][ta]来做进一步推导 } } if(f==0)syntax(); else { td[t]='-1'; err(f); } sp--; cout<<'\\t'< else cout<<\空串\ for(int i=len(p[n])-1;i>=0;i--) { } cout< stack[++sp]=p[n][i]; cout< 因为在推导过程中,会一并完成产生式后面附加的语义动作,所以这两部分是一起做的。 另外,在LL(1)分析过程中,会出现错误信息,如字符不匹配,或字符没有出现在产生式终结符集VT中,或没有找到合适的候选产生式来做进一步推导,会调用相应的出错处理函数err(f)。另外,此函数是递归实现,结束标志是f!=0,即成功或失败。 10 武汉理工大学《编译原理》课程设计说明书 11 武汉理工大学《编译原理》课程设计说明书 6 出错处理 由于输入的表达式有错误就要产生相应的出错处理函数 void err(int n) { if(n==1) cout<<\字符不匹配\ else if(n==2) cout<<\字符没有出现在产生式终结符集VT中\ else if(n==3) cout<<\没有找到合适的候选产生式来做进一步推导\ else cout<<\该句子是文法语言的句子!\} 7 语义分析及中间代码输出 根据上面给出的属性文法所规定的翻译方案,即可对输入的程序进行相应的语义分 析。对于中间代码部分,老师给的题目是以三地址的形式输出。对于三地址形式,在学习编译原理的时候接触的不是很多。我们接触的多的一般都是逆波兰式和四元式。仔细看书才发现,三地址和四元式是很相近的。比如说计算一个表达式a+b-c,四元式的形式是(+,a,b,t1),(-,t1,c,t2)。而三地址的形式为t1:=a+b,t2=t1-c。而对于跳转语句,无条件跳转如jump L1的四元式形式为(jump,-,-,L1);而其对应的三地址形式为goto L1。而对于条件跳转语句,则四元式为(jrop,a,b,L1),而三地址形式为if a rop b goto L1。 产生跳转的主要有三个地方,第一,就是if条件成立,则跳转到then后面的语局;第二,执行完then后面的语句后跳转到程序的出口;第三,就是if条件不成立则跳转到else后面的语句。在判断完if后面的条件后,保存这个布尔值,并产生跳转地址,这时,应该继续向前读取,如果碰到then这个关键字,则回填地址到then前面,否则报错。 关键是回填地址的那个函数一定要写准确。在有跳转的语句后面,一定要有跳转的地址,即要跳到什么地方。产生跳转的语句有在token这个结构体中有个地址域,用来保存转向的地址。而在产生运算结果的语句中,token这个结构体中有个result域,用来保存这个结果。 //打印词法分析结果 void print() 12 武汉理工大学《编译原理》课程设计说明书 { cout<<\ if(count<10)cout<<'0'; cout< for(i=0;i<=sp;i++)cout< for(;queue[i]!='#';i++)cout< for(;i<=20;i++)cout<<\} //语义分析程序 void semantic() { if(VT[opr]=='=') { arr[d][1]=arr_i[opd]; arr[d][0]='='; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='>') { arr[d][1]=arr_i[opd]; arr[d][0]='>'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='<') { arr[d][1]=arr_i[opd]; arr[d][0]='<'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='+') { //{\判断}; //{\判断}; //{\判断}; //{\判断}; 13 武汉理工大学《编译原理》课程设计说明书 arr[d][1]=arr_i[opd]; arr[d][0]='+'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='-') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='-'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='*') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='*'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='/') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='/'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(opr==-2) //{其他字符判断}; { arr[d][1]=id-1; arr[d][0]=' '; arr[d][2]=arr_i[opd]; arr[d][3]=' '; arr[d][4]=' '; } else if(VT[opr]!='<'&&VT[opr]!='>'&&VT[opr]!='+'&&VT[opr]!='-'&&VT[opr]!='*'&&VT[opr]!='/')//{\结束符判断}; 14 武汉理工大学《编译原理》课程设计说明书 arr[d][1]=id-1; { d++; } } //输出三地址 cout<<\输出三地址:\ for(i=0;i 而三元式的输出则很简单。但也要根据它具体的语义来进行输出。如果是if语句,则要根据if后面的bool语句来实现跳转。如果为真,应该调到then后面的语句,如果为假,则跳转到else后面的语句,每个语句都有自己的标号,用label来标识。而对于每个计算结果的表达式,则首先用一个中间变量来存放结果,每次按照运算符的优先级算出一个结果,保存在中间变量中,最后将中间变量的结果赋给语句中的变量。 8 软件测试方法和结果 输入一组正确的词法和语法的if-else语句,和一组有词法错误和语法错误的if语句。 1. if {m>n} then i=i+3 else b=b/2 测试结果如下: 15 武汉理工大学《编译原理》课程设计说明书 char queue[MAX]; int sp,front; int M[10][14]={ {-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}, {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}, }; //预测分析表 int f=0; int count=0; int c=0; char arr_i[MAX]; //字符管理 char var[MAX]; //表格管理 int td[MAX]; //输出产生式序列 int t=0; int opd=-1; int opr=-1; int id=0; //int ptr[MAX]; int d=0; char arr[MAX][5]; //存放待输出的三地址 //char keyword[2][11]={\ int len(char str[]) { int i=0; while(str[i]!='\\0')i++; return i; } int index(char ch,char str[]) { int i=0; while(str[i]!='\\0') { if(ch!=str[i])i++; else break; } if(str[i]=='\\0')return -1; return i; 21 武汉理工大学《编译原理》课程设计说明书 } //出错管理选项 void err(int n) { if(n==1) cout<<\字符不匹配\ else if(n==2) cout<<\字符没有出现在产生式终结符集VT中\ else if(n==3) cout<<\没有找到合适的候选产生式来做进一步推导\ else cout<<\该句子是文法语言的句子!\} //打印此法分析结果 void print() { cout<<\ if(count<10)cout<<'0'; cout< //语义分析程序 void semantic() { if(VT[opr]=='=') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='='; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='>') //{\判断}; { arr[d][1]=arr_i[opd]; 22 武汉理工大学《编译原理》课程设计说明书 arr[d][0]='>'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='<') //{\判断}; { arr[d][1]=arr_i[opd]; arr[d][0]='<'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='+') { arr[d][1]=arr_i[opd]; arr[d][0]='+'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='-') { arr[d][1]=arr_i[opd]; arr[d][0]='-'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='*') { arr[d][1]=arr_i[opd]; arr[d][0]='*'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(VT[opr]=='/') { arr[d][1]=arr_i[opd]; //{\判断}; //{\判断}; //{\判断}; //{\判断};23 武汉理工大学《编译原理》课程设计说明书 arr[d][0]='/'; arr[d][2]=id; arr[d][3]=' '; arr[d][4]=' '; id++; } else if(opr==-2) //{其他字符判断}; { arr[d][1]=id-1; arr[d][0]=' '; arr[d][2]=arr_i[opd]; arr[d][3]=' '; arr[d][4]=' '; } else if(VT[opr]!='<'&&VT[opr]!='>'&&VT[opr]!='+'&&VT[opr]!='-'&&VT[opr]!='*'&&VT[opr]!='/')//{\结束符判断}; arr[d][1]=id-1; { d++; } } //语法分析程序 void syntax() { int n; 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') //{\是特征字母} { if(a!='f'&&a!='t'&&a!='e'&&a!=';'&&a!='#') { opr=index(a,VT); semantic(); } 24 武汉理工大学《编译原理》课程设计说明书 else if(a==';'||a=='e'||a=='t'||a=='#') { opr=-2; semantic(); } cout<<'\\t'<<'\\''<=0;i--) { stack[++sp]=p[n][i]; cout< if(f==0)syntax(); else 25 武汉理工大学《编译原理》课程设计说明书 { td[t]='-1'; err(f); } } //测法分析程序 void lexical() { //\是其一条特殊的例子 int i,j,d; char ch; j=d=0; for(i=0;var[i]!='#';i++) { ch=var[i]; if(ch=='i'&&var[i+1]=='f') { cout<<\关键字]\ queue[j++]='f';i+=1; }//{判断\关键字} else if(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]; } } } cout<<\关键字]\ queue[j++]='t';i+=3; }//{判断\关键字} else if(ch=='e') { ch=var[i+5]; if(ch=='l') { ch=var[i+6]; 26 武汉理工大学《编译原理》课程设计说明书 if(ch=='s') { ch=var[i+7]; if(ch=='e') { ch=var[i+8]; } } } cout<<\关键字]\ queue[j++]='e';i+=3; }//{判断\关键字} else if(index(ch,VT)<=0) { if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')') { cout< //主函数 int main() //主程序 { int i=0; char S='K'; sp=front=0; stack[0]='#'; sp++; stack[1]='K'; cout<<\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ 27 武汉理工大学《编译原理》课程设计说明书 cout<<\ | IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) |\ cout<<\ | made by Jebb Xu|\ cout<<\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ cout< εε 28
正在阅读:
IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) 206-09
水利技术标准体系表05-22
ch1.3 古典概率模型07-26
统计分析在葡萄酒质量评价中的应用07-26
IE助理工程师考核试题及答案07-26
关务工作中经常困扰的问题12-21
同济大学附属天佑医院网络推广主管招聘07-26
全市村容村貌综合整治考核验收方案08-07
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 程序设计
- 语句
- 输出
- 表示
- 条件
- 翻译
- 地址
- ELSE
- LL
- 护理文书质量标准
- 清北学堂2013年五一生物竞赛模拟押题试卷3含标记答案(苏宏鑫)
- 邵培仁《传播学》教材内容梳理
- 中国游戏健身车行业市场调查研究报告(目录) - 图文
- 初等数论期末考试试卷张
- 国军全部战绩与日军战报的对比
- 绿带2006试题(带答案)
- 食品科学与工程专业 本科 毕业论文 蜂蜜软枣果酒的研制
- 商务印书馆同人录(布衣书局论坛老陈整理)
- 傅雷家书中考名著导读试题及答案
- 物质的量浓度学案教学设计
- 中学乡土地理教育发展和建设策略的研究
- 2010920185456小学语文六年级上册教学计划
- 立体几何证明题归类
- (免费)小学英语六年级英语语法及测试题
- 南岸小学2017年春季科学实验室工作计划
- 某公司薪酬现状分析及对策研究
- 质量手册(外企)
- 地价监测技术与工作问题解答
- 监理挂靠合同2(1)