编译原理上机报告1.docx
《编译原理上机报告1.docx》由会员分享,可在线阅读,更多相关《编译原理上机报告1.docx(17页珍藏版)》请在冰点文库上搜索。
![编译原理上机报告1.docx](https://file1.bingdoc.com/fileroot1/2023-5/5/7e13d3e3-635d-4444-90e7-b4667179f4b0/7e13d3e3-635d-4444-90e7-b4667179f4b01.gif)
编译原理上机报告1
重庆科技学院
上机实验报告(程序设计类)
课程名称
编译原理
实验项目
词法分析程序设计
机房名称
I313
上机时间
2018年5月8日
指导老师
王双明
上机成绩
学生姓名
李翼
学号
2015442377
专业班级
计科15
一、上机目的和要求
1.了解词法分析程序的功能、单词符号及输出单词的形式
2.掌握词法分析程序的编写方法
二、上机开发环境
硬件环境:
能流畅运行Windows7、VC++6.0或Eclipse4.5
软件环境:
Windows7、VC++6.0或Eclipse4.5
三、上机内容(老师布置的具体任务)
1.构造词法分析程序:
根据给出的词法规则构造相应的词法分析程序。
词法规则:
关键字(fromfordrawscaleoriginrotstepisTto)、运算符和界符(+-*/^<<=>>====;,()#)、整数(NUM=数字数字*)、空白(空格、制表符(\t)、换行符组成);字母区分大小写,单词最长不超过20个符号。
2.模拟一个DFA的执行。
DFA如下图所示。
四、上机调试中出现的错误信息、错误原因及解决办法
原输入串进行分析的预处理是在注释的嵌套判断上出现了问题,调试了几次才发现是出现注释时计数值本来应该减2结果减了1。
五、上机实验中的收获及心得(不少于50字)
在看到词法分析这个实验时,对于词法分析的这个含义还不是很清楚,对于老师布置这个作业的意义也不清楚。
在看到书上对于词法分析的讲解时,才明白词法分析是整个编译的第一阶段工作,可以说好的词法分析程序会让之后的编译工作变得更轻松。
在参考了一些词法分析程序后,对于词法分析程序中的侧重点也有所了解,特别是对于一段源程序的存储与判断,最后与种别表进行相应的对比,这是简单的词法分析过程。
在自己实现这个代码时,印象最深的是在对于分界符的判断时,在两个以上的一起判断时,就会出现单个分界符的错误输出,在经过一系列的错误尝试后,最后正确输出。
可以说这个词法分析程序结合许多不同的方法,最终得到的简单可行的程序。
要求:
正文采用小四宋体,代码用5号TimesnewRoman字体
附录:
程序流程图
上机调试后的源程序及注解
题目一:
#include
#include
#include
#include
#include
inti,row=0,line=0;
chara[1000];//程序
intnumber[1000][100];//常数表
charmark[100][5];//标识符表
//词法分析
intwordanalysis()
{
if((a[i]>='A'&&a[i]<='Z')||(a[i]>='a'&&a[i]<='z'))//分析标识符和保留字
{
charword[10];
charpro[100][100]={"FROM","FOR","DRAW","SCALE","ORIGIN","ROT","STEP","IS","TO",};//保留字表
intn=0;
word[n++]=a[i++];
//若字符为A~Z或0~9,则继续读取
while((a[i]>='A'&&a[i]<='Z')||(a[i]>='0'&&a[i]<='9')||(a[i]>='a'&&a[i]<='z'))
{
word[n++]=a[i++];
}
word[n]='\0';
i--;
//判断该标识符是否为保留字
for(n=0;n<100;n++)
{
if(strcmp(word,pro[n])==0)
{
printf("%s\t(%d,-)保留字\n",pro[n],n+1);
return3;
}
}
//判断标识符长度是否超出规定
if(strlen(word)>20)
{
printf("%s\tERROR\n",word);
return0;
}
//判断该标识符是否存在标识符表中
intm=0;
if(line!
=0)
{
intq=0;
while(q{
if(strcmp(word,mark[q++])==0)
{
printf("%s\t(12,%d)标识符\n",word,q);
return3;
}
}
}
//将该标识符保存到标识符表中
strcpy(mark[line],word);
printf("%s\t(12,%d)标识符\n",word,line+1);
line++;
return3;
}
elseif(a[i]>='0'&&a[i]<='9')//分析常数
{
charx[100];
intn=0,sum;
x[n++]=a[i++];
//判断字符是否是0~9
while(a[i]>='0'&&a[i]<='9')
{
x[n++]=a[i++];
}
x[n]='\0';
i--;
intnum=atoi(x);//将字符串转换成int型
//判断该常数是否存在于常数表中
if(row!
=0)
{
inty;
for(y=0;y<1000;y++)
{
intw=number[y][0];
sum=0;
intd;
for(d=1;d<=number[y][0];d++)
{
w=w-1;
sum=sum+number[y][d]*pow(2,w);
}
if(num==sum)
{
printf("%d\t(13,%d)\n",num,y+1);
return3;
}
}
}
intz=num,c=num;
intm=0;
do//计算是几位二进制数
{
z=z/2;
m++;
}while(z!
=0);
for(n=m;n>0;n--)//将二进制保存于常数表中
{
number[row][n]=c%2;
c=c/2;
}
number[row][0]=m;
intline=row;
printf("%d\t(13,%d)\n",num,line+1);
row++;
return3;
}
else//分析符号
switch(a[i])
{
case'':
case'\n':
return-1;
case'#':
return0;
case'=':
printf("=\t(14,-)\n");return3;
case'<':
i++;
if(a[i]=='=')
{
printf("<=\t(16,-)\n");
return3;
}
elseif(a[i]=='>')
{
printf("<>\t(19,-)\n");
return3;
}
else
{
i--;
printf("<\t(15,-)\n");
return3;
}
case'>':
i++;
if(a[i]=='=')
{
printf(">=\t(18,-)\n");
return3;
}
else
{
i--;
printf(">\t(17,-)\n");
return3;
}
case'+':
printf("+\t(20,-)\n");return3;
case'-':
printf("-\t(21,-)\n");return3;
case'*':
printf("*\t(22,-)\n");return3;
case'/':
i++;
if(a[i]!
='/'){
i--;
printf("/\t(23,-)\n");return3;
}
else{
while
(1){
if(a[i++]=='\n')
return-1;
}
printf("//\t(35,-)\n");return3;
}
case':
':
printf(":
\t(24,-)\n");return3;
case';':
printf(";\t(25,-)\n");return3;
case'(':
printf("(\t(26,-)\n");return3;
case')':
printf(")\t(27,-)\n");return3;
case'{':
printf("{\t(28,-)\n");return3;
case'}':
printf("}\t(29,-)\n");return3;
case'[':
printf("[\t(30,-)\n");return3;
case']':
printf("]\t(31,-)\n");return3;
case'|':
printf("|\t(32,-)\n");return3;
case'"':
printf("\"\t(33,-)\n");return3;
case',':
printf(",\t(34,-)\n");return3;
case'\'':
printf("'\t(36,-)\n");return3;//单引号
case'&':
i++;
if(a[i]!
='&'){
i--;
printf("&\t(37,-)\n");return3;
}
else{
printf("&&\t(38,-)\n");return3;
}
case'\\':
printf("\\\t(39,-)\n");return3;
}
}
intmain()
{
intl=0;
intm;
i=0;
FILE*fp;
fp=fopen("E:
\\code.txt","r");
if(fp==NULL)
{
printf("Can'topenfile!
\n");
exit(0);
}
while(!
feof(fp))
{
a[l++]=fgetc(fp);
}
a[l]='#';
do
{
m=wordanalysis();
switch(m)
{
case-1:
i++;break;
case0:
i++;break;
case3:
i++;break;
}
}while(m!
=0);
_getch();
return0;
}
题目二:
#include
usingnamespacestd;
intmain()
{
chars[1000];
chara[1000];
intk=0,i;
charc;
cout<<"请输入字符串s:
"<while((c=cin.get())!
='\n')//用数组s装载以01组成的字符串
{
s[k]=c;
k++;
}
s[k]='\0';
if(s[0]!
='1')//当第一个不为1时,不能被识别
{
cout<<"不能被M识别"<}
else
{
intflag=0;
c='A';
intlen=strlen(s);
a[0]='S';
k=1;
while(k{
a[k]=c;
if(c=='A')
{
switch(s[k])
{
case'0':
c='B';k++;break;
case'1':
c='C';k++;break;
}
continue;
}
elseif(c=='B')
{
if(s[k]!
='1')
{
flag=1;
break;
}
else
{
c='A';
k++;
continue;
}
}
elseif(c=='C')
{
switch(s[k])
{
case'0':
c='B';k++;break;
case'1':
c='C';k++;break;
}
continue;
}
}
a[len]=c;
if(a[len]=='B'||a[len]=='C')
{
if(flag==0)
{
for(i=0;i{
cout<";
}
cout<}
else
{
cout<<"不能被M识别"<cout<<"ssss----1"<}
}
else
{
cout<<"不能被M识别"<cout<<"ssss----2"<}
}
return0;
}
四、程序运行结果截图及还存在的问题
题目一
题目二