编译原理词法分析器实验报告最终版.docx

上传人:b****8 文档编号:27719520 上传时间:2023-07-04 格式:DOCX 页数:18 大小:42.71KB
下载 相关 举报
编译原理词法分析器实验报告最终版.docx_第1页
第1页 / 共18页
编译原理词法分析器实验报告最终版.docx_第2页
第2页 / 共18页
编译原理词法分析器实验报告最终版.docx_第3页
第3页 / 共18页
编译原理词法分析器实验报告最终版.docx_第4页
第4页 / 共18页
编译原理词法分析器实验报告最终版.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

编译原理词法分析器实验报告最终版.docx

《编译原理词法分析器实验报告最终版.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器实验报告最终版.docx(18页珍藏版)》请在冰豆网上搜索。

编译原理词法分析器实验报告最终版.docx

编译原理词法分析器实验报告最终版

学院(系)名称:

计算机工程系

姓名

学号

专业

班级

实验项目

实验一:

词法分析

课程名称

编译原理

课程代码

0310243

实验时间

2013年4月28日第1、2节

2013年5月7日第1、2节

实验地点

第一教学楼1508

批改意见

成绩

 

教师签字:

实验内容:

实现标准C语言词法分析器

实验目的:

1.掌握程序设计语言词法分析的设计方法;

2.掌握DFA的设计与使用方法;

3.掌握正规式到有限自动机的构造方法;

实验要求:

1.单词种别编码要求

基本字、运算符、界符:

一符一种;

标识符:

统一为一种;

常量:

按类型编码;

2.词法分析工作过程中建立符号表、常量表,并以文本文件形式输出;

3.词法分析的最后结果以文本文件形式输出;

4.完成对所设计词法分析器的功能测试,并给出测试数据和实验结果;

5.为增加程序可读性,请在程序中进行适当注释说明;

6.整理上机步骤,总结经验和体会;

7.认真完成并按时提交实验报告。

实验步骤:

1.基本思想:

从源程序中依次读入字符并解析,与关键字、运算符、结束符进行比较,得出其中的关键字,并将它存入到数组中去。

2.程序源代码:

#include

#include

#include

#defineMaxSize117//关键字的个数

#defineMaxSize220//运算符的个数

#defineMaxSize34//结束符的个数

//数据结构

structTNode

{

charvalue[20];//存放标识符的值

intnumber;//存放标识符的种别码

chardescription[20];//描述

}KeyWords[MaxSize1],Operation[MaxSize2],EndOperation[MaxSize3];

//存放关键字的数组

char*WordsBuff[MaxSize1]={"const","long","float","double","void","main","if","else","then","break","int","char","include","for","while","printf","scanf"};

//存放运算符的数组

char*OperationBuff[MaxSize2]={"+","-","*","/","+=","-=","*=","++","--","<","<=",">",">=","<>","=","(",")","#","{","}"};

charEndOperationBuff[MaxSize3]={'',';','\n','\t'};

//存放词法分析程序输出的结果

TNodeTable1[500];

TNodeVariable[100];//标识符表

TNodeConst[100];

//关键字数组初始化

voidinputKeyWords(char*buff[],intsize)

{

//关键字编码从1-size

for(inti=0;i

{

strcpy(KeyWords[i].value,buff[i]);

KeyWords[i].number=i+1;

strcpy(KeyWords[i].description,"关键字");

}

}

//运算符数组初始化

voidinputOperation(char*buff[],intsize)

{

//运算符编码从50-(50+size)

for(inti=0;i

{

strcpy(Operation[i].value,buff[i]);

Operation[i].number=i+50;

strcpy(Operation[i].description,"运算符");

}

}

//结束符数组初始化

voidinputEndOperation(charbuff[],intsize)

{

//结束符编码从100-(100+size);

for(inti=0;i

{

EndOperation[i].value[0]=buff[i];

EndOperation[i].value[1]='\0';

EndOperation[i].number=i+100;

strcpy(EndOperation[i].description,"结束符");

}

}

//输出数据结构数组中的信息

voidoutputInfo(TNodea[],intsize)

{

for(inti=0;i

{

printf("(%d",a[i].number);

printf("\t");

printf("%s)",a[i].value);

printf("\t");

printf(a[i].description);

printf("\n");

}

}

voidoutInfoToFile(TNodea[],intsize,FILE*out)

{

//将词法分析程序的结果输出到文件中去

for(inti=0;i

{

fprintf(out,"(%d",a[i].number);

fprintf(out,"\t");

fprintf(out,"%s)",a[i].value);

fprintf(out,"\t");

fprintf(out,a[i].description);

fprintf(out,"\n");

}

}

//从文件中读取一个字符

//返回文件中读取的字符

chargetChar(FILE*fp)

{

charch=fgetc(fp);

returnch;

}

//判读是否是运算符

intisOperation(chara[])

{

//返回i表示是运算符在运算符数组中的位置

//返回-1表示不是运算符

intresult;

for(inti=0;i

{

result=strcmp(a,Operation[i].value);

if(result==0)

{

returni;

break;

}

}

return-1;

}

//判读是否是关键字

intisKeyWords(chara[])

{

//返回i表示在关键字表中的位置

//返回-1表示不是关键字

intresult;

for(inti=0;i

{

result=strcmp(a,KeyWords[i].value);

if(result==0)

{

returni;

break;

}

}

return-1;

}

//判读是否是结束符

intisEndOperation(chara)

{

//返回i表示是结束符在结束符表中的位置

//返回-1表示不是结束符

for(inti=0;i

{

if(a==EndOperation[i].value[0])

{

returni;

break;

}

}

return-1;

}

//判读是否是字符

intisChar(chara)

{

//返回1表示是字符

//返回0表示不是字符

if(a>='a'&&a<='z')

return1;

elseif(a>'A'&&a<='Z')

return1;

else

return0;

}

//判读是否是数字

intisDigit(chara)

{

//返回1表示是数字

//返回0表示不是数字

if(a>='0'&&a<='9')

return1;

else

return0;

}

intcount=0;//记录结果表中的关键字及运算符等表项个数,用于返回

intcount1=0;//记录标识符的表项个数

intcount2=0;//记录常量的表项的个数

//从屏幕上面获得字符并解析,返回在结果表中的表项

intstart1(FILE*in)

{

charbuff[20];//用于保存单词的缓冲区

charnextchar[2];

chartemp[20];//用于保存变量或常量的类型数组

inti=0;//缓冲区指针

inta;//比较的结果指针

charop[3];//用于保存第一个运算符

op[2]='\0';

nextchar[0]=fgetc(in);

nextchar[1]='\0';

while(nextchar[0]!

=EOF)

{

if(isChar(nextchar[0]))

{

buff[i]=nextchar[0];i++;

nextchar[0]=fgetc(in);

}

elseif(isDigit(nextchar[0]))

{

buff[i]=nextchar[0];i++;

nextchar[0]=fgetc(in);

}

elseif(nextchar[0]=='\r'||nextchar[0]=='\n')

{

buff[i]='\0';

a=isKeyWords(buff);

if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);

Table1[count].number=KeyWords[a].number;

strcpy(Table1[count].description,KeyWords[a].description);

count++;//计数器加一

i=0;//清空缓冲区

}

elseif(i>0)

{

if(isChar(buff[0]))

{

//是标识符

strcpy(Variable[count1].value,buff);

Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");

count1++;//计数器加一

i=0;//清空缓冲区

}

elseif(isDigit(buff[0]))

{

//是常量

strcpy(Const[count2].value,buff);

Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;//计数器加一

i=0;//清空缓冲区

}

}

else

{

//缓冲区为空!

}

//处理回车符与换行符

nextchar[0]=fgetc(in);

}

elseif(isEndOperation(nextchar[0])!

=-1)

{

buff[i]='\0';

a=isKeyWords(buff);

if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);

Table1[count].number=KeyWords[a].number;

strcpy(Table1[count].description,KeyWords[a].description);

strcpy(temp,KeyWords[a].value);

count++;//计数器加一

i=0;//清空缓冲区

}

elseif(i>0)

{

if(isChar(buff[0]))

{

//是标识符

strcpy(Variable[count1].value,buff);

Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");

count1++;//计数器加一

i=0;//清空缓冲区

}

elseif(isDigit(buff[0]))

{

//是常量

strcpy(Const[count2].value,buff);

Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;//计数器加一

i=0;//清空缓冲区

}

}

else

{

//缓冲区为空!

}

nextchar[0]=fgetc(in);

}

elseif((a=isOperation(nextchar))!

=-1)

{

//首先输出缓冲区中的数据

buff[i]='\0';

a=isKeyWords(buff);

if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);

Table1[count].number=KeyWords[a].number;

strcpy(Table1[count].description,KeyWords[a].description);

count++;//计数器加一

i=0;//清空缓冲区

}

elseif(i>0)

{

if(isChar(buff[0]))

{

//是标识符

strcpy(Variable[count1].value,buff);

Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");

count1++;//计数器加一

i=0;//清空缓冲区

}

elseif(isDigit(buff[0]))

{

//是常量

strcpy(Const[count2].value,buff);

Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;//计数器加一

i=0;//清空缓冲区

}

}

else

{

//缓冲区为空!

}

//处理运算符

op[0]=nextchar[0];

nextchar[0]=fgetc(in);

if(nextchar[0]!

='@')

{

if(isOperation(nextchar)!

=-1)

{

op[1]=nextchar[0];

if((a=isOperation(op))!

=-1)

{

//输出双目运算符

strcpy(Table1[count].value,Operation[a].value);

Table1[count].number=Operation[a].number;

strcpy(Table1[count].description,Operation[a].description);

count++;//计数器加一

//读取下一个字符

nextchar[0]=fgetc(in);

}

else

{

//错误的双目运算符

strcpy(Table1[count].value,op);

Table1[count].number=-1;

strcpy(Table1[count].description,"未定义的运算符");

count++;//计数器加一

//读取下一个字符

nextchar[0]=fgetc(in);

}

}

else

{

//输出一元运算符

op[1]='\0';

a=isOperation(op);

strcpy(Table1[count].value,Operation[a].value);

Table1[count].number=Operation[a].number;

strcpy(Table1[count].description,Operation[a].description);

count++;//计数器加一

}

}

}

}

returncount;

}

voidmain()

{

inputKeyWords(WordsBuff,MaxSize1);

inputOperation(OperationBuff,MaxSize2);

inputEndOperation(EndOperationBuff,MaxSize3);

FILE*in,*out;

boolFlag=true;

while(Flag)

{

printf("源文件的位置:

C:

\\input.txt\n");

if((in=fopen("C:

\\input.txt","r"))==NULL)

{

printf("读取源文件失败!

\n");

exit(0);

}

if((out=fopen("C:

\\out.txt","w"))==NULL)

{

printf("打开文件失败!

\n");

exit(0);

}

intMaxSize=start1(in);

printf("关键字及运算符\n");

fprintf(out,"关键字及运算符\n");

outputInfo(Table1,MaxSize);

outInfoToFile(Table1,MaxSize,out);

printf("标识符表:

\n");

fprintf(out,"标识符表:

\n");

outputInfo(Variable,count1);

outInfoToFile(Variable,count1,out);

printf("常量表:

\n");

fprintf(out,"常量表:

\n");

outputInfo(Const,count2);

outInfoToFile(Const,count2,out);

Flag=false;

fclose(in);

fclose(out);

}

}

3.测试用例:

inta=3;

doubleb=4;

intc;

if(a>b)

c=a;

else

c=b;

4.测试结果:

5.心得体会:

通过这次实验,我对编译原理这门专业必修课有了进一步的深层次了解,把理论知识应用于实验中,实验过程中对于转义字符,结束符、欠缺了考虑,在多次的调试和改进中最终完善了程序,而在调试过程中学习的知识得到了完善和补充,对词法分析器的理解更进一步。

也让我重新熟悉了C++语言的相关内容,加深了对C++语言知识的深化和用途的理解。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1