学习 bison 原理(一)

学习 bison 原理(一)

Bison 是一个解析器生成程序(Parser generator), 其将 CFG 转换为 LALR(1) 解析表,
兼容 yacc(Yet Another Compiler Compiler),
是一个来自 GNU 的开源软件. 网址是 http://www.gnu.org/software/bison/

关于 bison, 我见过有 Flex&Bison 使用手册/指南一类的图书, 也有翻译为中文
的, 在中文博客,文库或其它地方也有如何使用的心得说明等.

我在自己学编译原理的时候(如著名的龙书), 里面会讲到自底向上的语法分析,
也讲述了 LR(0), LR(1), LALR(1) 的原理和计算方法. 然而仅仅看书仍然是不能
全都理解, 所以我想找一个实际的软件好好研究下源代码, 跟书上的理论对应起来,
也许可以帮助我们真正地理解书上的理论. 然而终究我水平有限, 所学的也可能没太多用,
不过既然研究了些, 就还是写下来自己的一点认识, 以期和对此感兴趣的朋友共学,
最终也能促进自己更提高一些. 所以, 如果本文错误百出, 还希望大家能多体谅...

在 bison 的网站可以下载到 bison 的源代码, 我先下载了 bison 的早期版本 1.25,
看早期的代码的好处是, 早期代码比较多关注在核心算法本身的实现, 没有太多的
包装, 可以让我把焦点放在算法本身上... 可实际上, 可能下载个 2.0 研究更合适,
如果还有时间, 我也想再看看更新的版本.


Bison 读入一个 CFG(context-free grammar, 上下文无关文法) 的文法文件,
在程序内经过计算, 主输出一个 parser generator 的 c 文件. 这些内容见手册,
这里不多说了, 下面主要论述程序如何做到.

主程序分为如下几个步骤进行:
    1. 读取/解析命令行选项 Main.getargs(), 打开文件 Files.openfiles()
       这些是程序基本的准备工作, 一般不属于算法范畴, 我们略去不述.
    2. 读入文法文件 Reader.reader(), 文法文件一般以 .y 为后缀.
       读取时建立内存的一些中间数据结构(主要是单链结构), 后面详述.
    3. 将第2步读入的数据进行检查, 消除无用的,错误的产生式, 建立/转换为适合
       计算 LR 的数据结构(主要是单链=>数组结构). 预先计算一些辅助数据.
    4. 计算 LR0 状态集, 结果可能是一个非确定的(有冲突的)有限状态机.
    5. 转变第 4 步的状态机为确定的 LALR 状态机.
    6. 如果第 5 步中有 s/r, r/r 冲突, 则解决冲突.
    7. 输出及别的收尾工作. 一般略去不细述了.

这几个步骤的核心是 4,5,6, 前面的一些准备步骤 2,3 因为为 后面步骤建立所需数据
结构, 所以也有必要提及, 1,7 我们就不细述了. 为了方便研究, 我写了一个 c# 版的
研究程序, 或可以说 bison 1.25 的 c# 调试版. 后面随着研究写完注解, 我会将其
上传, 请大家方便对照本文看, 也可多给提建议.


参考: http://3e8.org/pub/scheme/doc/parsing/Efficient%20Computation%20of%20LALR(1)%20Look-Ahead%20Sets.pdf
   主要的参考, 此程序的 LALR 算法根据该论文所写. 我注释中所提 论文[1] 即指此文档.
 
参考: http://wenku.baidu.com/view/57fa798da0116c175f0e4824.html
   里面提到上文, 计算向前看符号集(各种方法及比较).
 
参考: http://hi.baidu.com/ekpumiyvnciouye/item/64dd1a51fc884bcbd3e10cd2
   里面解读 lalr.c 文件, 但实在有点简略.
  
参考: http://blog.csdn.net/dragonzht/article/details/3352070
   解释 LALR 中 LA符号的传播.
 

你可能感兴趣的:(generator,parser,LALR,bison)