编译原理实验报告2.docx
《编译原理实验报告2.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告2.docx(14页珍藏版)》请在冰豆网上搜索。
![编译原理实验报告2.docx](https://file1.bdocx.com/fileroot1/2023-3/30/c6ecb8ce-65a1-496f-ba4a-ebc1dbebab55/c6ecb8ce-65a1-496f-ba4a-ebc1dbebab551.gif)
编译原理实验报告2
学生学号
实验课成绩
武汉理工大学
学生实验报告书
实验课程名称编译原理
开课学院计算机科学与技术学院
指导老师姓名饶文碧
学生姓名
学生专业班级
—学年第学期
实验课程名称:
编译原理
实验项目名称
单词的词法分析
实验成绩
实验者
专业班级
组别
同组者
实验日期
第一部分:
实验分析与设计(可加页)
一、实验内容描述(问题域描述)
完成对某一种常用高级语言(如Pascal、C语言、PL/0语言)的各类单词进行词法分析,即对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。
实验要求:
(1)选择常用高级程序设计语言(如Pascal、C语言、PL/0语言)的源程序作为词法分析对象。
(2)根据教学要求和学生具体情况,从上列语言之一中选取它的一个适当大小的子集,可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。
其基本要求是:
对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词,并把其转换成属性字输出。
二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)
#include
#include
#include
#include
char*table[7]={"","main","int","if","then","else","return"},TOKEN[20],ch;
//定义关键字
intlookup(char*TOKEN){//关键字匹配函数
intm,i;
for(i=1;i<6;i++){
if((m=strcmp(TOKEN,table[i]))==0)
return(i);
}
return(0);
}
voidout(intc,char*TOKEN){//输出函数
printf("(%d,%s)\n",c,TOKEN);
}
voidscanner(FILE*fp){//扫描函数
charTOKEN[20]={'\0'};
charch;
inti,c;
ch=fgetc(fp);//获取字符指针fp并自动指向下一个字符
if(isalpha(ch)){//判断该字符是否是字母
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isalnum(ch)){//判断该字符是否是字母或数字
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);//回退一个字符
c=lookup(TOKEN);
if(c==0)
out(6,TOKEN);//输出标识符
elseout(c,TOKEN);//输出关键字
}
else
if(isdigit(ch)){//判断是否是数字
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isdigit(ch)){
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
out(7,TOKEN);
}
else
{
TOKEN[0]=ch;
switch(ch){
case'{':
out(17,TOKEN);
break;
case'}':
out(18,TOKEN);
break;
case',':
out(14,TOKEN);
break;
case';':
out(15,TOKEN);
break;
case'<':
ch=fgetc(fp);
TOKEN[1]=ch;
if(ch=='='){
out(9,TOKEN);
}
elseif(ch=='>'){
out(11,TOKEN);
}
else{
fseek(fp,-1,1);
out(8,TOKEN);
}
break;
case'=':
out(10,TOKEN);
break;
case'>':
ch=fgetc(fp);
TOKEN[1]=ch;
if(ch=='=')out(13,TOKEN);
else{
fseek(fp,-1,1);
out(12,TOKEN);
}
break;
default:
printf("error!
\n");
break;
}
}
}
voidmain()
{FILE*fp;
if((fp=fopen("D:
\\ZHT.txt","r"))==NULL){
//读取文件内容,并返回文件指针,该指针指向文件的第一个字符
fprintf(stderr,"erroropening.\n");
exit
(1);
}
do{
ch=fgetc(fp);
if(ch=='#')//文件以#结尾作为扫描结束条件
break;
if(ch=='')//如果是空格,自动跳到下个字符
scanner(fp);
else{
fseek(fp,-1,1);//如果不是空格,则回退一个字符并扫描
scanner(fp);
}
}while(ch!
='#');
return(0);
}
三、主要仪器设备及耗材
VC6.0
第二部分:
实验调试与结果分析(可加页)
一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)
在扫描源程序字符串时一旦识别出关键字、分隔符、标识符、无符号常数中之一即以单词形式各类单词均采用相同的结构,即二元式编码形式输出。
每次调用词法分析程序它均能自动继续扫描下去形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。
二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)
三、实验小结、建议及体会
1、通过本次实验对词法分析的过程有了进一步的了解,并把理论知识应用于试验。
2、在编写程序过程中也遇到了很多困难,不过最终通过老师同学的帮助得到了解决。
为以后编程积累了一些小知识。
3、程序实现功能很有限,以后会继续改进。
实验课程名称:
编译原理
实验项目名称
赋值语句的翻译程序设计
实验成绩
实验者
专业班级
组别
同组者
实验日期
第一部分:
实验分析与设计(可加页)
一、实验内容描述(问题域描述)
对于常用高级语言(如Pascal、C语言)的源程序从左到右进行扫描,把其中赋值语句用所学过的语法分析方法进行语法分析,采用最有代表性的语义分析方法将其转换为中间代码形式表示输出。
实验要求
(1)选择最有代表性的语法分析方法,如算符优先法(或简单优先法)、递归下降分析法、LL分析法和LR分析法之一进行语法分析。
(2)选择对各种常见程序语言都通用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
(3)选择最有代表性的语义分析方法,如语法制导翻译方法进行语义翻译工作。
(4)实习时间为4~6小时。
二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)
voidmain(){
intg,h,i,j,l,p,y,z,count;
inta[10];//状态栈
intni[10];//存放输出逆波兰式的参数
charb[10];//符号栈
charstr[10];//放输入的表达式
charc1;
inttop1,top2,top3,top,topn,m,n;
charx;
charcopy[10];//放Si,ri,看移进还是归约
charcopy1[10];
charvt[6]={'+','*','i','(',')','#'};//存放非终结符
charvn='E';//存放终结符
char*LR[4]={"E->E+E",
"E->E*E",
"E->(E)",
"E->i"
};//存放产生式
};
top1=0;top2=0;top3=0;top=0;topn=0;
a[0]=0;y=a[0];b[0]='#';
count=0;z=0;
cout<<"文法G[E]:
"<cout<<'\t'<<"
(1)E:
:
=E+E"<cout<<'\t'<<"
(2)E:
:
=E*E"<cout<<'\t'<<"(3)E:
:
=(E)|i"<cout<<"文法G[E]合法句子举例:
i+i*i"<cout<<"*************************************************************"<cout<<"请输入符号串:
"<cin>>str;
l=strlen(str);
str[l]='#';
for(i=l+1;i<10;i++){
str[i]=NULL;
}
cout<"<cout<<"-----------------------------------------------------------------"<cout<<"步骤"<<'\t'<<"状态栈"<<'\t'<<'\t'<<"符号栈"<<'\t'<<'\t'<<"输入串"<<'\t'<<'\t'<<"ACTION"<<'\t'<<"GOTO"<do{
y=z;m=0;n=0;//y,z指向状态栈栈顶
g=top;j=0;
x=str[top];
count++;
cout<while(m<=top1)
{//输出状态栈
cout<m=m+1;
}
cout<<'\t'<<'\t';
while(n<=top2)
{//输出符号栈
cout<
n=n+1;
}
cout<<'\t'<<'\t';
str[top-1]='';
cout<cout<<'\t'<<'\t';
while(x!
=vt[j]&&j<=6)j++;//vt[6]={'+','*','i','(',')','#'}存放终结符
if(j==6&&x!
=vt[j]){
cout<cout<"<cout<"<cin>>i;
return;
}
if(action[y][j]==NULL){
cout<cout<"<cout<"<cin>>i;
return;
}
else
//cout<<"y="<strcpy(copy,action[y][j]);
if(copy[0]=='S'){//处理移进
z=copy[1]-'0';
top1=top1+1;
top2=top2+1;
a[top1]=z;//a[10]状态栈
b[top2]=x;//b[10]符号栈x=str[top]
top=top+1;
i=0;
while(copy[i]!
='#'){
cout<i++;
}
cout<}
//cout<<"y="<if(copy[0]=='r'){//处理归约
i=0;
while(copy[i]!
='#'){
cout<i++;
}
h=copy[1]-'0';
ni[topn]=h;
topn=topn+1;
h=h-1;
strcpy(copy1,LR[h]);
//*LR[4]={"E->E+E#","E->E*E#","E->(E)#","E->i#"}存放产生式
//while(copy1[0]!
=vn[0])k++;//vn[1]={'E'}存放非终结符
l=strlen(LR[h]);
top1=top1-l+3;
y=a[top1];
//cout<<"top1="<//y=h-1;
p=goto1[y];
top2=top2-l+4;
top1=top1+1;
a[top1]=p;
b[top2]=copy1[0];
z=p;
cout<<'\t';
cout<
}
}while(action[y][j]!
="acc");
cout<<"acc"<cout<cout<"<cout<<"中间代码的逆波兰式如下:
"<for(i=0;i<10;i++){
if(ni[i]==1)
cout<<"EEE+="<if(ni[i]==2)
cout<<"EEE*="<if(ni[i]==3)
cout<<"EE()="<if(ni[i]==4)
cout<<"iE="<}
cout<"<cin>>i;
}
三、主要仪器设备及耗材
VC6.0
第二部分:
实验调试与结果分析(可加页)
一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)
用LR分析法完成此次文法分析的关键在于构造该文法的分析表,以及如何运用该分析表完成移入和归约的过程,从而完成整个文法的分析。
根据LR分析的基本原理,语法分析程序的主要任务就是:
不断移进输入符号,识别句柄并归约它。
在分析过程中,利用分析栈存放已识别的那部分句型,而句型的其余部分由剩余输入串组成,通过输入串的当前符号和分析栈的栈顶状态查找分析表应采取的动作,对状态栈和符号栈进行相应的操作。
本程序中主要用到的数据结构是栈,实现的相应操作有建立两个空栈
操作数栈OPR,操作符栈OPT,压栈push,出栈pop,取栈顶元素OPRtop等,每个操作用相应的代码实现。
该数据结构主要完成状态栈的操作,对每个状态进行相应的压栈、出栈和取栈顶元素等操作。
二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)
三、实验小结、建议及体会
通过本次实验对赋值语句的分析有了进一步的学习,但是这个程序在状态栈的分析的时还有会出现些意外的问题,还有其他的不分需要完善,以后学习里会进一步改进!