编译原理设计c语言的词法分析器Word文件下载.docx
《编译原理设计c语言的词法分析器Word文件下载.docx》由会员分享,可在线阅读,更多相关《编译原理设计c语言的词法分析器Word文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
{"
"
}"
5■5?
5I5J
单词二元组(单词分类号、单词自身值)
单词
分类号
标识符
1
整数或浮点型
2
保留字
3
运算符
4
界符
5
词法分析器的设计
算法设计
概要设计
否则回退字符,在对应
从文件中逐个读取字符,只要这五大类的状态序列则继续读取,类别进行查找,输出单元二次组至另一文件夹。
常数?
状态图设计
打开txt文件读取C语言代码
!
扫
描
开始
是否读取到相应字符
Y
记录标号
界符?
结束
输入输出设计
输入:
通过文件指针从文件中一个一个读取字符
输出:
输出单词二元组至文件。
格式为(种别码,值)
主要函数
voidGetchar(FILE*fp)//读入一个字符
voidGetBC(FILE*fp)//读入一个非空字符
voidcontacat()//连接字符
intletter()//判断是否为字母
intdigit()//判断是否为字母
voidretract(FILE*fp,char*c)//回退
intreserve(char**k)//处理保留字
intsysmbol(identifier*id)//处理标识符,查找符号表并存放位置若没有则添加
intconstant(constnumber*con)//存入常数表,并返回它在常数表中的位置
voidTofile(intnum,intval,identifier*id,constnumber*con,FILE*fw)//
写到文件
voidWordAnalyze(char**k,char*c,char**CODE,identifier*id,constnumber
*con,FILE*fp,FILE*fw)//词法分析函数
四、结果测试
文件输入
intmain()
inta=1,b=3;
if(a>
1)
b=b-2;
输出结果:
哀件(E輪辑®
搐式gi童看也帮助凹
(3,int)
(1,main)
dej)
(20s[)
(l.a)
(2,1)
(2,3)
(3,if)
aa)
(2.1)
(l.b)
(l,b)
(2,2)
(21,})
结论:
程序输出结果与期望输出结果相符
四、收获与感想
通过我本次课程设计掌握了词法分析器设计的基本方法与相关知识。
词法分析的关键
是明确各类字符的状态转换过程。
同时辅助标识符、常量结构体与保留字表用于查找返回值。
同时我也对分析问题解决问题有了更深入全面的认识与理解。
面对一个大的问题,需
要理清解决的步骤再将其分解成小的模块逐个解决最后再串联在一起,问题就会变得更容易,思路也会更加清晰。
五、实验代码
#include<
iostream>
usingnamespacestd;
#defineLENGTH10
charch;
char*CODE[]={"
identifier"
"
constant"
keyword"
/**/,"
+"
-"
*"
/"
<
="
>
=="
("
)"
};
人J~JJ>
JJ—JJ—>
—J>
char*k[]={"
for"
while"
do"
else"
if"
static"
int"
sizeof"
break"
continue"
//保留字
chartoken[16];
//存放处理后的字符串
//标识符结构体
typedefstruct
{
char*I[256];
intlen;
}identifier;
intcont[300];
}constnumber;
//读入一个字符
voidGetchar(FILE*fp)
if((ch=getc(fp))==EOF)
exit
(1);
}
//读入一个非空字符
voidGetBC(FILE*fp)
while(ch=='
'
||ch=='
\n'
||ch==9)
Getchar(fp);
//连接字符
voidcontacat()
char*cht=&
(ch);
strcat_s(token,cht);
//判断是否为字母
intletter()
returnisalpha(ch);
intdigit()
returnisdigit(ch);
//回退
voidretract(FILE*fp,char*c)
inta=ftell(fp);
fseek(fp,0,SEEK_SET);
fprintf_s(fp,"
%c"
ch);
ch='
fseek(fp,a,SEEK_SET);
//处理保留字
intreserve(char**k)
inti;
for(i=0;
i<
LENGTH;
i++)
if(strcmp(token,k[i])==0)
return(i+1);
return0;
//处理标识符,查找符号表并存放位置若没有则添加
intsysmbol(identifier*id)
id->
len;
if(strcmp(token,id->
I[i])==0)returni+1;
if(id->
len>
256)
cout<
error"
id->
I[id->
len]=token;
len++;
returnid->
//数字字符串转化为整数
intstr_to_num()
inti=0;
intk=token[i]-'
0'
for(i=1;
token[i]!
='
\0'
k=k*10+token[i]-'
returnk;
//存入常数表,并返回它在常数表中的位置
intconstant(constnumber*con)
con->
cont[con->
len]=str_to_num();
con->
returncon->
//写到文件
voidTofile(intnum,intval,identifier*id,constnumber*con,FILE*fw){
intnum_=num;
fprintf_s(fw,"
(%d,"
num);
if(num>
=4)
fprintf_s(fw,"
%s"
CODE[num-1]);
if(num<
4)
switch(num)
case1:
id->
I[val-1]);
break;
case2:
%d"
con->
cont[val-1]);
case3:
k[val-1]);
)\n"
);
voiderror(FILE*fw)
(Error,"
<
ch<
endl;
(Error,%c\n)"
ch);
//词法分析函数
FILE
voidWordAnalyze(char**k,char*c,char**CODE,identifier*id,constnumber*con,FILE*fp,*fw)
intnum,val;
strcpy_s(token,"
//初始化为空字符串
GetBC(fp);
if((ch>
A'
ch<
Z'
)||(ch>
a'
z'
))//分析标识符和保留字
//若字符为A~Z或0~9,则继续读取
while(letter()||digit())
contacat();
retract(fp,c);
num=reserve(k);
if(num!
=0)
val=sysmbol(id);
Tofile(1,val,id,con,fw);
elseif(digit())//处理常数
while(digit())
retract(fp,c);
val=constant(con);
Tofile(2,val,id,con,fw);
else//分析符号
switch(ch)
case'
'
if(ch=='
='
)
Tofile(8,0,id,con,fw);
Tofile(11,0,id,con,fw);
else
Tofile(10,0,id,con,fw);
Tofile(13,0,id,con,fw);
Tofile(12,0,id,con,fw);
error(fw);
+'
Tofile(4,0,id,con,fw);
break;
-'
Tofile(5,0,id,con,fw);
*'
Tofile(6,0,id,con,fw);
/'
Tofile(7,0,id,con,fw);
('
Tofile(15,0,id,con,fw);
)'
'
Tofile(17,0,id,con,fw);
Tofile(18,0,id,con,fw);
Tofile(19,0,id,con,fw);
{'
Tofile(20,0,id,con,fw);
}'
Tofile(21,0,id,con,fw);
default:
charc[100]="
FILE*fp,*fw;
errno_terr;
err=fopen_s(&
fp,c,"
r"
if(err!
printf("
Thefilewasnotopened\n"
exit(0);
errno_terr1;
err1=fopen_s(&
fw,"
"
w"
if(err1!
identifier*id=(identifier*)malloc(sizeof(identifier));
len=0;
constnumber*con=(constnumber*)malloc(sizeof(constnumber));
WordAnalyze(k,c,CODE,id,con,fp,fw);
while
(1)
if(feof(fp))break;
fclose(fw);
fclose(fp);