• Flex & Bison 开始


    Flex 与 Bison 是为编译器和解释器的编程人员特别设计的工具:

    • Flex 用于词法分析(lexical analysis,或称 scanning),把输入分割成一个个有意义的词块,称为记号(token)。
    • Bison 用于语法分析(syntax analysis,或称 parsing),确定这些记号是如何彼此关联的。

    例如,如下代码片段:

    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 -V
    flex 2.6.4
    $ bison -V
    bison (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/
    
    # 编译 release
    make
    # 编译 debug
    make 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/
    
    # 编译 release
    make -j8
    # 编译 debug
    make -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)的自动生成工具,应用了形式语言理论的结果。这些工具同样可用于文本搜索、网站过滤、文字处理和命令行语言解释器。

    本文内容主要来源于以下书籍:

    GoCoding 个人实践的经验分享,可关注公众号!

  • 相关阅读:
    jqgrid自带多选与单选
    NPOI读写Excel【转载】
    C# 對 List<string> 取交集、補集、超集、串聯
    在前端解決顯示null值一例
    Linux netstat命令详解和使用例子(显示各种网络相关信息)
    Git 忽略規則及 .gitignore 規則不生效的辦法
    树莓派上传数据错误一例
    搭建本地SVN資料
    利用樹霉派採集溫濕度上傳到OneNET(非完整,僅參考)
    部署ASP.Net Core 2.1 項目到 IIS
  • 原文地址:https://www.cnblogs.com/gocodinginmyway/p/16412441.html
Copyright © 2020-2023  润新知