Part3�法分�3.ppt

Download Report

Transcript Part3�法分�3.ppt

Part3词法分析
授课:胡静
内容提要
词法分析器的作用
词法分析程序的设计与实现——状态图
词法分析程序的自动生成——有穷自动机
词法分析器的自动产生
LEX工作过程
首先,使用LEX语言写一个定义词法分析器的源程序
lex.l。
然后利用LEX编译器将lex.l转换成C语言程序lex.yy.c。
它包括从lex.l的正规表达式构造的状态转换图的表格
形式以及使用该表格识别词素的标准子程序。
与lex.l中正规表达式相关联的动作是C代码段,这些
动作可以直接加入到lex.yy.c中。
最后,lex.yy.c通过C编译器生成目标程序,这个目标
程序就是把输入流转换成记号序列的词法分析器。
LEX工作过程
Lex源程序
Lex编译程序
词素
FA模拟器
转换表
词法分析器
词法分析器L
输入缓冲区
LEX说明
一个LEX程序由如下三部分组成:
声明部分(辅助定义式)
%%
转换规则(识别规则)
%%
辅助过程 (用户子程序)
声明部分包括变量声明、符号常量声明和正规定义。
声明部分
声明部分举例
LEX识别规则
LEX程序的转换规则是如下形式的语句:
P1
P2
…
pn
{A1}
{A2}
{An}
LEX程序的第三部分包含action所需要的辅助过程。这些过程
可以单独编译,并与词法分析器一起装载。
LEX举例
正规表达式
记号
属性值
ws
-
-
if
if
-
then
then
-
else
else
-
id
id
指向符号表表项的指针
num
num
指向符号表表项的指针
<
relop
LT
<=
relop
LE
=
relop
EQ
<>
relop
NE
>
relop
GT
>=
relop
GE
LEX举例
%{
/*符号常数定义
LT, LE, EQ, NE, GT, GE,
IF, THEN, ELSE, ID, NUMBER, RELOP */
%}
/*正规定义*/
dilim
[ \t \n]
ws
{delim}+
letter
[A-Za-z]
digit
[0-9]
id
{letter}({letter}|{digit})*
number
{digit}+(\.{digit}+)?(E[+\-])?{digit}+)?
%%
LEX举例
%%
{ws}
if
then
else
{id}
{number}
“<”
“<=”
“=”
“<>”
“>”
“>=”
%%
{/*没有动作和返回值*/ }
{return(IF);}
{return(THEN);}
{return(ELSE);}
{yylval = install_id(); return(ID);}
{yylval = install_num(); return(NUMBER);}
{yylval = LT; return(RELOP);}
{yylval = LE; return(RELOP);}
{yylval = EQ; return(RELOP);}
{yylval = NE; return(RELOP);}
{yylval = GT; return(RELOP);}
{yylval = GE; return(RELOP);}
LEX举例
%%
install_id()
{
/*往符号表填入词素的过程,yytext指向词素的第一个字符,
yyleng表示词素的长度。将词素填入符号表,返回指向该词素
所在表项的指针*/
}
install_num()
{
/*与填写词素的过程类似,只不过词素是一个数。*/
}
LEX举例说明
假设由上面的程序生成的词法分析器被给定的一个由两个制
表符、一个if和一个空格组成的输入串。
两个制表符是能与模式ws匹配的初始最长前缀。
与ws相关联的动作不做任何事,因此词法分析器移动词素的开
始指针yytext使其指向i,并开始查找下一个记号。
下一个匹配的词素是if。请注意,模式if和{id}均匹配这个词素,
并且没有能匹配更长串的模式。由于上面的程序中匹配关键字if
的模式先于匹配标识符的模式执行,所以if被匹配成关键字。通
常,采用将匹配关键字的模式置于匹配标识符的模式之前的策
略,可以简单有效的保留关键字。
假设读入的头两个字符是<=。
模式<匹配上第一个字符,但它不是能匹配输入字符串的最长前
缀的模式。
LEX采用“选择最长匹配前缀的策略”方便的解决了<和<=之间
的冲突。这里,当然<=被选择作为下一个记号。
LEX说明
由LEX创建的词法分析器与语法分析器协同工作的方式如下:
词法分析器被语法分析器调用后,从尚未扫描的输入字符串中
读字符,每次读入一个字符,直到发现能与某个正规表达式pi匹
配的最长前缀。
词法分析器执行Ai。通常Ai会将控制返回给语法分析器。然后如
果不将控制交给语法分析器,词法分析可以继续发现更多的词
素,直到某个操作将控制返回给语法分析器。
词法分析器这种不断查找词素,直到以显示的return调用结束工
作的方式,使其可以方便的处理空白符和注释。
词法分析器只返回记号给语法分析器,带有与词素相关信息的
属性值是通过全局变量yylval传递的。
超前扫描操作
在LEX中我们可以把模式写成r1/r2的形式,其中r1
和r2都是正规表达式。它的意思是当一个字符串与r1
匹配时,还需要其后的字符串与r2匹配,这样才算该
字符串与r1匹配成功。在超前扫描操作符/后面的正
规表达式r2表示需要进一步匹配的内容,这里他只是
匹配的一个限制,而不是匹配的一个部分。
将Fortran中DO识别为关键字的LEX说明如下:
DO 501 I =1.25
DO/({letter} | {digit})* = ({letter} | {digit})*, {动作}
超前扫描符举例
区别Fortran中的关键字和标识符
识别关键字IF的模式可以写为:
IF/\(. *\) {letter}
处理Fortran的if语句问题的另一种方法是:当看到字
符串IF(后,先确定IF是否被声明为数组。如果是,
我们才去匹配上面给出的整个模式。这样的检查使得
由LEX说明自动实现一个词法分析器变得很难,而且
在运行时可能会花费更多的时间,因为要由模拟状态
转化图的程序频繁的判断是否要进行这样的检查。
LEX的实现
单个正则表达式
词法分析器
处理多样的REs
将所有的正则表达式的NFA联合在一起,变成一个单
一的有限自动机
LEX二义性的处理方法
词法分析器
输出端是Token流
将tokens和终态联系在一起。
当到达一个终态时,就将相应的token输出。
最长匹配
当到达一个终态时,要查看是否存在更进一步的转换。
如果不存在,则返回当前终态对应的token
优先级规则
当终态对应多个token的时候,有可能会有相同的最长
匹配的token
将这个终结状态和最高优先级的token联系起来。
LEX举例
LEX举例
NFA确定化
给出状态转换表
LEX程序举例
Thanks for your time!
Questions & Answers