编译原理while语句的翻译

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计
题目WHILE循环语句的翻译程序设计(简单
优先法、输出四元式)
学院计算机科学与技术学院
专业计算机科学与技术专业
班级1003班
姓名刘颖
指导教师李玉强
2013 年 1 月11 日
目录
任务书 (2)
1.系统描述 (3)
2.文法及属性文法的描述 (3)
3.语法分析方法的描述及分析表设计 (3)
3.1.语法分析方法的描述 (3)
3.2.优先关系表 (4)
4.1.中间代码形式的描述 (4)
4.2.中间代码序列的结构设计 (4)
5.编译系统的概要设计 (4)
6.详细的算法描述(流程图或伪代码) (5)
6.1.主函数伪代码 (5)
6.2.词法分析总控流程图 (5)
6.3.语法分析 (5)
7.源程序 (6)
7.1.优先关系 (6)
7.2.词法分析 (6)
7.3.语法分析 (10)
7.4.归约函数 (10)
8.软件的测试方法和测试结果 (11)
8.1.输入 (11)
8.2.词法分析结果 (11)
8.3.语法分析结果 (12)
9.研制报告 (12)
10.参考文献 (13)
11.开发工具 (13)
评分表 (14)
课程设计任务书
学生姓名:刘颖专业班级:计算机1003班
指导教师:李玉强工作单位:计算机科学与技术学院
题目: WHILE循环语句的翻译程序设计(简单优先法、输出四元式)
初始条件:
理论:学完编译原理课程,掌握一种计算机高级语言的使用。

实践:计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码四元式的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:
1 系统描述(问题域描述);
2 文法及属性文法的描述;
3 语法分析方法描述及语法分析表设计;
4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;
5 编译系统的概要设计;
6 详细的算法描述(流程图或伪代码);
7 软件的测试方法和测试结果;
8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);
9 参考文献(按公开发表的规范书写)。

时间安排:
设计安排一周:周1、周2:完成系统分析及设计。

周3、周4:完成程序调试及测试。

周5:撰写课程设计报告。

设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。

设计报告书收取时间:设计周的次周星期一上午10点。

指导教师签名: 2012年 11月 13日
系主任(或责任教师)签名: 2012年 11月 13日
一、系统描述(问题域描述)
理解和分析C++中的while循环语句,应用在《编译原理》课程中学习的词法分析、语法分析、语义分析、中间代码生成及四元式等知识,用简单优先法分析while语句,并用四元式形式输出。

词法分析的输入取自含有while循环语句的txt文件,结果存入另一txt文件并作为语法分析的输入。

1.按给定的题目写出符合自身语法分析方法要求的文法和属性文法描述。

2.按给定的题目给出语法分析方法的思想及分析表设计。

3.按给定的题目给出中间代码序列的结构设计。

4.完成相应的词法分析、语法分析和语义分析程序设计。

5.编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

二、文法及属性文法的描述
文法G=(V
N ,V
T
,P ,S)
V
N
={S,C,E,F,}
V
T
={while,do,(,),{,},;,0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,w,x,y,z,_,+,-,*,%,/,<,>,=,<=,>=,==,!=,.} P={
S->while C do E=F
C->(F>F)|(F<F)|(F==F)|(F>=F)|(F<=F)|(F)
F->E|E+E|E*E|E-E|E/E
E->character|number
character->a|b|...|z|character(a|b|...|z)
number->0|1...|9|number(0|1 (9)
}
三、语法分析方法的描述及分析表设计
3.1语法分析方法的描述
简单优先分析法是按照文法符号(终极符和非终极符)的优先关系确定句柄的。

首先根据已知文法求出相应优先关系,并将文法的产生式保存,设置符号栈S,步骤如下:
(1)将输入符号串a
1a
2
…a
n
#依次逐个存入符号栈S中,直到遇到栈顶符号a
i
的优先性>
下一个待输入符号a
j
为止。

(2)栈顶当前符号a
i 为句柄尾,由此向左在栈中找句柄的头符号a
k
,即找到a
k-1
<a
k
为止。

(3)由句柄a
k ... a
i
在文法的产生式中查找右部为a
k
…a
i
的产生式,若找到则用相应左
部代替句柄,若找不到则为出错,这时可断定输入串不是该文法的句子。

(4)重复上述(1)、(2)、(3)步骤直到规约完输入符号串,栈中只剩文法的开始符号
为止。

若不能归约到文法开始符号则认为输入的while语句语法有误,进行报错。

3.2优先关系表
根据产生式确定优先关系,在程序中以二维数组存取,直接初始化即可。

四、中间代码形式描述及中间代码序列的结构设计
4.1中间代码形式的描述
中间代码有两种形式:词法分析的二元组和语法分析过程中的四元式。

二元组的两个元素是字符(串)的类型和它本身;四元式的四个组成成分是:算符,第一和第二运算对象及运算结果。

运算对象和运算结果有时指用户自己定义的变量,有时指编译程序引进的临时变量。

4.2 中间代码序列的结构设计
词法分析后对字符(串)的类型已判断完毕,依次输出,形式如下:
1.关键字 while
2.数字 10
3.界符;
4.标识符 i
5.运算符 >
语法分析之后,取出其中的运算表达式。

对表达式进行分析。

其中,先乘除后加减,先运算括号内的。

如a=b*c+b*d 的四元式表示如下:
1.(*,b, c, t
1

2.(*, b, d, t
2
)
3.(+, t
1, t
2
, t
3
)
4.(=, t
3
, -, a)
五、编译系统的概要设计
1 通过程序,在in.txt文本中输入while语句。

对文本进行扫描,通过词法分析函数对输入的while语句进行词法分析,结果以二元式形式保存在out.txt中。

2 将已算好的优先关系矩阵以二维数组的形式放至程序中。

对已进行词法分析的while语句进行语法分析,其中包括进栈函数和归约,当满足归约条件时由进栈函数调用规约函数,其中包含对错误语句的报错处理。

将分析过程输出到yufafenxi.txt中
3 通过四元式输出函数将运算表达式表示为四元式的形式,输出到yufafenxi.txt中。

六、详细的算法描述(流程图)
6.1.主函数伪代码
void main()
{
Precedence();//调用优先关系函数求解
Lexical();//调用词法分析程序
Syntax();//调用语法分析程序
}
6.2.词法分析总控程序
6.3.语法分析程序
七、源程序
7.1.优先关系函数
void Precedence()
{
int i,j;
for(i=0;i<=16;i++)
{ for(j=0;j<=16;j++)
{ PreTable[i][j]=ER;
PreTable[1][0]=LT;
}
}
for(i=0;i<=8;i++) PreTable[i][8]=PreTable[i][10]=PreTable[i][11]=PreTable[i][14]=LT; PreTable[1][8]=PreTable[1][11]=PreTable[1][14]=ER;
PreTable[6][14]=PreTable[7][14]=PreTable[1][12]=PreTable[0][13]=EQ;
PreTable[0][15]=LT;
PreTable[2][15]=PreTable[3][15]=PreTable[4][15]=PreTable[5][15]=PreTable[8][15]=EQ; for(i=9;i<=11;i++)
{ for(j=1;j<8;j++)
{ PreTable[i][j]=GT;
PreTable[9][5]=PreTable[11][5]=ER;
PreTable[10][5]=PreTable[13][1]=EQ;
PreTable[9][9]=PreTable[10][9]=PreTable[11][9]=GT;
PreTable[9][16]=PreTable[10][16]=PreTable[11][16]=PreTable[12][16]=GT;
PreTable[14][1]=PreTable[14][2]=PreTable[14][3]=PreTable[14][4]=GT;
PreTable[14][6]=PreTable[14][7]=EQ;
PreTable[14][9]=PreTable[14][16]=PreTable[15][1]=PreTable[15][16]=GT;
PreTable[15][2]=PreTable[15][3]=PreTable[15][4]=PreTable[15][9]=EQ;
PreTable[16][0]=PreTable[16][10]=LT;
}
}
}
7.2.词法分析函数
void Lexical()
{
char *pch,str[100],*pstr,*pt;
char ch[200]={'\0'};
int length;
int i=0,u=-1;
while(!infile.eof())//判断文件是否读完?
{
u++;
ch[u]=infile.get();
}
pch=ch;
length=strlen(ch);
pch=ch;
printf("词法分析结果:\n");
outfc<<"词法分析结果: "<<endl;
while(pch<=ch+length)
{
pstr=str;
while(*pch==' '||*pch=='('||*pch==')') pch++;
pt=pch;
f(isalpha(*pch))
{ while(isalnum(*pch))
{ *pstr=*pch;
pstr++;
pch++;
}
*pstr='\0';
if(strcmp(str,"while")==0)
{
printf("关键字 while\n");
outfc<<"关键字while"<<endl;
Buff[i].p=0;
Buff[i++].adr=NULL;
}
else if(strcmp(str,"do")==0)
{
printf("关键字 do\n");
outfc<<"关键字 do"<<endl;
Buff[i].p=1;
Buff[i++].adr=NULL;
}
else
{
printf("标识符 ");
outfc<<"标识符 ";
printf(str);
printf("\n");
outfc<<str<<endl;
Buff[i].p=10;
Buff[i++].adr=pt;
}
}
else if(isdigit(*pch))
{ pt=pch;
printf("数字 ");
outfc<<"数字 ";
while(isdigit(*pch))
{ printf("%c",*pch);
outfc<<*pch;
pch++;
}
outfc<<endl;
printf(" ");
outfc<<" ";
Buff[i].p=11;
Buff[i++].adr=pt;
}
if(*pch=='=')
{ if(*(pch+1)=='=')
{ printf("等于 ==\n");
outfc<<"等于 =="<<endl; pch++;
pch++;
Buff[i].p=4;
Buff[i++].adr=NULL;
}
else
{ printf("赋值符 =\n");
outfc<<"赋值符 ="<<endl; pch++;
Buff[i].p=5;
Buff[i++].adr=NULL;
}
}
else if(*pch=='*')
{ printf("乘号 *\n");
outfc<<"乘号 *"<<endl;
pch++;
Buff[i].p=7;
Buff[i++].adr=NULL;
}
else if(*pch=='+')
{ printf("加号 +\n");
outfc<<"加号 +"<<endl;
pch++;
Buff[i].p=6;
Buff[i++].adr=NULL;
}
else if(*pch=='-')
{ t=1;
printf("减号 -\n");
outfc<<"减号 -"<<endl;
pch++;
Buff[i].p=6;
Buff[i++].adr=NULL;
}
else if(*pch=='/')
{ t=1;
printf("除号 /\n");
outfc<<"除号 /"<<endl;
pch++;
Buff[i].p=7;
Buff[i++].adr=NULL;
}
else if(*pch =='<')
{ printf("小于号 <\n");
outfc<<"小于号 <"<<endl;
pch++;
Buff[i].p=3;
Buff[i++].adr=NULL;
}
else if(*pch=='>')
{ printf("大于号 >\n");
outfc<<"大于号 >"<<endl;
pch++;
Buff[i].p=2;
Buff[i++].adr=NULL;
}
else if(*pch=='\0')
{ printf("\n词法分析正确结束!");
pch++;
Buff[i].p=16;
Buff[i++].adr=NULL;
}
else pch++;
}
7.3.语法分析函数
bool Syntax()
{ int ip = 0;
printf("\n\n\n语法分析过程为:\n");
InitStack();
while (true)
{ if (GetValue().p==12 && Buff[ip].p==16&&Top==2)
{ printf("语法分析正确结束!\n"); return true; }
else if (GetValue().p==-1)
{ printf("语法错误!\n"); return false; }
else
{ switch (GetPrecedence(GetValue().p, Buff[ip].p))
{ case LT:
case EQ: Push(Buff[ip].p,Buff[ip].adr); ip++; PrintStack(); break;
case GT: Reduce(); PrintStack(); break;
default: printf("语法错误!\n"); return false;
}
}
}
}
7.4.归约函数
void Reduce()
{ structure outstring[10];
int len;
int c;
len=1;
outstring[len].p=GetValue().p;
outstring[len].adr=Pop().adr;
c=GetValue().p;
while (GetPrecedence(c,outstring[len].p)==EQ)
{ outstring[++len].p=GetValue().p;
outstring[len].adr=Pop().adr;
c=GetValue().p;
if(len==3&&outstring[1].p==14&&outstring[3].p==14) break;
}
if(len==1&&(outstring[1].p==10||outstring[1].p==11))
{ print(outstring[1].adr);
Push(14,outstring[1].adr);
}
else if (len==1&&outstring[1].p==14) Push(15,outstring[1].adr);
else if (len==3&&outstring[1].p==14&&outstring[3].p==14)
{ middle[n++]='#';
middle[n++]=Tn++;
Push(15,&middle[n-2]);
}
else if (len==3&&outstring[1].p==9) Push(14,outstring[1].adr);
else if (len==4&&outstring[1].p==12) Push(12,NULL);
else if (len==3&&outstring[1].p==15&&outstring[3].p==10) Push(12,NULL);
else if (len>=3&&outstring[len].p==15)
{ middle[n++]='#';
middle[n++]=Tn++;
Push(13,&middle[n-2]);
}
else Push(-1,NULL);
}
八、软件的测试方法和测试结果
8.1.程序的输入
程序的输入在in.txt中,while语句为:while(a>b)do d=e/3
8.2.词法分析结果
8.3.语法分析结果
九、研制报告
这次程序设计让我对编译中简单优先分析法有了更加深刻的了解。

一个编译程序的工作过
程一般可以划分为五个阶段:词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。

每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。

经过大量思考完成这个课设使我明白了很多,也了解了自己的不足。

在设计过程中,产生式、优先关系矩阵及算法的描述方面或多或少的有些欠缺,能够通过简单while循环语句的编译;但是,当语句更加复杂时,比如do后面的语句为复合运算式时无法识别,显示语法错误;只能对简单运算进行分析,这些问题都需要进一步改进。

由于我个人的编程水平不高,导致程序的大量冗余,过于复杂。

通过与从网上查找到的程序对比,发现我的程序不够简洁,算法思想仍然有些狭隘,不能更准确更简洁的将我的算法思想写出来。

在这些方面,我仍需努力。

编译原理这门学科对于我来说算是比较难懂的了,对于自己在过去一周的课程设计中,我学到了不少的东西,当然是通过和同学交流讨论所学习到的,虽然不是很精通,但是多少还是了解了一点皮毛。

虽然这样,本次的课程设计还是让我受益匪浅的,因为它极大的提升了我的编程能力和对程序的阅读理解能力,这样也使我对编译原理中的词法分析和语法分析部分比较深刻的了解和熟悉,通过此次课程设计我学到了很多东西,当然自己还有许多不足的地方需要以后进一步的提高,这对我今后不管是学习还是生活都会很有帮助,当然我也深刻的认识到了写代码必须要有比较过硬的理论基础作为铺垫才能编写出好的程序.如果不熟练的掌握它们,很难写出高水平的代码,这样就不能很好的提高自己和锻炼自己。

而这恰恰是我现在所缺乏的一种能力,希望以后很好的提升自己这方面的能力。

我对编译原理这门课程的基本思想又有了新的认识以及更加深刻的学习。

通过对编译中的词法分析程序、简单优先分析法的加深学习,能够写出程序来实现编译,这是对我非常大的考验和锻炼。

而其中,我学到最多的更是对C++程序编写的更深入的了解及学习。

我想在我的整个计算机生活中,编程始终是最重要的,而又最需要更进一步学习的!
十、参考文献
《编译原理》(第二版)清华大学出版社,张素琴吕映芝等编著
《C++程序设计》清华大学出版社,闵联营何克右主编
《数据结构》清华大学出版社,严蔚敏吴伟民编著
十一、开发工具
Windows环境下使用Visual C++ 6.0
本科生课程设计成绩评定表班级:计科1003姓名:刘颖学号:0121010340328
及格(60-69分)、60分以下为不及格
指导教师签名:
20 年月日。

相关文档
最新文档