Lex和Yacc应用方法(二).再识Lex与Yacc
草木瓜 20070314
早在二十世记七十年代之前,编写编译器一直是一个非常费时的工作。但到了1975这
一年这一切却发生了重大转变,首先Stephen C. Johnson Lesk在贝尔实验室完成了
Yacc开发,为了配合yacc更好的协作, Mike Lesk和Eric Schmidt又完成了lex。从
而Lex和yacc成为计算机编译领域的重要理论,而这些工具也极大地简化了编写编译
器的工作。
后来Robert Corbett和Richard Stallman在此基础上又完成了bison。Jef Poskanzer,
Vern Paxson 也对lex作了大量改进,称为flex。
<本系列文章的地址:http://blog.csdn.net/liwei_cmg/category/207528.aspx>
一、Lex理论
Lex使用正则表达式从输入代码中扫描和匹配字符串。每一个字符串会对应一个动作。
通常动作返回一个标记给后面的剖析器使用,代表被匹配的字符串。每一个正则表达
式代表一个有限状态自动机(FSA)。我们可以用状态和状态间的转换来代表一个(FSA)。
其中包括一个开始状态以及一个或多个结束状态或接受状态。
我们以上文《Lex和Yacc应用方法(一).初识Lex》第一个例子详细说明:
exfirst.l
%{
#include "stdio.h"
%}
%%
[/n] ; A
[0-9]+ printf("Int : %s/n",yytext); B
[0-9]*/.[0-9]+ printf("Float : %s/n",yytext); C
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s/n",yytext); D
[/+/-/*///%] printf("Op : %s/n",yytext); E
. printf("Unknown : %c/n",yytext[0]); F
%%
这里使用一相对简单的输入文件 file.txt
i=1.344+39;
bcd=4%9-333
我们假定,
Lex 系统创建一动态列表:内容+规则+状态
Lex 状态:1 接受 2 结束
接受表示该元素可以做为模式匹配
结束表示该元素已完成模式匹配
读入“i”
[查找元素]查找相邻且状态为1的元素,无元素,
[匹配规则]D,
[新增列表<元素1>并置数据](存在则覆盖)状态为1,规则为D,内容为"i"。
[操作顺序符] 1
读入“=”
[查找元素]查找相邻且状态为1的元素,“i=”寻找匹配规则,无规则
[置上一元素]<元素1>状态为2
[匹配规则]F,
[新增列表<元素2>并置数据](存在则覆盖)状态为1,规则为F,内容为"="
[操作顺序符] 2
读入“1”,
[查找元素]查找相邻且状态为1的元素,“=1”寻找匹配规则,无规则
[置上一元素]<元素2>状态为2
[匹配规则]B,
[新增列表<元素3>并置数据](存在则覆盖)状态为1,规则为B,内容为"1"
[操作顺序符] 3
读入“.”
[查找元素]查找相邻且状态为1的元素,“1.”寻找匹配规则,无规则,但有潜在规则C
[匹配规则]F,
[新增列表<元素4>并置数据](存在则覆盖)状态为1,规则为F,内容为"."
[置上一元素]<元素3>状态为1
[操作顺序符] 4
读入“3”
[查找元素]查找