编译原理实验报告
实验名称:_____编写词法分析程序_______
实验类型:_______设计类__________________
指导教师:________蒋勇________________
专业班级:________软件1002班_________
姓 名:________ 邓椿嵋______________
学 号:____ 20101575________________
实验地点:_______东6A319_____________
实验成绩:____________________________
日期: 2012年 4月 21 日
实验一 编写词法分析程序
一、实验目的
通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步
理解自动机理论;掌握文法转换成自动机的技术及有穷自动机实现的方法;会确定词法分析
器的输出形式及标识符与关键字的区分方法;加深对课堂教学的理解,提高词法分析方法的
实践能力。
二、实验设计
1、 根据TEST语言的词法规则,写出正则文法或者正则表达式
2、 将正则文法或者正则表达式转换为NFA
3、 将NFA确定化并化简
4、 根据化简后的DFA画出流程图
5、 确定单词分类、单词输出方案
6、 编写词法分析程序
1、程序设计语言词法规则⇒正则文法⇒ FA;
或:词法规则⇒正则表达式⇒ FA;
2、NFA确定化⇒ DFA;
3、DFA最小化;
4、确定单词符号输出形式;
5、化简后的DFA+单词符号输出形式⇒构造词法分析程序。
三、实验过程
1.根据老师发的那个实验要求自己写好了代码。
2.再通过老师讲了一些后修改了代码,主要是之前的测试数据没有弄好,缺少对注释不
匹配问题的考虑。
3.再根据老师的提示修改好了代码。
四、实验结果
测试数据为:{
int a=0;
for
/*fgrtg*/
}
/*fgthy
现象:提示第二个注释那个地方匹配不成功!
通过词法分析过后的那个文件里的内容为:
五、讨论与分析
1、你的编写词法分析程序满足最长匹配原则吗?如果满足请给出你的实现方案。如果
不满足请给出改进方案。
2、你的单词分类考虑了哪些因素?
TEST语言的单词符号如下:
标识符:字母打头,后接任意字母或数字。
保留字:标识符的子集,包括:if,else,for,while,do, int,write,read。
无符号整数:由数字组成。
分界符:+、-、*、/、(、)、;、<、>、{、}、!
双分界符:>=、<=、!=、==
注释符:/* */
3、构建词法分析程序一般过程是怎样的?
1、根据词法规则写出正则文法;
2、将正则文法转换成状态图;
3、将状态图转换成流程图;
4、根据流程图写出词法分析程序。
六、附录:#include
#include
#include
#define keywordSum 8
char * keyword[keywordSum]={"if","else","for","while","do","int","read","write"};
char singleword[50]="+-*;,:";
char doubleword[10]="><=!(){}";
extern char Scanin[300],Scanout[300];
extern FILE * fin,*fout;
int TESTscan()
{
char ch,token[40];
int es=0,j,n;
printf("请输入源程序文件名(包括路径):");
scanf("%s",Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s",Scanout);
if((fin=fopen(Scanin,"r"))==NULL)
{
printf("\n打开词法分析输入文件出错!\n");
return(1);
}
if((fout=fopen(Scanout,"w"))==NULL)
{
printf("\n创建词法分析输入文件出错!\n");
return(2);
}
ch=getc(fin);
while (ch!=EOF)
{
while (ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);
if(isalpha(ch))
{
token[0]=ch;j=1;
ch=getc(fin);
while (isalnum(ch))
{
token[j++]=ch;
ch=getc(fin);
}
token[j]='\0';
n=0;
while((n
fprintf(fout,"%s\t%s\n","ID",token);
else
fprintf(fout,"%s\t%s\n",token,token);
}else if (isdigit(ch))
{
token[0]=ch;j=1;
ch=getc(fin);
while(isdigit(ch))
{
token[j++]=ch;
ch=getc(fin);
}
token[j]='\0';
fprintf(fout,"%s\t%s\n","NUM",token);
}else if(strchr(singleword,ch)>0)
{
token[0]=ch;token[1]='\0';
ch=getc(fin);
fprintf(fout,"%s\t%s\n",token,token);
}else if(strchr(doubleword,ch)>0)
{
token[0]=ch;
ch=getc(fin);
if(ch=='=')
{
token[1]=ch;token[2]='\0';
ch=getc(fin);
}
else
token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}else if (ch == '/') //如果是/,继续读下一个符号
{
char ch1;
ch1 = getc(fin);
if (ch1 == '*') //如果是*,则开始处理
注释
{
ch1 = getc(fin);
while(ch1 != EOF)
{
ch = ch1;
ch1 = getc(fin);
//删除注释
if (ch == '*' && ch1 == '/')
{
break;
}
else
{
if(ch1 == EOF)
{
fprintf(fout,"%s\n","匹配不成功!");
break;
}
}
}
//知道遇到注释结束符*/
ch = getc(fin);
}
else //不是*则处理单分
界符
{
token[0] = '/';
token[1] = '\0';
fprintf(fout,"%s\t%s\n",token,token);
}
}
else //错误处理
{
token[0] = '/';
token[1] = '\0';
ch = getc(fin);
es = 3;
fprintf(fout,"%s\t%s\n","ERROR!",token);
}
ch = getc(fin);
}
fclose(fin); //关闭输入输出文件
fclose(fout);
return(es); //返回主程序
}
extern int TESTscan();
char Scanin[300],Scanout[300];
FILE * fin,* fout;
void main(){
int es=0;
es=TESTscan();
if(es>0) printf("词法分析有错,编译停止!");
else printf("词法分析成功!\n");
}
七、实验者自评
感觉这次的实验做的不是很好,希望下次会比这次好。