编译原理while语句的翻译.docx
《编译原理while语句的翻译.docx》由会员分享,可在线阅读,更多相关《编译原理while语句的翻译.docx(22页珍藏版)》请在冰豆网上搜索。
编译原理while语句的翻译
学号:
0121010340328
课程设计
题目
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=(VN,VT,P,S)
VN={S,C,E,F,}
VT={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->whileCdoE=F
C->(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、语法分析方法的描述及分析表设计
3.1语法分析方法的描述
简单优先分析法是按照文法符号(终极符和非终极符)的优先关系确定句柄的。
首先根据已知文法求出相应优先关系,并将文法的产生式保存,设置符号栈S,步骤如下:
(1)将输入符号串a1a2…an#依次逐个存入符号栈S中,直到遇到栈顶符号ai的优先性>下一个待输入符号aj为止。
(2)栈顶当前符号ai为句柄尾,由此向左在栈中找句柄的头符号ak,即找到ak-1(3)由句柄ak...ai在文法的产生式中查找右部为ak…ai的产生式,若找到则用相应左部代替句柄,若找不到则为出错,这时可断定输入串不是该文法的句子。
(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,t1)
2.(*,b,d,t2)
3.(+,t1,t2,t3)
4.(=,t3,-,a)
五、编译系统的概要设计
1通过程序,在in.txt文本中输入while语句。
对文本进行扫描,通过词法分析函数对输入的while语句进行词法分析,结果以二元式形式保存在out.txt中。
2将已算好的优先关系矩阵以二维数组的形式放至程序中。
对已进行词法分析的while语句进行语法分析,其中包括进栈函数和归约,当满足归约条件时由进栈函数调用规约函数,其中包含对错误语句的报错处理。
将分析过程输出到yufafenxi.txt中
3通过四元式输出函数将运算表达式表示为四元式的形式,输出到yufafenxi.txt中。
6、详细的算法描述(流程图)
6.1.主函数伪代码
voidmain()
{
Precedence();//调用优先关系函数求解
Lexical();//调用词法分析程序
Syntax();//调用语法分析程序
}
6.2.词法分析总控程序
6.3.语法分析程序
7、源程序
7.1.优先关系函数
voidPrecedence()
{
inti,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.词法分析函数
voidLexical()
{
char*pch,str[100],*pstr,*pt;
charch[200]={'\0'};
intlength;
inti=0,u=-1;
while(!
infile.eof())//判断文件是否读完?
{
u++;
ch[u]=infile.get();
}
pch=ch;
length=strlen(ch);
pch=ch;
printf("词法分析结果:
\n");
outfc<<"词法分析结果:
"<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"<Buff[i].p=0;
Buff[i++].adr=NULL;
}
elseif(strcmp(str,"do")==0)
{
printf("关键字do\n");
outfc<<"关键字do"<Buff[i].p=1;
Buff[i++].adr=NULL;
}
else
{
printf("标识符");
outfc<<"标识符";
printf(str);
printf("\n");
outfc<Buff[i].p=10;
Buff[i++].adr=pt;
}
}
elseif(isdigit(*pch))
{pt=pch;
printf("数字");
outfc<<"数字";
while(isdigit(*pch))
{printf("%c",*pch);
outfc<<*pch;
pch++;
}
outfc<printf("");
outfc<<"";
Buff[i].p=11;
Buff[i++].adr=pt;
}
if(*pch=='=')
{if(*(pch+1)=='=')
{printf("等于==\n");
outfc<<"等于=="<pch++;
pch++;
Buff[i].p=4;
Buff[i++].adr=NULL;
}
else
{printf("赋值符=\n");
outfc<<"赋值符="<pch++;
Buff[i].p=5;
Buff[i++].adr=NULL;
}
}
elseif(*pch=='*')
{printf("乘号*\n");
outfc<<"乘号*"<pch++;
Buff[i].p=7;
Buff[i++].adr=NULL;
}
elseif(*pch=='+')
{printf("加号+\n");
outfc<<"加号+"<pch++;
Buff[i].p=6;
Buff[i++].adr=NULL;
}
elseif(*pch=='-')
{t=1;
printf("减号-\n");
outfc<<"减号-"<pch++;
Buff[i].p=6;
Buff[i++].adr=NULL;
}
elseif(*pch=='/')
{t=1;
printf("除号/\n");
outfc<<"除号/"<pch++;
Buff[i].p=7;
Buff[i++].adr=NULL;
}
elseif(*pch=='<')
{printf("小于号<\n");
outfc<<"小于号<"<pch++;
Buff[i].p=3;
Buff[i++].adr=NULL;
}
elseif(*pch=='>')
{printf("大于号>\n");
outfc<<"大于号>"<pch++;
Buff[i].p=2;
Buff[i++].adr=NULL;
}
elseif(*pch=='\0')
{printf("\n词法分析正确结束!
");
pch++;
Buff[i].p=16;
Buff[i++].adr=NULL;
}
elsepch++;
}
7.3.语法分析函数
boolSyntax()
{intip=0;
printf("\n\n\n语法分析过程为:
\n");
InitStack();
while(true)
{if(GetValue().p==12&&Buff[ip].p==16&&Top==2)
{printf("语法分析正确结束!
\n");returntrue;}
elseif(GetValue().p==-1)
{printf("语法错误!
\n");returnfalse;}
else
{switch(GetPrecedence(GetValue().p,Buff[ip].p))
{caseLT:
caseEQ:
Push(Buff[ip].p,Buff[ip].adr);ip++;PrintStack();break;
caseGT:
Reduce();PrintStack();break;
default:
printf("语法错误!
\n");returnfalse;
}
}
}
}
7.4.归约函数
voidReduce()
{structureoutstring[10];
intlen;
intc;
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);
}
elseif(len==1&&outstring[1].p==14)Push(15,outstring[1].adr);
elseif(len==3&&outstring[1].p==14&&outstring[3].p==14)
{middle[n++]='#';
middle[n++]=Tn++;
Push(15,&middle[n-2]);
}
elseif(len==3&&outstring[1].p==9)Push(14,outstring[1].adr);
elseif(len==4&&outstring[1].p==12)Push(12,NULL);
elseif(len==3&&outstring[1].p==15&&outstring[3].p==10)Push(12,NULL);
elseif(len>=3&&outstring[len].p==15)
{middle[n++]='#';
middle[n++]=Tn++;
Push(13,&middle[n-2]);
}
elsePush(-1,NULL);
}
八、软件的测试方法和测试结果
8.1.程序的输入
程序的输入在in.txt中,while语句为:
while(a>b)dod=e/3
8.2.词法分析结果
8.3.语法分析结果
九、研制报告
这次程序设计让我对编译中简单优先分析法有了更加深刻的了解。
一个编译程序的工作过程一般可以划分为五个阶段:
词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。
每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。
经过大量思考完成这个课设使我明白了很多,也了解了自己的不足。
在设计过程中,产生式、优先关系矩阵及算法的描述方面或多或少的有些欠缺,能够通过简单while循环语句的编译;但是,当语句更加复杂时,比如do后面的语句为复合运算式时无法识别,显示语法错误;只能对简单运算进行分析,这些问题都需要进一步改进。
由于我个人的编程水平不高,导致程序的大量冗余,过于复杂。
通过与从网上查找到的程序对比,发现我的程序不够简洁,算法思想仍然有些狭隘,不能更准确更简洁的将我的算法思想写出来。
在这些方面,我仍需努力。
编译原理这门学科对于我来说算是比较难懂的了,对于自己在过去一周的课程设计中,我学到了不少的东西,当然是通过和同学交流讨论所学习到的,虽然不是很精通,但是多少还是了解了