词法分析程序的构造.docx

上传人:b****4 文档编号:5283508 上传时间:2023-05-08 格式:DOCX 页数:20 大小:164.56KB
下载 相关 举报
词法分析程序的构造.docx_第1页
第1页 / 共20页
词法分析程序的构造.docx_第2页
第2页 / 共20页
词法分析程序的构造.docx_第3页
第3页 / 共20页
词法分析程序的构造.docx_第4页
第4页 / 共20页
词法分析程序的构造.docx_第5页
第5页 / 共20页
词法分析程序的构造.docx_第6页
第6页 / 共20页
词法分析程序的构造.docx_第7页
第7页 / 共20页
词法分析程序的构造.docx_第8页
第8页 / 共20页
词法分析程序的构造.docx_第9页
第9页 / 共20页
词法分析程序的构造.docx_第10页
第10页 / 共20页
词法分析程序的构造.docx_第11页
第11页 / 共20页
词法分析程序的构造.docx_第12页
第12页 / 共20页
词法分析程序的构造.docx_第13页
第13页 / 共20页
词法分析程序的构造.docx_第14页
第14页 / 共20页
词法分析程序的构造.docx_第15页
第15页 / 共20页
词法分析程序的构造.docx_第16页
第16页 / 共20页
词法分析程序的构造.docx_第17页
第17页 / 共20页
词法分析程序的构造.docx_第18页
第18页 / 共20页
词法分析程序的构造.docx_第19页
第19页 / 共20页
词法分析程序的构造.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

词法分析程序的构造.docx

《词法分析程序的构造.docx》由会员分享,可在线阅读,更多相关《词法分析程序的构造.docx(20页珍藏版)》请在冰点文库上搜索。

词法分析程序的构造.docx

词法分析程序的构造

通达学院

专业课程设计II

 

题目:

词法分析程序的构造

 

专业计算机通信

学生姓名

班级学号

指导教师

指导单位计算机学院计算机科学与技术系

日期2012.11.12-2012.11.23

教师评语

 

同学出勤率(满勤、较高、一般,较低),学习态度(端正、较端正、一般、较差),程序设计基础(好、较好、一般、较差),演示程序(已经、没有)达到了基本要求,算法设计(好、较好、一般),界面友好程度(好、较好、一般),答辩过程中回答问题(准确、较准确、错误率较高),撰写报告格式(规范、一般)、内容(丰满、简单)、表述(清晰、一般、不清楚),(圆满、较好、基本)完成了课题任务。

 

教师签名:

年月日

成绩评定

备注

 

词法分析程序的构造

一、课题内容和要求

通过状态转换图构造C或者PASCAL语言子集的词法分析程序。

原理解析:

选取语言,例如选取了C语言,选取其中一个子集,例如包含了部分关键字main、float、if、for等等,特殊符号(、<、=、+等等,特殊定义的标识符变量以及部分常量等,采用《编译原理》词法分析中有穷自动机的思想构建出该语言子集的状态转换图,并编码实现。

基本要求:

(1)将选取的语言子集编写一个简单程序,放在一个文本文件中;

(2)要将一个个单词区分清楚并归类(例如for属于关键字)。

二、需求和思路分析

本课题是用C++语言设计,选取的是C语言子集。

编写对简单语言进行词法分析的词法分析程序。

1、识别子集中的关键字、标识符、常数、运算符和分界符等。

2、对子集中的字符类型进行归类

三、概要设计

(1)状态转换图:

(2)核心代码:

1)定义:

charcbuffer;

char*keyword[14]={"if","else","for","while","do","float","return","break","continue","int","void","main","const","printf"};//关键字

char*border[8]={",",";","{","}","(",")",":

=","."};//分隔符

char*arithmetic[6]={"+","-","*","/","++","--"};//运算符

char*relation[7]={"<","<=","=",">",">=","==","!

="};//关系运算符

char*lableconst[80];//标识符

2)函数调用:

search(charsearchchar[],intwordtype)//查找类型

alphaprocess(charbuffer)//字符处理过程

digitprocess(charbuffer)//数字处理过程

otherprocess(charbuffer)//分隔符、运算符、逻辑运算符等

main()//主函数

3)状态类型:

状态转换图的形式:

■每个状态对应一个带标号的case语句

■转向边对应goto语句

switch(wordtype)

{

case1:

{for(i=0;i<=13;i++)//关键字

{

if(strcmp(keyword[i],searchchar)==0)

return(i+1);

}

return(0);}

case2:

{

for(i=0;i<=7;i++)//分隔符

{

if(strcmp(border[i],searchchar)==0)

return(i+1);

}

return(0);

}

case3:

{

for(i=0;i<=5;i++)//运算符

{

if(strcmp(arithmetic[i],searchchar)==0)

return(i+1);

}

return(0);

}

case4:

{

for(i=0;i<=6;i++)//关系运算符

{

if(strcmp(relation[i],searchchar)==0)

return(i+1);

}

return(0);

}

case5:

{

for(t=40;t<=constnum;t++)//常数

{

if(strcmp(searchchar,lableconst[t])==0)//判断该常数是否已出现过

return(t+1);

}

lableconst[t-1]=(char*)malloc(sizeof(searchchar));//为新的元素分配内存空间

strcpy(lableconst[t-1],searchchar);//为数组赋值lableconst指针数组名

constnum++;//常数个数自加

return(t);

}

case6:

{

for(i=0;i<=lableconstnum;i++)

{

if(strcmp(searchchar,lableconst[i])==0)//判断标识符是否已出现过

return(i+1);

}

lableconst[i-1]=(char*)malloc(sizeof(searchchar));

strcpy(lableconst[i-1],searchchar);

lableconstnum++;//标识符个数自加

return(i);

}

5)单字符判断

if(otypetp=search(othertp,3))//判断该运算符是否是由连续的两个字符组成的

{

cout<<"row:

"<

fp.get(buffer);

gotoout;

}

else//单字符逻辑运算符

{

othertp[1]='\0';

cout<<"row:

"<

gotoout;

}

四、详细设计

实验环境:

visualC++6.0win7系统

源程序代码:

#include

#include

#include

#include

#include

usingnamespacestd;

ifstreamfp("09002801.txt",ios:

:

in);

charcbuffer;

char*keyword[14]={"if","else","for","while","do","float","return","break","continue","int","void"

"main","const","printf"};//关键字

char*border[8]={",",";","{","}","(",")",":

=","."};//分隔符

char*arithmetic[6]={"+","-","*","/","++","--"};//运算符

char*relation[7]={"<","<=","=",">",">=","==","!

="};//关系运算符

char*lableconst[80];//标识符

intconstnum=40;

intlableconstnum=0;//统计常数和标识符数量

introw=1;

intsearch(charsearchchar[],intwordtype)

{

inti=0,t=0;

switch(wordtype)

{

case1:

{for(i=0;i<=13;i++)//关键字

{

if(strcmp(keyword[i],searchchar)==0)

return(i+1);

}

return(0);}

case2:

{

for(i=0;i<=7;i++)//分隔符

{

if(strcmp(border[i],searchchar)==0)

return(i+1);

}

return(0);

}

case3:

{

for(i=0;i<=5;i++)//运算符

{

if(strcmp(arithmetic[i],searchchar)==0)

return(i+1);

}

return(0);

}

case4:

{

for(i=0;i<=6;i++)//关系运算符

{

if(strcmp(relation[i],searchchar)==0)

return(i+1);

}

return(0);

}

case5:

{

for(t=40;t<=constnum;t++)//常数

{

if(strcmp(searchchar,lableconst[t])==0)//判断该常数是否已出现过

return(t+1);

}

lableconst[t-1]=(char*)malloc(sizeof(searchchar));//为新的元素分配内存空间

strcpy(lableconst[t-1],searchchar);//为数组赋值lableconst指针数组名

constnum++;//常数个数自加

return(t);

}

case6:

{

for(i=0;i<=lableconstnum;i++)

{

if(strcmp(searchchar,lableconst[i])==0)//判断标识符是否已出现过

return(i+1);

}

lableconst[i-1]=(char*)malloc(sizeof(searchchar));

strcpy(lableconst[i-1],searchchar);

lableconstnum++;//标识符个数自加

return(i);

}

default:

cout<<"错误!

";

}

}

charalphaprocess(charbuffer)//字符处理过程

{

intatype;

inti=-1;

charalphatp[20];

while((isalpha(buffer))||(isdigit(buffer)))

//这两个函数分别是判字符和判数字函数位于ctype.h中

{

alphatp[++i]=buffer;

fp.get(buffer);

}

alphatp[i+1]='\0';//在末尾添加字符串结束标志

if(atype=search(alphatp,1))

cout<<"row:

"<

else

{

atype=search(alphatp,6);//标识符

cout<<"row:

"<

}

return(buffer);

}

chardigitprocess(charbuffer)//数字处理过程

{

inti=-1;

chardigittp[20];

intdtype;

while((isdigit(buffer)))

{

digittp[++i]=buffer;

fp.get(buffer);

}

digittp[i+1]='\0';

dtype=search(digittp,5);

cout<<"row:

"<

return(buffer);

}

charotherprocess(charbuffer)//分隔符、运算符、逻辑运算符等

{

inti=-1;

charothertp[20];

intotype,otypetp;

othertp[0]=buffer;

othertp[1]='\0';

if(otype=search(othertp,3))

{

fp.get(buffer);

othertp[1]=buffer;

othertp[2]='\0';

if(otypetp=search(othertp,3))//判断该运算符是否是由连续的两个字符组成的

{

cout<<"row:

"<

fp.get(buffer);

gotoout;

}

else//单字符逻辑运算符

{

othertp[1]='\0';

cout<<"row:

"<

gotoout;

}

}

if(otype=search(othertp,4))//关系运算符

{

fp.get(buffer);

othertp[1]=buffer;

othertp[2]='\0';

if(otypetp=search(othertp,4))//判断该关系运算符是否是由连续的两个字符组成的

{

cout<<"row:

"<

fp.get(buffer);

gotoout;

}

else//单字符逻辑运算符

{

othertp[1]='\0';

cout<<"row:

"<

gotoout;

}

}

if(buffer=='!

')//"=="的判断

{

fp.get(buffer);

if(buffer=='=')

//cout<<"!

=(2,2)\n";

fp.get(buffer);

gotoout;

}

else

{

if(otype=search(othertp,2))//分界符

{

cout<<"row:

"<

fp.get(buffer);

gotoout;

}

}

if((buffer!

='\n')&&(buffer!

=''))

cout<<"错误!

非法字符为:

"<<"\t\t\t"<

fp.get(buffer);

out:

return(buffer);

}

voidmain()

{

printf("=========================词法分析器==========================\n");

inti;

for(i=0;i<=50;i++)

{

lableconst[i]="";//用于保存标识符

}

if(!

fp)

cout<<"源文件无法打开,请检查!

"<

else

{

fp.get(cbuffer);

while(!

fp.eof())

{

if(cbuffer=='\n')

{

row++;

fp.get(cbuffer);

}

elseif(isalpha(cbuffer))

{

cbuffer=alphaprocess(cbuffer);

}

elseif(isdigit(cbuffer))

{

cbuffer=digitprocess(cbuffer);

}

else

cbuffer=otherprocess(cbuffer);

}

cout<<"标识符个数是:

"<

i=0;

while(i

{

cout<

}

cout<

cout<<"词法分析结束!

\n";

getchar();

}

}

(3)程序流程图:

五、测试数据及其结果分析

若源程序中没有09002801.txt文档,则会出现如下提示:

若文档中包含09002801.txt文档,文档代码为:

 

运行后结果如下:

 

六、调试过程中的问题

在代码调试过程中,由于代码编写时将主函数main和文件打开的顺序颠倒,导致未写入源文档也会提示词法分析结束,实际上并未进行词法分析过程,应该提示文件打开错,返回检查。

在重新修改之后能够达到理想要求编译运行。

七、专业课程设计总结

通过这次实验,我对编译原理关于词法分析有了进一步的了解,能够把《编译原理》中有穷自动机的理论知识应用于实验中。

通过这次语义分析的实验,我对高级语言的学习有了更深的认识,了解得更透彻我了解了高级语言转化为目标代码或汇编指令的过程。

对今后的学习将起很大的作用,对以后的编程有很大的帮助。

本次实验通过查找书本和网上搜索了解了大致地实验思路,虽然只是完成了一个简单的程序,但在组织程序结构中学到了很多,加深了对编译原理词法编译器的理解,掌握了编译程序的实现方法和技术,巩固了前面所学的相关理论知识。

虽然完成了本次课程设计,但代码还有一些优化的地方,因为可能出现的符号均是事先例举出来,并不能包含所有可能的符号,有一定的局限性,今后会多多锻炼语句的优化方面。

 

参考资料:

[1]王汝传.编译技术原理及其实现方法.成都:

成都科技大学出版社,1998.

[2]吕映芝等编著.编译原理.北京:

清华大学出版社,1998.

[3]陈火旺等编著.程序设计语言编译原理.北京:

国防工业出版社,2000.

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

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

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2