Bison 的使用说明

一、使用 Bison 的流程

1. 创建语言描述文件 (.y 文件)
    2. 编写词法分析器函数 yylex()
    3. 编写错误报告函数 yyerror()
    4. 在 main() 中调用分析器函数 yyparse()
    5. 执行 bison -d,由 .y 文件 产生 .tab.c 和 .tab.h 文件
    6. 执行 gcc,把 .tab.c 文件编译和链接成可执行程序

例. 计算器项目 calc。
    calc.y
       |  bison -d calc.y
    calc.tab.c
    calc.tab.h
       |  gcc calc.tab.c -o calc
    calc

二、语言描述文件的组成

%{
1. 序言 (Prologue)
   声明全局标识符,定义数据类型、变量和宏,包含头文件,等。
%}

2. 声明 (declarations)
   声明终结符,非终结符,运算符的优先级,符号语义值的各种类型。

%%

3. 文法 (Grammar rules)
   定义每一非终结符的文法规则。

%%

4. 结言 (Epilogue)
   定义序言中声明的函数,以及剩余的所有程序。如 yylex(), yyerror(), main(), 等。

三、语言描述文件中的声明

1. 语素类型的结合性
    %left       声明左结合操作符
    %right      声明右结合操作符
    %token      声明无结合性的语素类型
    单字符语素原本不用声明,声明它们是指出其结合性。

2. token 的语义值
    若有,存储在全局变量 yylval (类型 YYSTYPE) 中。

四、词法分析器函数 yylex()

该函数实现功能:读入下一 token,返回它的编号。

例. 对于简化的 C语言。

1. 对于各种各样的数,编号 NUM。

2. 对于各种各样的字符串,编号 STR。

3. 对于各种各样的名称, 编号 ID。

4. 每一关键字有唯一的编号。
    例.
    关键字      编号
    int         INT
    double      DOUBLE
    if          IF
    while       WHILE
    return      RETURN
说明:这里把编号取为相应的大写,是为了方便记忆,并非必须。

5. 单字符 token 包括运算符和分隔符,如 '+', '-', ';', ',', 等。它们的编号为其自身,直接返回即可。

6. 输入结束,编号为 0。

如果把 token 的编号视作符号的分类,那么每个单字符自成一类。
    编号是一个整数,定义在 .tab.h 文件中,形如
    #define NUM 257
    #define ID  258
    ...

五、基本概念

1. BNF (Backus-Naur Form, 或 Backus Normal Form)
    John Backus 提出的描述上下文无关文法的范式。在 Peter Naur 的 Algol60 报告中做了少许改进。

2. 上下文无关文法 (Context-free grammars)
    描述不考虑上下文的规则的文法。如某规则说整数是表达式,那么,整数在任何地方都是一个允许的表达式。

3. 左递归 (Left recursion)
    规则中,右端的第一个符号与左端相同。如
exprs:    exprs ',' expr
        ;

4. 右递归 (Right recursion)
    规则中,右端的最后一个符号与左端相同。如
exprs:    expr ',' exprs
        ;

辨析:左递归比右递归更为自然,分析时占用内存也更少些。

5. 符号表 (Symbol table)
    用来存储和查询已存在符号的名称和相关数据的数据结构。

6. 终结符 (Terminal symbol)
    不可再分的文法符号。也称 token,中文称作语素、词法记号、记号、单词、符号等。

7. 非终结符 (Nonterminal symbol)
    可以表达为更小结构的文法结构。每一非终结符用一条规则来定义。

8. 开始符号 (Start symbol)
    一个特殊的非终结符,代表语言的开始。通常作为文法中的第一个规则。

9. LR(1)
    一种用于自底向上分析的上下文无关文法,大多数时侯需要一个预读语素来消除任何输入片段的歧义。

10. LALR(1)
    LR(1)的子集。Bison 采用的文法。

11. parser stack  分析栈
    自底向上分析算法用到的栈。

12. shift  移进
    把输入流中的下一个 token 移入分析栈。

13. reduce  归约
    归约分析栈顶中已识别的规则。当分析栈顶的符号序列匹配某规则右端时,用该规则的左端替换之。

14. look-ahead token  预读语素
    已读取、尚未移进的 token。

五、Bison 分析器算法

bison 采用自底向上 (bottom-up) 的分析方法。它用到一个分析栈 (parser stack),关键有两个动作:

1. 移进 (shift)
    读取的 token 移进到分析栈中。

2. 归约 (reduce)
    当分析栈顶的 n 个符号匹配某规则的右端时,用该规则的左端取代之。

自底向上算法要做的事情是,对于一个接一个读入的 token,何时移进,何时归约。LR(1) 中的 1表示,只需预读 1个语素,就可以确定是移进,还是归约。

在移进和归约的过程中,可能出现两类冲突。

1. 移进/归约冲突 (shift/reduce conflicts)
    在某一时刻,可以移进,也可以归约。是选择移进,还是归约?这就是移进/归约冲突。这种冲突可以接受。
    在出现移进/归约冲突时,bison 选择移进。

例. if 语句的文法。
stmt_if:  IF expr THEN stmt
        | IF expr THEN stmt ELSE stmt
        ;
    分析栈顶的符号序列是 IF expr THEN stmt,而当前符号是 ELSE。是移进?还是归约?bison 选择移进。

2. 归约/归约冲突 (Reduce/Reduce Conflicts)
    当分析栈顶的符号序列可归约到多于一个规则时,选择哪一个规则?这就是归约/归约冲突。这种冲突不可接受。这是文法中的严重错误,必须修改文法。
    在出现归约/归约冲突时,bison 选择归约到第一个匹配的规则。这十分冒险。

例. 定义包含 word 或 redirect 的序列。
sequence: /* empty */
        | sequence words
        | sequence redirects
        ;

words:    /* empty */
        | words word
        ;

redirects: /* empty */
        | redirects redirect
        ;

sequence, words 和 redirects 的定义单独来看没问题,但放在一起产生了歧义:一个空输入可以归约到这三个规则中的任何一个。

(笔记)Bison 的使用说明相关推荐

  1. CentOS笔记:yum使用说明

    2019独角兽企业重金招聘Python工程师标准>>> 1.基本操作 a) 列出package # yum list b) 搜索package # yum search <pa ...

  2. [笔记] GPGPU-SIM的使用说明(一)

    本文来自魏继增科学网博客:链接地址:http://blog.sciencenet.cn/blog-1067211-726653.html 3.1 Simulation Modes 默认情况下,大多数的 ...

  3. CentOS笔记:VirtualBox使用说明之Shared Folders

    一.安装依赖包 #yum install kernel-headers #yum install kernel-devel #yum install gcc* #yum install make 二. ...

  4. Bison 的构成与使用

    Bison 采用自底向上( bottom-up)的分析方法. bottom-up 算法是 LR(1),最先由knuth 1965年提出,以 BNF 文法为指引,比 top-down 算法更为强大.算法 ...

  5. S-function的使用

    说明:<MATLAB/Simulink系统仿真超级学习手册>石良臣 matlab2018a--仅作为笔记. S-function使用说明 相关概念 1.直接馈通 2.动态维矩阵 3.采样时 ...

  6. Zemax学习笔记(16)- ZEMAX_分析>报告使用说明

    Zemax学习笔记(16)- ZEMAX_分析>报告使用说明 总述 1.报告图 2.数据报告 3.摘要数据 总述 在ZEMAX中,想要获取系统最直接的参数,最方便的工具不失为系统分析>报告 ...

  7. Mask_RCNN翻译和详解笔记一(原文翻译+源代码+代码使用说明)

    Mask_RCNN翻译和详解笔记一(原文翻译+源代码+代码使用说明) 2018年06月01日 23:45:47 阅读数:332 原文:https://github.com/matterport/Mas ...

  8. stm32笔记02——ST-Link下载器使用说明

    <-----------------------------------------------------------------------------> 以前经常使用的仿真器是j-l ...

  9. 工作笔记:Android高德定位使用说明

    高德定位模块使用说明 权限和KEY 在AndroidManifest.xml添加权限,如果仅使用定位功能,其他不需要的权限可去掉. <!-- Normal Permissions 不需要运行时注 ...

最新文章

  1. android canvas png 失真,【小程序】--------------处理canvas导出图片模糊问题-------------【劉】...
  2. Linux 学习笔记:批量新增SAMBA用户的脚本
  3. AI:2020年6月22日北京智源大会演讲分享之09:00-09:50 全体大会《AI精度与隐私的博弈》
  4. unity3d干货分享:实现敌人锥形视角的3个方法
  5. 阿里巴巴java规范检查_阿里巴巴Java开发规范
  6. Centos7作为VNCserver,本地使用VNCViewer连接
  7. [HTML+CSS+Vue.js] 超长文本等内容默认折叠显示,点击展开全文,再点击收起(仿知乎效果)
  8. 四大常用视频接口对比
  9. 金仓数据库-java连接金仓数据库方法笔记
  10. Spring5-完全注解开发【之】第一步,先实现功能(增删改查),再讲解陌生代码
  11. 中国联通开放号码标记一键查询与清除服务
  12. 删除服务器tomcat上项目,删除tomcat服务器
  13. 带选择头像的用户注册页面
  14. Windows10 2021年5月更新正式推出,驱动人生详细介绍win10更新新功能
  15. 小牛叔讲Python第10章:化繁为简的推导式
  16. 【1小时记住Docker常用命令】Docker学以致用
  17. 12306官网页面html,新版12306网址页面以及订票系统功能介绍
  18. “你的期望薪资是多少?” 月薪3万的他是这样回答的......
  19. vault mysql_Hashicorp vault 简明配置教程
  20. 谈谈培训机构的-骗局-给新人一些建议

热门文章

  1. STM32智能门锁之调试步进电机
  2. 【HTTP】请求方法
  3. 【Opencv】目标追踪——高斯混合模型分离算法(MOG)
  4. 【ML】MoG与EM:从EM到MoG
  5. 【台大郭彦甫】Matlab入门教程超详细学习笔记六:高阶绘图(附PPT链接)
  6. html标签:表格、列表、图片、文字、表单、以及h5新增特性
  7. centos系统简析
  8. 素质、职教、信息化:教育实时互动的新命题
  9. 保监会欲放险资投房产
  10. 第一天:外企面试英语口语常用语