alpha = beta + gamma;
词法剖析把这段代码分解为这样一些暗号:alpha, =, beta, +, gamma, ;。接着语法剖析确定了 beta + gamma 是一个表达式,而这个表达式被赋给了 alpha。
不过后来它们在其他运用领域被证明也非常有效。任何运用程序,尤其文本处理,只要在其输入中探求特定的模式,或者它利用命令措辞作为输入,都适宜利用 Flex 与 Bison。
例如,SQL 剖析:

在编译器构造中,词法剖析器、语法剖析器是编译器前真个紧张组成部分。大多数编译器组织成三个紧张的阶段:前端、优化器和后端。前端专注于理解源措辞程序,将其转换为某种中间表示(IR)。而 Flex 与 Bison 便是给编译器前端设计出的工具。
起源bison 来源于 yacc,一个由 Stephen C. Johnson 于 1975 年到 1978 年期间在贝尔实验室完成的语法剖析器天生程序。正如它的名字(yacc 是 yet another compiler compiler 的缩写)所暗示的那样,那时很多人都在编写语法剖析器天生程序。Johnson 的工具基于 D. E. Knuth 所研究的语法剖析理论(因此 yacc 十分可靠)和方便的输入语法。这使得 yacc 在 Unix 用户中非常盛行,只管当时 Unix 所遵照的受限版权使它只能够被利用在学术界和贝尔系统里。大约在 1985 年,Bob Corbett,一个加州伯克利大学的研究生,利用改进的内部算法再次实现了 yacc 并演化成为伯克利 yacc。由于这个版本比贝尔实验室的 yacc 更快并且利用了灵巧的伯克利容许证,它很快成为最盛行的 yacc。来自自由软件基金会(Free Software Foundation)的 Richard Stallman 改写了 Corbett 的版本并把它用于 GNU 项目中,在那里,它被添加了大量的新特性并蜕变成为当前的 bison。bison 现在作为 FSF 的一个项目而被掩护,且它基于 GNU 公共容许证进行发布。
在 1975 年,Mike Lesk 和暑期演习生 Eric Schmidt 编写了 lex,一个词法剖析器天生程序,大部分编程事情由 Schmidt 完成。他们创造 lex 既可以作为一个独立的工具,也可以作为 Johnson 的 yacc 的协同程序。lex 因此变得十分盛行,只管它运行起来有一点慢并且有很多缺点。(不过 Schmidt 后来在打算机行业里拥有一份非常成功的奇迹,他现在,2009年,是 Google 的 CEO。2010 年 CEO 移交了,连续担当 Google 董事长。)
大概在 1987 年,Lawrence Berkeley 实验室的 Vern Paxson 把一种用 ratfor(当时盛行的一种扩展的 Fortran 措辞)写成的 lex 版本改写为 C 措辞的,被称为 flex,意思是“快速词法剖析器天生程序”(Fast Lexical Analyzer Generator)。由于它比 AT&T 的 lex 更快速和可靠,并且就像伯克利的 yacc 那样基于伯克利容许证,它终极也超越了原来的 lex。flex 现在是 SourceForge 的一个项目,依然基于伯克利容许证。
安装大多数 Linux 和 BSD 系统自带 flex 和 bison 作为系统的根本部分。如果你的系统没有包含它们,安装它们也很随意马虎。
例如在 Ubuntu/Debian 系统,可以直接 apt 安装:
# Ubuntu 20$ sudo apt install flex bison -y$ flex -Vflex 2.6.4$ bison -Vbison (GNU Bison) 3.5.1
范例
范例请见 https://github.com/ikuokuo/start-ai-compiler/tree/main/books/flex_bison ,都来自结语给出的 Flex & Bison 一书。
范例辅导了我们如何利用 Flex & Bison 开拓一个打算器,并能支持变量、过程、循环和条件表达式,有内置函数,也支持用户自定义函数。
如下编译所有范例:
cd books/flex_bison/# 编译 releasemake# 编译 debugmake debug# 清理make clean
范例程序会输出进 _build 目录,如下实行:
$ ./_build/linux-x86_64/release/1-5_calc/bin/1-5_calc> (1+2)3 + 4/2= 11$ ./_build/linux-x86_64/release/3-5_calc/bin/3-5_calc> let sq(n)=e=1; while |((t=n/e)-e)>.001 do e=avg(e,t);;Defined sq> let avg(a,b)=(a+b)/2;Defined avg> sq(10)= 3.162> sqrt(10)= 3.162> sq(10)-sqrt(10)= 0.000178
如果只编译某一范例:
cd ch01/1-1_wc/# 编译 releasemake -j8# 编译 debugmake -j8 args="debug"# 清理make clean
程序
Flex 与 Bison 程序都是由三部分构成:定义部分、规则部分和用户子例程。
... definition section ...%%... rules section ...%%... user subroutines section ...
Flex 规则部分基于正则表达式,Bison 则基于 BNF (Backus-Naur Form) 文法。详细用法,请依照结语给出的 Flex & Bison 一书,及范例。
这里不做过多阐述,本文旨在让大家理解有 Flex 与 Bison 这样工具,以及它们能帮助我们完成什么样的事情。
结语Flex 与 Bison 是词法剖析器(Scanner)与语法剖析器(Parser)的自动天生工具,运用了形式措辞理论的结果。这些工具同样可用于文本搜索、网站过滤、笔墨处理和命令行措辞阐明器。
本文内容紧张来源于以下书本:
2011-03 / flex与bison(中文版)[4] / 阅读[5]2009 / flex & bison - Text Processing Tools[6] / 阅读[7]GoCoding 个人实践的履历分享,可关注"大众年夜众号!
脚注[1] sql/sql_yacc.yy: https://github.com/mysql/mysql-server/blob/8.0/sql/sql_yacc.yy
[2] parser/scan.l: https://github.com/postgres/postgres/blob/master/src/backend/parser/scan.l
[3] parser/gram.y: https://github.com/postgres/postgres/blob/master/src/backend/parser/gram.y
[4] 2011-03 / flex与bison(中文版): https://book.douban.com/subject/6109479/
[5] 阅读: http://home.ustc.edu.cn/~guoxing/ebooks/flex%E4%B8%8Ebison%E4%B8%AD%E6%96%87%E7%89%88.pdf
[6] 2009 / flex & bison - Text Processing Tools: https://book.douban.com/subject/3568327/
[7] 阅读: https://web.iitd.ac.in/~sumeet/flex__bison.pdf