Lex 和 Yacc 从入门到精通
熊春雷
Abstract
在开发程序的过程中经常会遇到文本解析的问题,例如:解析 C 语言源程序,
编写 脚本引擎等等,解决这种文本解析的方法有很多,一种方法就是自己手动
用 C 或者 C++直接编写解析程序,这对于简单格式的文本信息来说,不会是什么
问题,但是 对于稍微复杂一点的文本信息的解析来说,手工编写解析器将会是
一件漫长痛苦 而容易出错的事情。本系列文档就是专门用来由浅入深的介绍两
个有名的 Unix 工 具 Lex 和 Yacc,并会一步一步的详细解释如何用这两个工具
来实现我们想要的任何 功能的解析程序,为了方便理解和应用,我会在该系列
的文章中尽可能的采用具 体可行的实例来加以阐释,而且这种实例都是尽可能
的和具体的系统平台无关的 ,因此我采用命令行程序作为我们的解析程序的最
终结果。
1、环境配置篇
开发 Lex 和 Yacc 程序最需要的程序就是 lex 和 yacc 了,如果你是 Unix 或
者 Linux 系统,则 系统自带了这两个工具,无需安装,不过值得说明的是
GNU/Linux 下面的 Lex 是 flex, 而 Yacc 则是 bison。另外需要的就是一个 C/C++
语言编译器,由于我们采用的是 GNU 的 lex 和 yacc,所以,理所当然的我们就
使用 GNU 的编译器了,如果是 Unix 或者 Linux 系统 ,那么编译器应该已经安装
了。在这里我重点讨论的是 Windows 系统环境下的 Lex 和 Yacc 程序的开发,至
于为什么选择 Windows 系统作为开发平台,则是为了尽可能的让初 学者容易入
门。
1.1.必备工具
言归正传,首先列举 Windows 平台下面 Lex 和 Yacc 开发环境所需要安装的程
序:
1. Lex(flex.exe)和 Yacc(bison.exe)环境
2. C/C++编译器
1.2.flex 和 bison
值得说明的是,flex.exe和bison.exe是UnxUtils包中的文件,已经将许多
Unix/Linux平台的程序都移植到了Windows平台,可以直接到UnxUtils网站下载,
下载解压缩之后在系统的PATH环境变量中增加UnxUtils所有的exe文件所在的目
录,使 得DOS命令行可以直接搜索到flex.exe和bison.exe,除此之外还需要从
网络上下载 bison需要的bison.simple和bison.hairy两个文件,并且还要分别
设置环境变量 BISON_HAIRY指向bison.hairy,BISON_SIMPLE指向bison.simple。
Tip
如果觉得麻烦也可以直接使用我做好的flex和bison环境,点击这里下载。
解压缩 lexyacc.rar 之后运行里面的 lexyacc.bat 文件就会得到一个 lex 和
yacc 环境, 下图是简单的运行结果:
1.3.C/C++编译器
由于我们使用的flex和bison都是GNU的工具,所以为了方便,采用的C/C++
编译器也 采用GNU的编译器GCC,当然我们需要的也是Windows版本的GCC了。目
前Windows平台 的GCC主要是MinGW编译器,可以到 MinGW的主页下载安装。
Important
注意安装了 MinGW 之后一定要将安装后的 MinGW 的 bin 路径设置到环境变量
PATH 中。
我们在下一章里面将会真正的接触到 Lex 和 Yacc 的具体内容,敬请关注:)
2、正则表达式篇
正则表达式在 Unix/Liunx 系统中起着非常重要的作用,在很大一部分的程
序中都使用了正则表达式,可以这么说:“在 Unix/Linux 系统中,如果不懂正
则表达式就不算会使用该系统”。本文中使用的 Lex 和 Yacc 都是基于正则表达
式的应用,因此有必要用一篇文档的形式详细说明在 Lex 和 Yacc 中使用的正则
表达式为何物!
其实正则表达式非常简单,用过 DOS 的人都知道通配符吧,说得简单一点,
正则表达式就是稍微复杂一点的通配符。这里的正则表达式非常简单,规则非常
少,只需要花上几分钟就可以记住。正则表达式的元字符列表如下:
元字符 匹配内容
. 除了换行符之外的任意字符
\n 换行符
* 0 次或者多次匹配
+ 1 次或者多次匹配
? 0 次或者 1 次匹配
^ 行首
$ 行尾
a|b a 或者 b
(ab)+ ab 的一次或者多次匹配
“a+b” a+b(字面意思)
[] 一类字符
有了上面的元字符之后,就可以用上面的元字符表达出非常复杂的匹配内容
出来,就像 DOS 名令中的通配符可以匹配多个指定规则的文件名一样。现在让我
们看看上面的元字符的一些应用例子,列表如下:
表达式 匹配内容
abc abc
abc* abc abcc abccc abcccc ……
abc+ abcc abccc abcccc ……
a(bc)+ abcbc abcbcbc abcbcbcbc ……
a(bc)? abc abcbc
[abc] a b c 其中之一
[a-z] a b c d e f g… … z 其中之一
[a\-z] a – z 三个字符其中之一
[-az] – a z 三个字符其中之一
[A-Za-z0-9]+ 大小写字符和 10 个数字的一个或多个
[ \t\n] 空格,跳格,换行三者之一(空白符)