完整版C语言词法分析器实验报告汇总.docx
- 文档编号:26062380
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:32
- 大小:525.85KB
完整版C语言词法分析器实验报告汇总.docx
《完整版C语言词法分析器实验报告汇总.docx》由会员分享,可在线阅读,更多相关《完整版C语言词法分析器实验报告汇总.docx(32页珍藏版)》请在冰豆网上搜索。
完整版C语言词法分析器实验报告汇总
计算机科学与工程系
编译原理课程设计实验报告
姓名:
__******_学号_*******_年级专业及班级_08计算机科学与技术成绩
实验名称
词法分析程序设计与实现
完成日期
2011/4/12指导教师*******
实验目的:
能够米用C编程语言实现简单的词法分析程序;设计、编制并调试一个词法分析程序,加深对词法分析原理的理解
实验要求:
1.对单词的构词规则有明确的定义;
2.编与的分析程序能够正确识别源程序中的单词付号;
3.识别出的单词以<单词符号,种别码>的形式保存在符号表中(链表);
4•词法分析中源程序的输入以.c格式,分析后的符号表,将二元组保存在.txt文件中。
实验内容:
选择高级语言(C语言),编制它的词法分析程序。
词法分析程序的实现可以采用任何一种编程工具实验原理:
1、算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号;
2、其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
实验分析:
(1)关键字:
ifelsewhiledocaseintbreak等所有的关键字都是小写。
(2)运算符和界符:
=+-*/<<=<>>>==;()等
(3)其他单词是标识符(ID)和整型常数(SUM,通过以下正规式定义:
ID=_|letter(letter|digit)*
NUM=digitdigit*
(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM运算符、界符和关键字,词法分析阶段通常被忽略。
(5)注释被忽略
(6)各种单词符号对应的种别码(如下):
单词符号
种别码
单词符号
种别码
auto
1
double
2
int
3
struct
4
break
5
else
6
long
7
switch
8
case
9
enum
10
register
11
typedef
12
char
13
extern
14
return
15
union
16
const
17
float
18
short
19
unsigned
20
continue
21
for
22
signed
23
void
24
default
25
goto
26
sizeof
27
volatile
28
do
29
while
30
static
31
if
32
\a
33
\b
34
\f
35
\n
36
\t
37
\v
38
\\
39
\?
40
41
42
\0
43
\ddd
44
\xhh
45
数字
46
标识符
47
#
48
(
49
)
50
[
51
]
52
{
53
}
54
C
55
*
56
:
57
58
%
59
A
60
+
61
?
62
=
63
1
64
&
65
!
66
<
67
>
68
>=
69
==
70
>>
71
!
=
72
<<
73
&&
74
<=
75
II
76
++
77
?
=
78
-
79
--
80
->
81
a
82
%A(A可为d's'c)
83
84
85
/
86
87
88
89
90
91
其他类别
99
扫描数字:
是f判别为自减符
Ch是否为‘-'
判别为”->”
预读ch
预读ch
判别为负号
回退3
Ch为数字或‘
预读ch
扫描引号:
0
扫描单词:
实验步骤:
1、准备:
用TC、VC++等开发工具;
2、对本实验的任务进行分析,确定实现功能的函数;
3、写好程序,仔细修改函数;
4、上机操作:
输入源程序,修改、调试,运行。
5、写好试验报告。
/*******************************
实验调试过程及测试结果
代^码******************************/
#include
FILE*fp,*fp1;
inthanjsq=1;〃行计数器,
保存行号
intguanjz(charch1[]);〃
关键字和标识符判断
charch,infile[15],outfile[15];〃
定义输入和输出文件名
printf("*****************Entertheinfilename*****************
scanf("%s",infile);//输入需要扫描的文件名
printf(
Entertheoutfilename******************\n");
scanf("%s",outfile);//输入需要另存为的文件名
if((fp=fopen(infile,"r"))==NULL)//
{
printf("cannotopenfile\n");exit(0);
}
if((fp1=fopen(outfile,"w"))==NULL)//
打开需要扫描的文件
打开需要存入的文件
{
printf("cannotopenfile'n");exit(O);
}
printf("\n********************************************************
printf("*******************************************************
printf("\n********************************************************
printf("*******************************************************
fprintf(fp1,"*******************************************************
**\n");
fprintf(fp1,while(!
feof(fp))
{
ch=fgetc(fp);
if(ch==1O)hanjsq++;
扫描头文件单词及保留字
*********************
if(isalpha(ch)||ch=='_')〃如果第一个字符为字母或下划线则判断为标识符
{
inti=0;
charch1[30];〃
假疋母个标识付取长为
ch1[i++]=ch;〃
将ch保存到ch1[0]中并使i自加1
while(!
feof(fp))
{
ch=fgetc(fp);
if(ch==1O)hanjsq++;〃如果ch为换行符,则行计数器自加1
if(isalpha(ch)||isdigit(ch)||ch=='')
{//如果ch为字母、数字或下划线就把ch放到ch1[i]中并使i自加1
ch1[i++]=ch;
}
if(ch=='.')〃如果ch为小数点则判断是否为头文件
{
if(ch==10)hanjsq++;
chi[i++]='.';
chi[i++]='h';
ch1[i]='\0';〃把结束标志放到chi[i]中作为单词结束标志
break;
{
fseek(fp,-1,1);//fp回退1
ch1[i]='\0';〃把结束标志放到ch1[i]中作为单词结束标志
出chi
printf("line%d:
%s%d\n",hanjsq,ch1,guanjz(ch1));〃以字符串形式输
fprintf(fp1,"line%d:
%s%d\n",hanjsq,ch1,guanjz(ch1));
break;
}
}if(!
isalpha(ch)&&!
isdigit(ch)&&ch!
='_'&&ch!
='.')
{//如果ch不为字母、数字、下划线和点时判断其为标识符
ch1[i]='\0';printf("line%d:
fprintf(fp1,"line%d:
%s
break;
/************************
j扫描数*************************/
if(isdigit(ch)||ch=='-')〃
如果ch为数字或'-'
if(isdigit(ch))//
如果ch为数字
printf("line%d:
%c",hanjsq,ch);
fprintf(fp1,"line%d:
%c",hanjsq,ch);
while(!
feof(fp))
if(isdigit(ch)||ch=='.')
printf("%c",ch);
fprintf(fp1,"%c",ch);
else//否则视为数字结束
46\n");
46\n");
printf(”
fprintf(fp1,"
ch='O:
〃置ch为0,以免影响下面误判并顺利退出扫描数字
break;
ch=fgetc(fp);〃预读一位
if(ch=='-')〃如果ch还是为'-'则判断为自减符'--'
{
printf("line%d:
fprintf(fp1,"line%d:
}
}
if(isdigit(ch))〃如果ch为数字则可能为减号或负号
{
fseek(fp,-3,1);〃回退3为判断
ch=fgetc(fp);
if(isdigit(ch))〃如果ch为数字则判断'-'为减号
ch=fgetc(fp);
printf("line%d:
%c
fprintf(fp1,"line%d:
}
else//否则判断'-'为负号
{
ch=fgetc(fp);
printf("line%d:
fprintf(fp1,"line%d:
while(!
feof(fp))
{
ch=fgetc(fp);〃
79\n",hanjsq,ch);
%c79\n",hanjsq,ch);
if(isdigit(ch)||ch=='.'){
printf("%c",ch);
fprintf(fp1,"%c",ch);
}
else//否则视为数字结束
{
printf(”
46\n");
fprintf(fp1,"
46\n");
fseek(fp,-1,1);//
回退1
break;
}
}
}
if(ch=='/')〃如果ch为'/'则可能为注释
{
ch=fgetc(fp);〃读下一个字符
if(ch==10)hanjsq++;
if(ch=='/')〃如果该字符也为'/'则判断为注释一行
{
while(fgetc(fp)!
=10);
if(ch==10)hanjsq++;〃直到遇到换行符出现才认为注释结束
}
if(ch=='*')〃如果该字符为'*'则判断为注释多行
{//直到出现’*/'才认为注释结束
while(!
feof(fp)){
ch=fgetc(fp);if(ch==10)hanjsq++;if(ch=='*')〃出现'*'
{//且接着出现'/'if((ch=fgetc(fp))=='/')
break;
break;
inti=0;
while(!
feof(fp))
{//先整体输出引号内所有字符并定为第99类
ch=fgetc(fp);
i++;〃用于积累回退长度
if(ch==10)hanjsq++;
if(ch!
=””)
{
if(ch!
=32)
{
printf("%c",ch);
fprintf(fp1,"%c",ch);
}
}
elsebreak;
99\n");
99\n");
回退到引号开始
}
printf(”
fprintf(fp1,"fseek(fp,-i,1);//for(;i>0;i--)
{
ch=fgetc(fp);
if(ch==92)//如果ch为'\'则可能为转义字符
{
charch5[13]={"abfntv\\?
'\"0"};//转义字符集
ch=fgetc(fp);//预读一位
for(intk=0;k<12;k++)
{//如果为转义字符则输出
if(ch==ch5[k])
{
%d\n",hanjsq,ch,k+33);
printf(”line%d:
\\%c
fprintf(fp1,"line%d:
\\%c
}
}
if(ch=='d'&&isdigit(fgetc(fp))&&isdigit(fgetc(fp)))〃
{
fseek(fp,-2,1);
printf("line%d:
%c%c
fprintf(fp1,"line%d:
%c%c
}
if(ch=='x'&&isdigit(fgetc(fp))&&isdigit(fgetc(fp)))//
{
fseek(fp,-2,1);
printf("line%d:
%c%c
fprintf(fp1,"line%d:
%c%c
}
}
if(ch=='%')〃如果为'%'则可能为%s%c%d
%d\n",hanjsq,ch,k+33);
任意字符转换为三位八进制
44\n",hanjsq,fgetc(fp),fgetc(fp));
44\n“,hanjsq,fgetc(fp),fgetc(fp));
任意字符转换为二位十六进制
45\n",hanjsq,fgetc(fp),fgetc(fp));
45\n",hanjsq,fgetc(fp),fgetc(fp));
{
ch=fgetc(fp);
charbfh[4]={"dcs"};
for(i=0;i<3;i++)
{
if(bfh[i]==ch)
{
printf("line%d:
%%%c
fprintf(fp1,"line%d:
%%%c
83\n",hanjsq,ch);
83\n",hanjsq,ch);
}
}
}
}
/*********************
描其他符^号********************/
if(!
isdigit(ch)&&!
isalpha(ch)&&ch!
='_'&&ch!
=””&&ch!
='/')
定义部分单符号集
charch2[14]={"#()[]{}'*:
~%A"};〃
for(inti=0;i<13;i++){//判断单个符号
if(ch==ch2[i])
for(intj=0;j<8;j++){//判断双符号
if(ch==ch3[j])
ch=fgetc(fp);//预读一位
//if(ch==10)hanjsq++;
if(ch==ch4[j])
连起来为一个双符号
{//且ch与ch4第j个匹配,则表示ch3[j]与ch4[j]
printf("line%d:
%c%c
%d\n",hanjsq,ch3[j],ch4[j],i+69);
fprintf(fp1,"line%d:
%c%c
%d\n",hanjsq,ch3[j],ch4[j],i+69);
判断'<<'符
if(ch=='<'&&ch3[j]=='<')〃
printf("line%d:
fprintf(fp1,"line%d:
}
if(ch=='>'&&ch3[j]=='>')〃
{
printf("line%d:
fprintf(fp1,"line%d:
}
else//否则表示ch3[j]
{
printf("line%d:
fprintf(fp1,"line%d:
fseek(fp,-1,1);
}
}
}
}
<<
<<
判断'>>'符
>>
>>
为单符号,不是双符号的
%c
%c
77\n",hanjsq);
77\n",hanjsq);
78\n",hanjsq);
78\n",hanjsq);
部分
%d\n",hanjsq,ch3[j],j+61);
%d\n",hanjsq,ch3[j],j+61)
******************************************************************************************
printf(
**\n");
printf("*》词法分析结束
printf("*》分析结果保存在文件%$中
printf("*》欢迎下次使用,谢谢!
《*\n");
《*\n",outfile);
《*\n");
printf(
**\n");
fprintf(fp1,
**\n");
fprintf(fp1,"*》
词法分析结束
《*\n");
fprintf(fp1,"*》
欢迎下次使用,谢谢!
《*\n");
**\n");
intguanjz(charch1[])〃关键字和标识符判断
{
charch2[32][9]={"auto","double","int","struct","break","else","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","if"};〃
for(inti=0;i<32;i++)
{//逐个比对如果为关键字则返回类别i+1
if(!
strcmp(ch1,ch2[i]))returni+1;
return47;//否则返回一般标识符类
竝船悅Q)動勒卜
1Inc
1:
u
4S
line
12
iniclude
4?
1ine
1*
<
b'f
line
1=
.Ili
B3
lino
is
>
hV
lliw
2s
U
4R
lima
2s
inaludo
47
aIm
2?
<
67
line
2s
atAlib.h
linfi
2:
>
GS
line
3;
void
line
main
<17
line
3:
<
J.inc
3=
>
ba
line
3:
S3
1inc
Ss
riLE
47
1Irte
5:
lime
S;
s
4?
test
・曹■:
m曹Entei'thsoutfileri之盯日****^***-¥******<^^cfFmqi,txt
at■wawatitat■atituifatitatutguitat■•acnunitar・atariMiMatmtmat:
mat■uat心开史舱行词法分析<*
讪:
"Ik1:
血1:
line1:
Ike]:
Hue2:
Iine2:
line2:
lines:
!
k2:
line3:
line3:
line5;
line3:
lineS:
lint5:
J5qe5:
inclut
stdinh
CaiL
FILE
丰
ft
:
■
:
•
S3
=;
阴
i7
占
fl
:
b豪溥■ar河*"百■苜筒nwi{耳鼻pnt尸广『卄戸1nt-_iInFinp卄可・w耳黑図耳溥■ar・鼻*ee戸ftrst«t具t
■if耳材imcirHirjtKjnfifK^nrBl*Th&outflie寺暮打補整并*需斗弭書!
**祥略再整番
cffXQ-tXt
atiruifat■uukmat■・atmenuat■um~w;matwmataa・:
■■■!
imatatnwuat 心开给进行词法分析3 =! KXKMXMMXXMJ4KMMXKMXKMXMMXMMMMMMXKMX liineline丄±n&linelino1irielinnllnftlineliri@Urielineline丄inclinelinnlineline ninclude stdllo.li includo stdlib.lh uoid Piaui PILE 48 4? G7 83 bS 1? 67 68244? 印呼 bU 53 4? -1? Line 2C 4 Gi Limo 2^ 鼻 llna 26 cnimt 47 Line 2& > Line 27 9JlE& E Line 27 if 3Z line 27 C 49 Lime H7 st>£rii^ 47 line 2? C 51 Line 2? 1 47 Line 27 J ^2 Lime 2? 71 Lino 2? ■ «3 Jifle 7.7 = Livw 2? i 55 Lino 2? > sa line 27 55 Li
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整版 语言 词法 分析器 实验 报告 汇总