C语言词法分析器构造实验报告Word文档格式.docx
《C语言词法分析器构造实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《C语言词法分析器构造实验报告Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
IsLetter和IsDigit:
布尔函数过程,分别判断ch中的字符是否为字母和数字;
Reserve:
整型函数过程,对strtoken中的字符串查找关键字表,若是关键字则返回编码,否则返回-1;
Retract:
将搜索指示器回调一个字符位置,将ch置为空白字符;
reflesh:
刷新,把strtoken数组置为空;
prearrange1:
将注释部分置为空格;
prearrange2:
预处理空格,去掉多余空格;
analysis:
词法分析;
main:
主函数。
4、状态转换图:
字母或数字
字母非字母或数字
数字数字
非数字
字符a
字符a
字符b
‘=’
字符c
字符a包括:
=,&
|,+,--
字符b包括:
--,<
>
|,*
字符c包括:
,:
(,),{,},[,],!
#,%,”,/,*,+,--,>
<
.
三、源代码如下:
#include<
stdio.h>
string.h>
charset[1000],str[500],strtoken[20];
charsign[50][10],constant[50][10];
charch;
intsr,to,id=0,st=0;
typedefstructkeytable/*放置关键字*/
{
charname[20];
intkind;
}KEYTABLE;
KEYTABLEkeyword[]={/*设置关键字*/
{"
main"
0},
int"
1},
float"
2},
char"
3},
if"
4},
else"
5},
for"
6},
while"
7},
do"
8},
switch"
9},
case"
10},
break"
11},
default"
12},
};
openfile()/*打开文件*/
FILE*fp;
chara,filename[10];
intn=0;
printf("
Inputthefilename:
"
);
gets(filename);
if((fp=fopen(filename,"
r"
))==NULL)
{
cannotopenfile.\n"
exit(0);
}
else
while(!
feof(fp))/*文件不结束,则循环*/
a=getc(fp);
/*getc函数带回一个字符,赋给a*/
set[n]=a;
/*文件的每一个字符都放入set[]数组中*/
n++;
fclose(fp);
/*关闭文件*/
set[n-1]='
\0'
;
\n\n-------------------SourceCode--------------------------\n\n"
puts(set);
\n--------------------------------------------------------\n"
}
reflesh()/*清空strtoken数组*/
to=0;
/*全局变量to是strtoken的指示器*/
strcpy(strtoken,"
"
prearrange1()/*预处理程序1*/
inti,a,b,n=0;
do
if(set[n]=='
/'
&
&
set[n+1]=='
*'
)
a=n;
/*记录第一个注释符的位置*/
(set[n]=='
))
b=n+1;
/*记录第二个注释符的位置*/
for(i=a;
i<
=b;
i++)/**/
set[i]='
'
/*把注释的内容换成空格,等待第二步预处理*/
}while(set[n]!
='
prearrange2()/*预处理程序2*/
intj=0;
sr=0;
/*全局变量sr是str[]的指示器*/
if(set[j]=='
||set[j]=='
\n'
while(set[j]=='
)/*扫描到有连续的空格或换行符*/
j++;
str[sr]='
/*用一个空格代替扫描到的连续空格和换行符放入str[]*/
sr++;
str[sr]=set[j];
/*若当前字符不为空格或换行符就直接放入str[]*/
}while(set[j]!
charGetChar()/*把字符读入全局变量ch中,指示器sr前移*/
ch=str[sr];
return(str[sr-1]);
voidGetBC()/*开始读入符号,直至第一个不为空格*/
while(ch=='
ch=GetChar();
Concat()/*把ch中的字符放入strtoken[]*/
strtoken[to]=ch;
to++;
strtoken[to]='
intIsLetter()/*判断是否为字母*/
if((ch>
=65&
ch<
=90)||(ch>
=97&
=122))
return
(1);
elsereturn(0);
intIsDigit()/*判断是否为数字*/
if(ch>
=48&
=57)
intReserve()/*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
inti,k=0;
for(i=0;
=20;
i++)
if(strcmp(strtoken,keyword[i].name)==0)
{k=1;
return(keyword[i].kind);
if(k!
=1)
return(-1);
voidRetract()/*指示器sr回调一个字符位置,把ch置为空*/
sr--;
ch='
intInsertId()
inti,k;
id;
k=strcmp(strtoken,sign[i]);
if(k==0)
return(i);
strcpy(sign[id],strtoken);
/*插入标识符*/
id++;
return(id-1);
intInsertConst()
st;
k=strcmp(strtoken,constant[i]);
if(k==0)
strcpy(constant[st],strtoken);
/*插入常数*/
st++;
return(st-1);
voidanalysis()
intvalue;
reflesh();
/*清空strtoken数组*/
prearrange1();
/*预处理,使注释内容换成单个空格,放回set[]中*/
prearrange2();
/*预处理,使set[]中连续的空格置换成单个空格,并把set[]的内容放到str[]中*/
GetChar();
GetBC();
/*读取第一个字符*/
while(ch!
)/*当不等于结束符,继续执行*/
if(IsLetter())
while(IsLetter()||IsDigit())/*若第一个是字符,继续读取,直到出现空格*/
Concat();
Retract();
/*指示器sr回调一个字符位置,把ch置为空*/
value=Reserve();
/*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
if(value==-1)/*如果返回值是-1,那就是变量,把它输出*/
InsertId();
\n%s"
strtoken);
getch();
}
else/*否则就是关键字,也输出*/
{
elseif(IsDigit())
while(IsDigit())/*否则,若第一个是数字,继续读取,知道出现空格*/
InsertConst();
switch(ch)/*否则,若是下面的符号,就直接把它输出*/
case'
'
:
'
('
)'
{'
}'
['
]'
!
#'
%'
%s'
break;
default:
if(ch=='
||ch=='
|'
+'
-'
)/*如果是这些符号,继续读取下一个*/
/*判断是否为==,&
||,++,--的情况*/
if(ch==strtoken[0])
elseif(ch=='
<
>
)
/*判断是否为+=,-=,<
=,>
=,!
=,*=的情况*/
if(ch=='
Error!
main()
{
clrscr();
openfile();
analysis();
printf(“analysisisover!
”);
五、测试结果:
1、分析文件test1.c中的程序:
test.c
*****************OriginalCode************************
/*HELLO.C--Hello,world*/
#include"
stdio.h"
conio.h"
Hello,world\n"
*****************************************************
include
stdio
.'
h
conio
main
printf
Hello
worldError!
n
getch
Analysisisover!
六、实验总结:
这个程序主要参考书上关于词法分析器的设计。
在设计过程中仍有遇到很多困难,但经请教同学后,好多问题都并不是想象中的困难。
尽管如此,分析考虑还不全面,例如没有创建符号表和常数表。
这些情况将在在语法和语义分析时进行完善。