词法分析器的实现与设计重点讲义资料.docx
《词法分析器的实现与设计重点讲义资料.docx》由会员分享,可在线阅读,更多相关《词法分析器的实现与设计重点讲义资料.docx(11页珍藏版)》请在冰豆网上搜索。
![词法分析器的实现与设计重点讲义资料.docx](https://file1.bdocx.com/fileroot1/2022-12/30/0fd6374f-dedd-47eb-b7c4-1a04d3148916/0fd6374f-dedd-47eb-b7c4-1a04d31489161.gif)
词法分析器的实现与设计重点讲义资料
题目:
词法分析器的设计与实现
一、引言3
二、词法分析器的设计4
2.1词的内部定义4
2.2词法分析器的任务及功能5
2.2.1任务5
2.2.2功能:
5
2.3单词符号对应的种别码:
6
三、词法分析器的实现6
3.1主程序示意图:
7
3.2函数定义说明7
3.3程序设计实现及功能说明8
3.3.1关键字8
3.3.2关键字的定义8
3.3.3符合的关键字的查找8
四、词法分析程序的C语言源代码:
8
五、结果分析:
11
摘要:
词法分析是中文信息处理中的一项基础性工作。
词法分析结果的好坏将直接影响中文信息处理上层应用的效果。
通过权威的评测和实际应用表明,IRLAS是一个高精度、高质量的、高可靠性的词法分析系统。
众所周知,切分歧义和未登录词识别是中文分词中的两大难点。
理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。
Abstract:
lexicalanalysisisabasictaskinChineseinformationprocessing.TheresultsoflexicalanalysiswilldirectlyaffecttheeffectivenessoftheapplicationofChineseinformationprocessing.TheevaluationandpracticalapplicationshowthatIRLASisahighprecision,highqualityandhighreliabilitylexicalanalysissystem.ItiswellknownthatsegmentationambiguityandunknownwordrecognitionarethetwomajordifficultiesinChinesewordsegmentation.Theunderstandingoflexicalanalysetheprogramatcompile,deepenoffiniteautomatamodelforunderstanding,masterlexicalanalysisprogramimplementationmethodandtechnology,usingClanguagesubsetofasimplelanguagecompilationofascannedagaincompiler,todeepentocompiletheprinciplesolution,mastercompilerimplementationmethodandtechnology.
关键词:
词法分析器 扫描器 单词符号 预处理
Keywords:
lexicalanalyzerwordsymbolpretreatmentscanner
一、引言
运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。
本程序是在Visual Studio环境下,使用C语言作为开发工具。
基于实验任务的内容及目的,实现初步的需求分析,具备词法分析器的基本功能和整体构架。
逐步细化其功能,做到相应模块的具体化。
画出未成熟的流程图,确定整体设计的走向,在一定范围内约束编程活动,确保没有大的问题及缺陷存在,然后通过将来的具体的编程设计完善流程图。
完成计算机翻译过程的关键阶段,它为后面的语法分析、语义分析做好准备,打好基础,以便快速地、高质量地生成目标语言程序。
二、词法分析器的设计
由于我们规定的程序语句中涉及单词较少"故在词法分析阶段忽略了单词输入错误的检查"而将编译程序的重点放在中间代码生成阶段$词法分析器的功能是输入源程序"输出单词符号$规定输出的单词符号格式为如下的二元式%!
单词种别"单词自身的值#
2.1词的内部定义
对常量,变量,临时变量,保留关键字(if,while,begin,else,do等)、关系运算符、逻辑运算符、分号、括号等,规定其内部定义如附表所示
2.2词法分析器的任务及功能
2.2.1任务
就编译器基本结构而言,词法分析(lexicalanalysis)是编译过程的第一阶段。
实际上,在词法分析之前,有些编译器模型存在编译预处理阶段,C语言就是一个典型的例子。
不过,大多数Pascal编译器都不存在预处理器。
本书对编译预处理不作讨论。
词法分析的任务是从左到右扫描与分析构成源程序的字符流(字符串),把字符流分解为多个单词(token)。
每个单词都是具有独立含义且不可再分割的字符序列。
在编译器框架中,完成词法分析任务的模块称为词法分析器。
2.2.2功能:
词法分析器的基本功能是,按照语言的定义规则,逐个地读入源程序的符号,识别出对语言有意义的符号串,即单词符号;然后分析单词符号的属性,并把单词符号及其属性填写在表中;同时把源程序改造成等价的计算机内部表示——单词记号,以便编译的后续阶段使用。
(1)识别出源程序中的各个单词符号,并将其转换成内部编码形式;
(2)删除无用的空白字符、回车字符以及其他非实质性字符;
(3)删除注释
(4)进行词法检查,报告所发现的错误。
2.3单词符号对应的种别码:
单词符号对应的种别码
单词符号
种别码
单词符号
种别码
bgin
1
:
17
If
2
:
=
18
Then
3
<
20
wile
4
<>
21
do
5
<=
22
end
6
>
23
lettet(letter|digit)*
10
>=
24
dightdight*
11
=
25
+
13
;
26
—
14
(
27
*
15
)
28
/
16
#
0
三、词法分析器的实现
编写词法分析器,词法分析器能够识别关系算符,词法分析器能够识别标识符和关键字,词法分析器能够识别无符号数。
编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析器。
词法分析是从左向右扫描每行源程序的符号,拼成单词,换成统一的二元式 (单词种别码,单词符号的属性值)表示。
对给定的程序通过词法分析器识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示,设计一个词法分析程序,理解词法分析器实现的原理,掌握程序设计语言中的各类单词的词法分析方法,加深对词法分析原理的理解。
3.1主程序示意图:
⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
Char*rwtab[6]={“begin”,“if”,“then”,“while”,“do”,“end”,};
是
(2)程序中需要用到的主要变量为syn,token和sum。
3.2函数定义说明
(1)search()查找并识别当前单词类别,并给定单词类别二元式码,决定给定字符串类别码(即单词种别)和记录次序码。
(2)alphaprocess()识别当前是数组、保留字、标识符。
(3)point()识别当前字符串是指针。
(4)digitprocess()识别当前是常整数、小数、负小数。
(5)otherprocess()识别当前是其它(标点符号等)。
(6)fopen()在默认路径下打开分析程序并读入字符串。
3.3程序设计实现及功能说明
3.3.1关键字
关键字:
beginifendwhlieelsewritereaddocallconstchar
Untilproducerepeat
运算符:
+—*/
界符:
{}[](),.;:
3.3.2关键字的定义
voidinit()
{for(intj=0;j<18;j++)
{strcpy(symtable[j].lexptr,str[j]);
symtable[j].token=j+3;}}
3.3.3符合的关键字的查找
intsearch(char*temp)
{for(unsignedinti=0;i<18;i++)
{if(!
strcmp(symtable[i].lexptr,temp))
returnsymtable[i].token;
}return0;}
四、词法分析程序的C语言源代码:
#include
#include
usingnamespacestd;
#defineMAX22
charch='';
stringkey[15]={"begin","end","if","then","else","while","write","read","do","call","const","char","until","procedure","repeat"};
//字符串键[15]={“开始”,“结束”,“如果”,“当时”,“其他”,“当”,“写”,“读”,“做”,“访问”,“常量”,“字符”,“直到”,“程序”,“重复”};
intIskey(stringc){//关键字判断
inti;
for(i=0;iif(key[i].compare(c)==0)return1;//将i作比较,返回1
}
return0;
}
intIsLetter(charc){//判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))return1;
elsereturn0;
}
intIsDigit(charc){//判断是否为数字
if(c>='0'&&c<='9')return1;
elsereturn0;
}
voidanalyse(FILE*fpin){//无效的分析(文件及外地个人识别号)
stringarr="";
while((ch=fgetc(fpin))!
=EOF){//赋值
arr="";
if(ch==''||ch=='\t'||ch=='\n'){}
elseif(IsLetter(ch)){
while(IsLetter(ch)||IsDigit(ch)){
if((ch<='Z')&&(ch>='A'))ch=ch+32;
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
if(Iskey(arr)){cout<elsecout<}
elseif(IsDigit(ch)){
while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
cout<}
elseswitch(ch){//标识符分类识别
case'+':
case'-':
case'*':
case'/':
cout<case'=':
case'(':
case')':
case'[':
case']':
case'{':
case'}':
cout<case';':
case',':
case':
':
{ch=fgetc(fpin);
if(ch=='=')cout<<":
="<<"\t$运算符"<else{cout<<"="<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
case'.':
case'<':
{ch=fgetc(fpin);
if(ch=='=')cout<<"<="<<"\t$运算符"<elseif(ch=='<')cout<<"<<"<<"\t$输出控制符"<elseif(ch=='>')cout<<"<>"<<"\t$运算符"<else{cout<<"<"<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
case'>':
{ch=fgetc(fpin);
if(ch=='=')cout<<">="<<"\t$运算符"<if(ch=='>')cout<<">>"<<"\t$输入控制符"<else{cout<<">"<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
default:
cout<}
}
}
voidmain(){
charin_fn[30];
FILE*fpin;
cout<<"请输入要查询的源文件名(包括路径和后缀名):
";
for(;;){
cin>>in_fn;
if((fpin=fopen(in_fn,"r"))!
=NULL)break;
elsecout<<"该文件路径错误!
请输入要查询的源文件名(包括路径和后缀名):
";
}
cout<<"\n********************查询结果分析如下*********************"<analyse(fpin);
fclose(fpin);
cout<cout<<"按任意键结束"<inta;
cin>>a;
}
5、结果分析:
在电脑D盘有一个名为源程序的文本文档,以此为例,运行结果如下:
输入:
输出:
6.总结:
在实验过程中遇到了很多的问题,经过查找资料和求助于同学再结合课堂上老师所讲解的内容,逐渐的把所遇到的问题解决。
实验的时候会出现各种BUG,而且比较注意细节问题,一点点问题出错就与自己所预想的结果有较大差距。
实验过程中我了解到c语言词法分析器是应用c语言编写通过扫描c语言源程序,从而正确识别出从源程序中分解出的二元式码形式的单词串,以供语法分析阶段使用。
词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
通过实验我对编译原理这门功课的知识掌握更加扎实稳固,比之前的只浮于表面的了解一些知识要有进步的多。
有了这次实验的经验更加加深了我对词法分析的理解,并且在之后的学习中更加激励我深入了解知识。