编译原理实验一.docx

上传人:b****5 文档编号:7431776 上传时间:2023-01-23 格式:DOCX 页数:32 大小:173.76KB
下载 相关 举报
编译原理实验一.docx_第1页
第1页 / 共32页
编译原理实验一.docx_第2页
第2页 / 共32页
编译原理实验一.docx_第3页
第3页 / 共32页
编译原理实验一.docx_第4页
第4页 / 共32页
编译原理实验一.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

编译原理实验一.docx

《编译原理实验一.docx》由会员分享,可在线阅读,更多相关《编译原理实验一.docx(32页珍藏版)》请在冰豆网上搜索。

编译原理实验一.docx

编译原理实验一

实验内容:

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

实验目的:

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

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

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

实验要求:

1.单词种别编码要求

基本字(关键字)、运算符、界符:

一符一种;

标识符(变量名):

统一为一种;

常量():

按类型编码;

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

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

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

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

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

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

二、设计方案:

这个词法分析器分析的主要关键字有:

main,int,float,char,if,else,for,while,do,switch,case,break;default……。

选择要分析的c文件,首先对其去掉注释和与空格处理,再根据字符的不同类型分析。

1、全局数据结构:

*key[]:

关键字表

全局文件指针*fr,*fw,*temp1,*temp2用于文件的读写。

2、以层次图模块的组成及调用关系

3、主要函数的设计要求(功能、参数、返回值):

isKey:

判断ch中的字符是否为关键字;

isLer和isNum:

布尔函数过程,分别判断ch中的字符是否为字母和数字;

isBoudany():

布尔函数过程,分别判断ch组成的字符否为边界符号;

check:

词法分析;

clock:

时间函数,计算程序运行所需的时间

main:

主函数。

4、状态转换图:

字母或数字

字母非字母或数字

数字数字

非数字

字符a

字符a

字符b

‘=’

字符c

 

字符a包括:

=,&,|,+,--

字符b包括:

--,<,>,|,*

字符c包括:

,:

(,),{,},[,],!

#,%,”,/,*,+,--,>,<,.

#include

#include

#include

#include

#include

 

FILE*fr,*fw,*temp1,*temp2;

char*key0[]={"main","printf","scanf","else","if","auto","double",

"int","struct","break","long","switch","case","enum","register","typedef",

"char","extern","return","union","const","float","short","unsigned","continue","for",

"signed","void","default","goto","sizeof","volatile","do","while","static"};

/*关键字表*/

char*key1[]={"\"","\\","(",")","[","]","{","}",",",";","'"};

/*边界符表*/

intisLet(charc)//判断是否是字母

{

if(c>='a'&&c<='z'||c>='A'&&c<='Z')

return1;

else

return0;

}

intisNum(charc)//判断是否是数字

{

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

return1;

else

return0;

}

intisKey(char*word)

{

intm,i;

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

{

if((m=strcmp(word,key0[i]))==0)

{

if(i==0)

return2;

else

return1;

}

}

return0;

}

intisBoudany(charc)

{

if(c=='\\')

return2;

else

if(c=='('||c==')'||c=='{'||c=='}'||c=='['||c==']'||c==','||c==';'||c=='\''||c=='\"'||c=='\"')

return1;

else

return0;

}

voidcheck(FILE*fr)

{

charword[30];

while(!

feof(fr))

{

memset(word,0,sizeof(word));

charch,temp;

ch=fgetc(fr);//获取字符,指针fr并自动指向下一个字符

inti,c;

if(ch=='#')//预处理

{

//temp=fgetc(fr);

while(ch!

='>')

ch=fgetc(fr);

ch=fgetc(fr);

fprintf(fw,"*****************************************跳过头文件和文件宏定义\n");

}

else

if(ch=='/')//跳过注释/**/类型

{

ch=fgetc(fr);

if(ch=='/')//跳过注释//类型

{

while(ch!

='\n')

ch=fgetc(fr);

fprintf(fw,"*********************************************************跳过注释\n");

}

else

if(ch=='*')

{

ch=fgetc(fr);

temp=fgetc(fr);

do

{

ch=fgetc(fr);

temp=fgetc(fr);

}

while(ch!

='*'||temp!

='/');

fprintf(fw,"******************************************************跳过注释\n");

ch=fgetc(fr);

}

}

else

if(isLet(ch))

{

word[0]=ch;

ch=fgetc(fr);

i=1;

while(isNum(ch)||isLet(ch))//判断该字符是否是字母或数字

{

word[i]=ch;

i++;

ch=fgetc(fr);

}

word[i]='\0';//'\0'代表字符结束(空格)

fseek(fr,-1,1);

c=isKey(word);//判断是否是关键字

if(c==0)//不是关键字

{

fprintf(temp1,"%s",word);

fprintf(fw,"字符%s是:

标识符,种别编码为:

%d\n",word,2);

}

else

{

if(ch!

='"')//判断是否是定义的字符

{

if(c==2)

fprintf(fw,"字符%s是:

***************************************************主函数,种别编码为:

%d\n",word,0);//主函数

else

fprintf(fw,"字符%s是:

关键字,种别编码为:

%d\n",word,1);//关键字

}

else

{

fprintf(fw,"字符%s是:

定义的字符常量,种别编码为:

%d\n\n",word,32);

}

}

}

else//开始判断的字符不是字母

if(isNum(ch))

{//判断是否是数字

word[0]=ch;

ch=fgetc(fr);

i=1;

while(isNum(ch))

{

word[i]=ch;

i++;

ch=fgetc(fr);

}

word[i]='\0';

fseek(fr,-1,1);//回退

fprintf(fw,"字符%s是:

常量,种别编码为:

%d\n",word,3);

}

else

{

c=isBoudany(ch);

//开始判断的字符不是字母也不是数字

//边界符

if(c)

{

if(c==2)//判断是否是转义字符

{

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

word[2]='\0';

fprintf(fw,"字符%s是:

转义字符,种别编码为:

%d\n",word,4);

}

else

if(c==1)

{

fprintf(fw,"字符%c是:

界符,种别编码为:

%d\n",ch,5);

fprintf(temp2,"%c",ch);

}

}

else

switch(ch)

{

case'+':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='='){

word[2]='\0';

fprintf(fw,"字符%s是:

运算符,种别编码为:

%d\n",word,6);//运算符"+="

}

else

if(ch=='+')

{

word[2]='\0';

fprintf(fw,"字符%s是运算符,种别编码为:

%d\n",word,7);//判断结果为"++"

}

else{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是运算符,种别编码为:

%d\n",ch,8);//判断结果为"+"

}

break;

case'-':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='='){

word[2]='\0';

fprintf(fw,"字符%s是:

运算符,种别编码为:

%d\n",word,9);}

else

if(ch=='-'){

word[2]='\0';

fprintf(fw,"字符%s是运算符,种别编码为:

%d\n",word,10);//判断结果为"--"

}

else{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是运算符,种别编码为:

%d\n",ch,11);//判断结果为"-"

}

break;

case'*':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch!

='=')

{

if(isNum(ch))

 

{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c:

是运算符,种别编码为:

%d\n",ch,12);//判断结果为"*"

}

else

{//判断是否是指针

i=2;

ch=fgetc(fr);

while(isLet(ch))

{

word[i]=ch;

ch=fgetc(fr);

i++;

}

fprintf(fw,"字符%s:

是指针定义运算符,种别编码为:

%d\n",word,13);

}

}

else

{

word[2]='\0';

fprintf(fw,"字符%s:

是运算符,种别编码为:

%d\n",word,14);//判断结果为"*="

}

break;

case'/':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch!

='=')

{

if(isNum(ch))

{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c:

是运算符,种别编码为:

%d\n",ch,15);//判断结果为"/"

}

}

else{

word[2]='\0';

fprintf(fw,"字符%s:

是运算符,,种别编码为:

%d\n",word,16);//判断结果为"/="

}

break;

case'!

':

case'?

':

case':

':

case'.':

case'=':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch!

='='){

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c:

是运算符,种别编码为:

%d\n",ch,17);

}

else{word[2]='\0';

fprintf(fw,"字符%s:

是运算符,种别编码为:

%d\n",word,18);

}

break;

case'|':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='|'){

word[2]='\0';

fprintf(fw,"字符%c是运算符,种别编码为:

%d\n",ch,19);//判断结果为运算符"||"

}

else{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是运算符,种别编码为:

%d\n",ch,20);//判断结果为"|"

}

break;

case'%':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='=')

{

word[2]='\0';

fprintf(fw,"字符%s是运算符,种别编码为:

%d\n",word,21);

}

else

if(isLet(ch))

{

word[2]='\0';

fprintf(fw,"字符%s是输出类型标识符,种别编码为:

%d\n",word,22);

}

else

{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是取余运算符,种别编码为:

%d\n",ch,23);

}

break;

case'&':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='&'){

word[2]='\0';

fprintf(fw,"字符%s是:

运算符,种别编码为:

%d\n",word,24);//判断结果为运算符"&&"

}

else{

fseek(fr,-2,1);

ch=getc(fr);

fprintf(fw,"字符%c是:

运算符,种别编码为:

%d\n",ch,25);//判断结果为"&"

}

break;

case'<':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='='){

word[2]='\0';

fprintf(fw,"字符%s是:

运算符,种别编码为:

%d\n",word,26);//判断结果为运算符"<="

}

else

if(ch=='<'){

word[2]='\0';

fprintf(fw,"字符%s是:

运算符,种别编码为:

%d\n",word,27);//判断结果为运算符"<<"

}

else

{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是:

运算符,种别编码为:

%d\n",ch,28);//判断结果为"<"

}

break;

case'>':

word[0]=ch;

ch=fgetc(fr);

word[1]=ch;

if(ch=='='){

word[2]='\0';

fprintf(fw,"字符%s是运算符,种别编码为:

%d\n",word,29);

}

else

if(ch=='>'){

word[2]='\0';

fprintf(fw,"字符%s是运算符,种别编码为:

%d\n",word,30);

}

else{

fseek(fr,-2,1);

ch=fgetc(fr);

fprintf(fw,"字符%c是运算符,种别编码为:

%d\n",ch,31);

}

break;

default:

break;

}

}

 

fprintf(fw,"\n");

}

}

intmain()

{

clock_tstart,end;

charcr;

charstr_in[25],str_out[25],str_out1[25],str_out2[25];

doubleduration;

start=clock();

printf("请输入文件的读取路径(包含文件的后缀名):

\n");

scanf("%s",str_in);

fr=fopen(str_in,"r");

while(fr==NULL)

{

printf("文件路径输入错误!

请重新输入:

\n");

scanf("%s",str_in);

fr=fopen(str_in,"r");

}

printf("文件读入成功!

内容显示如下:

\n");

printf("**************************************************\n");

cr=fgetc(fr);

while(cr!

=EOF){

putchar(cr);

cr=fgetc(fr);

}

printf("\n");

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

当前位置:首页 > 农林牧渔 > 林学

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

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