基于flex的词法分析器的设计和实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计1 基于Flex的词法分析器设计及实现
1.1 需求分析
1.1.1 问题定义
1、通过对 flex 基本知识的阅读,了解其工作原理和过程以及其匹配模式和规则,掌握简单的 lex 语法和规则;
2、在上述基础上能够自主编写出简单且可以运行的词法分析器,实现简单的词法分析功能;
3、通过实验,设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
1.1.2 功能描述
本次编制调试的词法分析器基本可以实现如下简单功能:
1、可以匹配识别关键字:else if switch for int float return void while (所有的关键字都是保留字,并且必须是小写);
2、可以匹配识别专用符号: + - * / < <= > >= == != = ; ,( ) [ ] { } /* */;
3、标识符(ID)和数字(NU )通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9;
4、可以匹配识别空格(空格由空白、换行符和制表符组成,空格通常被忽略,除了它必须分开 ID、NUM 关键字);
5、可以识别简单的注释(/* 注释内容*/);
1.1.3 开发环境及工具介绍
1、Window环境下载Visual Studio之后,利用其命令提示窗口进行操作。下载并安装Flex。
2、vs2010的编译器cl.exe。
3、flex:词法分析器
Flex是用来生成程序的工具,他们所生成的程序能够处理结构化输入,最初的Flex是用来生成编译器的,但是后来他们被证明在其他领域也非常有效。Flex是一个SourceForge项目。其依赖于GNU m4宏处理器。Linux和BSD都应该有m4,对于Windos用户来说,Flex被包含在Cygein Linux模拟环境中。
什么是FLEX?它是一个自动化工具,可以按照定义好的规则自动生成一个C 函数yylex(),也成为扫描器(Scanner)。这个C函数把文本串作为输入,按照定义好的规则分析文本串中的字符,找到符合规则的一些字符序列后,就执行在规则中定义好的动作(Action)。例如在规则中可以这样定义:如果遇到一个换行字符\n,那么就把行计数器的值加一。Flex文件就是一个文本文件,内容包括定义好的一系列词法规则。
1.2 系统概要设计
1.2.1 系统体系结构
Flex源文件(.l)flex
词法分析器的C
语言源文件
(.h)
编译
此法分析器
的课执行程
序图1-1 体系结构图
开始
初始化
读入需要
分析的语句
还有单词未分析?
读一个字符
是字母?
是数字?
其他单词
分析程序
输出单词二元式
常数分析程序关键字或标识符分析程序
结束
是
否否是是否
图1-2 词法分析流程图
1.2.2 系统模块划分
Lex 工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。一般可以分为<定义部分><规则部分>< 用户子程序部分>。其中规则部分是必须的,定义和用户子程序部分是任选的。
(1)定义部分:定义部分起始于 %{ 符号,终止于 %} 符号,其间可以是包括 include 语句、声明语句在内的 C 语句。这部分跟普通 C 程序开头没什么区别。
(2)规则部分:规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由 C 语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex 将识别出来的单词存放在 yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。类似 yytext 这些预定义的变量函数会随着后面内容展开一一介绍。动作部分如果有多行执行语句,也可以用{}括起来。
(3)用户子程序部分:最后一个%%后面的内容是用户子程序部分,可以包含用 C 语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的。这里需要注意的是,当编译时不带-ll 选项时,是必须加入 main 函数和 yywrap(yywrap 将下后面说明)。
Lex 其实就是词法分析器,通过配置文件*.l,依据正则表达式逐字符去顺序解析文件,并动态更新内存的数据解析状态。Lex 善长于模式匹配。词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:自动生成, 手工生成。
1.3 详细设计与实现
1.3.1 Lex代码的设计与实现
lex 源代码编写通过对 flex 的语法学习,掌握了编写的基本原则和步骤,因为实验要求编写一个简单地词法分析器,根据实验所要求实现检查分析的功能,实验代码较为简单,以下是自己编写的实验代码:
letter [a-zA-Z\_] 定义字母letter
dight [0-9] 定义数字dight
ID {letter}({letter})* 定义单词ID由若干个字母组成
NUM {dight}({dight})* 定义数字串NUM由若干个数字组成
B {letter}({dight}|{letter})* 定义标识符B 由数字戒字母组成
%{
int nchar, nword, nline; nchar 字符数nword单词数nline 行数
int line=1; line 为当前行数初始化为1
%}
%%
"else"|"if"|"else if"|"switch"|"for"|"int"|"float"|"return"|"void"|"while"
{nword++;nchar+=yyleng;printf("第%d 行:\t",line);printf("关键
字:%s\n",yytext);}
若匹配上else int float 等上述的关键字:单词数+1;字符数增加相应的个数;
输出“第line 行yytext \n”;
{B} {nword++;nchar+=yyleng;printf("第%d 行:\t",line);printf("标识
符:%s\n",yytext);} {B} {nword++;nchar+=yyleng;printf("第%d 行:\t",line);printf("标识
符:%s\n",yytext);}
若匹配上B 标识符:单词数+1;字符数增加相应的个数;
输出“第line 行标识符:yytext \n”;
{NUM} {nword++;nchar+=yyleng;printf("第%d 行:\t",line);printf("数
字:%s\n",yytext);}
若匹配上NUM数字:单词数+1;字符数增加相应的个数;
输出“第line 行数字:yytext \n”;
\+|\-|\*|\/|\<|\>|\=|\;|\,|\(|\)|\[|\]|\{|\} {nchar+=yyleng;printf("第%d
行:\t",line);printf("与%s\n",yytext);}
若匹配上+ - * / 等与:字符数增加相应的个数;
输出“第line 行与yytext \n”;
\<\=|\>\=|\=\=|\!\=|\/\*|\*\/ {nword++;nchar+=yyleng;printf("第%d
行:\t",line);printf("与%s\n",yytext);}
若匹配上< = > 等与:字符数增加相应的个数;
输出“第line 行与yytext \n”;
[ \t]+ {nchar++;}
若匹配上制表符:字符数+1;无输出;
\n { nline++;line++;nchar++; }