词法分析.docx
- 文档编号:28294192
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:21
- 大小:175.51KB
词法分析.docx
《词法分析.docx》由会员分享,可在线阅读,更多相关《词法分析.docx(21页珍藏版)》请在冰豆网上搜索。
词法分析
实验报告
课程名称编译原理
实验项目词法分析的实现
专业计算机课文学与技术班级二班
姓名陈雪莹学号08030212
指导教师邓玉洁实验成绩
2011年5月9日
一.词法分析识别的语言介绍
词法分析的英语解释是lexicalanalysis,是计算机科学中将字符序列转换为单词(Token)序列的过程。
进行语法分析的程序或者函数叫作词法分析器(Lexicalanalyzer,简称Lexer),也叫扫描器(Scanner)。
扫描器能够识别其所能处理的单词中可能包含的所有字符序列(单个这样的字符序列即前面所说的“语素”)。
例如“整数”单词可以包含所有数字字符序列。
很多情况下,根据第一个非空白字符便可以推导出该单词的类型,于是便可逐个处理之后的字符,直到出现不属于该类型单词字符集中的字符(即最长一致原则)。
词法分析器一般以函数的形式存在,供语法分析器调用。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用Lex等工具自动生成。
这里的单词是一个字符串,是构成源代码的最小单位。
从输入字符流中生成单词的过程叫作单词化(Tokenization),在这个过程中,词法分析器还会对单词进行分类。
单词经常使用正则表达式进行定义,像lex一类的词法分析器生成器就支持使用正则表达式。
语法分析器读取输入字符流、从中识别出语素、最后生成不同类型的单词。
其间一旦发现无效单词,便会报错。
二.语言的正规式->NFA->DFA->流程图
题目:
设某一语言有如下单词:
关键字:
BEGIN,END,IF,THEN,ELSE,for,do,while
<标识符>--><字母>|<标识符><字母>|<标识符><数字>
<无符号整数>--><数字>|<无符号整数><数字>
<分界符>-->+|-|*|/|;|(|)|{|}|<|<=|=|!
=|>=|>|:
=|<空格>
<字母>-->a|…|z|A|…|Z
<数字>-->0|…|9
<空格>-->’’
(1)正规文法→正规式
<标识符>:
S<字母>:
1<数字>:
n<无符号整数>:
y
<空格>:
K<分界符>:
c
S→1|1S|nS
y→n|yn
c→+|-|*|/|;|(|)|{|}|<|<=|=|!
=|>=|>|:
=|K
1→a|…|z|A|…|Z
n→0|…|9
K→’’
(2)正规文法→正规式
(1)S→1|1S|nS
(2)S→1,S→1S|nS
(3)S→1,S→(1|n)S
(4)S=(1|n)*1
(1)y→n|yn
(2)y→n,y→yn
(3)y→n*n
(4)y=n
(3)DFA图:
ε
ε11εε
n
ε
εn
n
(4)NFA图:
1
1
n
N
3.程序设计
(1)总体设计
(2)子程序设计
scanner函数流程
Sort函数流程
Handlecom函数流程
Recogdig流程图
Recogid程序流程
4.程序中的结构说明
(1)符号表
BEGIN
0
END
1
IF
2
THEN
3
ELSE
4
for
5
do
6
while
7
+
8
—
9
id
29
*
11
/
12
;
13
(
14
)
15
{
16
}
17
<
18
<=
19
=
20
!
=
21
>=
22
>
23
==
24
<空格>
25
(2)结构体
结构体
说明
structsymbolrecord
用来单词编码表初始化。
structentrytype
用来定义符号表的数据结构。
structdigittype
用来定义常数表的数据结构。
structtokentype
用来定义token的数据结构。
(3)源程序代码
#include
#include
#include
#include
//定义单词编码表的数据结构
structsymbolrecord
{charsymbol[10];
intid;
};
//定义符号表的数据结构
structentrytype
{charidname[10];
intaddress;
inttype;
};
//定义常数表的数据结构
structdigittype
{intnum;
intaddress;
};
//Token字的数据结构
structtokentype
{intid;
intentry;
};
FILE*fp;//源文件指针
structdigittyped[10];//定义常数表,个数指针
structentrytypea[40];//定义符号表,个数指针
intk=0,t=0;
//单词编码表初始化
structsymbolrecords[30]=
{"BEGIN",0,
"END",1,
"IF",2,
"THEN",3,
"ELSE",4,
"for",5,
"do",6,
"while",7,
"+",8,
"—",9,
"*",11,
"/",12,
";",13,
"(",14,
")",15,
"{",16,
"}",17,
"<",18,
"<=",19,
"=",20,
"!
=",21,
">=",22,
">",23,
"==",24,
"",25,
"id",29
};
//识别标识符算法
tokentyperecogid(charch)
{tokentypetokenid;
FILE*fs;
intflag,fflag;
charword[10]={0};
inti,j;
i=0;
while(isalpha(ch)||isdigit(ch))
{word[i]=ch;
ch=fgetc(fp);
i=i+1;
}
ungetc(ch,fp);
word[i]='\0';
for(j=0;j<=8;j++)
{flag=strcmp(word,s[j].symbol);
if(flag==0)//是关键字
{tokenid.id=j;
tokenid.entry=-1;
break;
}
}
if(flag!
=0)
{for(j=0;j<=k;j++)
{fflag=strcmp(a[j].idname,word);
if(fflag==0)//在符号表中可以找到
{tokenid.id=29;
tokenid.entry=a[j].address;
break;
}
}
if(fflag!
=0)
{fs=fopen("symbol.txt","a");//符号表中不存在的标识符
strcpy(a[k].idname,word);
a[k].address=k;
a[k].type=29;
tokenid.id=29;
tokenid.entry=k;
for(j=0;j<9;j++)
fprintf(fs,"%c",word[j]);
fprintf(fs,"%c",'\t');
fprintf(fs,"%d",a[k].address);
fprintf(fs,"%c",'\t');
fprintf(fs,"%d",a[k].type);
fprintf(fs,"%c",'\n');
fclose(fs);
k=k+1;
}
}
returntokenid;
}
///识别数字函数
tokentyperecogdig(charch)
{intflag;
inti=0,j;
intnum=0;
tokentypetokenid;
while(isdigit(ch))
{num=(ch-48)+num*10;
ch=fgetc(fp);
i=i+1;
}
for(j=0;j<=t;j++)
if(d[j].num==num)
{flag=1;
tokenid.id=9;
tokenid.entry=d[j].address;
break;
}
if(flag!
=1)
{d[t].num=num;
d[t].address=t;
tokenid.id=9;
tokenid.entry=t;
t=t+1;
}
returntokenid;
}
//识别算符和界符函数
tokentyperecogdel(charch)
{tokentypetokenid;
switch(ch)
{case'+':
tokenid.id=8;break;
case'-':
tokenid.id=9;break;
case'*':
tokenid.id=11;break;
case'/':
tokenid.id=12;break;
case'=':
ch=fgetc(fp);
if(ch=='=')tokenid.id=24;
else{tokenid.id=20;
ungetc(ch,fp);
};
break;
case';':
tokenid.id=13;break;
case'(':
tokenid.id=14;break;
case')':
tokenid.id=15;break;
case'{':
tokenid.id=16;break;
case'}':
tokenid.id=17;break;
case'<':
ch=fgetc(fp);
if(ch=='=')tokenid.id=19;
else{tokenid.id=18;
ungetc(ch,fp);
};
break;
case'!
=':
tokenid.id=21;break;
case'>':
ch=fgetc(fp);
if(ch=='=')tokenid.id=22;
else{tokenid.id=23;
ungetc(ch,fp);
};
break;
case'':
tokenid.id=25;break;
}
tokenid.entry=-1;
returntokenid;
}
/////////////////////handlecom函数////////////
tokentypehandlecom(charch)
{tokentypetokenid;
charch1;
intflag=0;
if(ch!
='*')
{tokenid.id=29;
tokenid.entry=-1;
}
else
{while(flag==0)
{ch1=ch;
ch=fgetc(fp);
if((ch1='*')&&(ch='/'))
flag=1;
}
}
returntokenid;
}
///////////sort函数/////////
voidsort(charch)
{
structtokentypetokenword;
FILE*fq=fopen("tokenfile.txt","a");
if(isalpha(ch))
tokenword=recogid(ch);//字母
elseif(isdigit(ch))
tokenword=recogdig(ch);//数字
elseif(ch=='/')
tokenword=handlecom(ch);
else
tokenword=recogdel(ch);
printf("%d\t%d\n",tokenword.id,tokenword.entry);
fprintf(fq,"%d",tokenword.id);
fprintf(fq,"%c",'\t');
fprintf(fq,"%d",tokenword.entry);
fprintf(fq,"%c",'\n');
fclose(fq);
}
/////////////scanner函数////////
voidscanner()
{charch;
fp=fopen("source.txt","r");
ch=getc(fp);
while(ch!
=EOF)
{if(!
isspace(ch))
{sort(ch);
}
ch=fgetc(fp);
}
fclose(fp);
}
voidmain()
{inti;
printf("输出token字如下:
\n");
scanner();
printf("************************************\n");
printf("输出符号表如下:
\n");
printf("%s\t%s\t%s\n","idname","address","type");
for(i=0;i<=k-1;i++)
printf("%s\t%d\t%d\n",a[i].idname,a[i].address,a[i].type);
printf("************************************\n");
printf("输出常数表如下:
\n");
printf("%s\t%s\n","num","address");
for(i=0;i<=t-1;i++)
printf("%d\t%d\n",d[i].num,d[i].address);
printf("\n\n");
system("pause");
}
5程序测试
6实验总结
经过这次的测试技术实验,我个人得到了不少的收获,一方面加深了我对课本理论的认识,另一方面也提高了实验操作能力。
现在我总结了以下的体会和经验。
这次的实验跟我们以前做的实验不同,这次实验没有老师辅导,是真真正正的自己亲自去完成。
所以是我觉得这次实验最宝贵,最深刻的。
就是实验的过程全是我们学生自己动手来完成的,这样,我们就必须要弄懂实验的原理。
在这里我深深体会到哲学上理论对实践的指导作用:
弄懂实验原理,而且体会到了实验的操作能力是靠自己亲自动手,亲自开动脑筋,亲自去请教别人才能得到提高的。
我们做实验绝对不能人云亦云,要有自己的看法,这样我们就要有充分的准备,若是做了也不知道是个什么实验,那么做了也是白做。
这次的实验报告是经过我一次次的修改,慢慢的完善。
因此在实验过程中我受易非浅:
它让我深刻体会到实验前的理论知识准备。
这学期的实验中,在收获知识的同时,还收获了阅历,收获了成熟,在此过程中,我们通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。
更重要的是,在实验课上,我们学会了很多学习的方法。
而这是日后最实用的,真的是受益匪浅。
要面对社会的挑战,只有不断的学习、实践,再学习、再实践。
指导教师签字:
年月日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 分析