目录
1. YACC
1.1. YACC概述–bison
- yacc(Yet Another Compiler Compiler),是一个经典的生成语法分析器的工具。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。
- Bison 基本上与 Yacc 兼容,并且在 Yacc 之上进行了改进。它经常和 Flex (一个自动的词法分析器生成器)一起使用。
- 此软件的源代码是可自由获得的,在 GPL 下发布。
参考资料:
- YACC(BISON)使用指南
- 书籍推荐:
- flex与bison 中文版
- yacc与lex 中文版
1.2. 语法规则
1.2.1. 结构
YACC文件格式
yacc文件分为三部分:
… definitions …(%{}%)
%%
… rules …
%%
… subroutines …
-
bison语法的结束标记 $end
-
其他
flase +
true -
1.2.2. %union
标记出符号值可能拥有的所有C类型;
%union{
}
1. 可以有多个;
2. 不检查里面的内容;
1.2.3. %type 声明
用来声明 非终结符的类型;
%type <type> name, name, ....
<type> 中的 type 必须在 %union 定义过; 不是非终结符的名字;
1.2.4. 记号
1.2.5. %code 块
-
用来定义部分 可以使用 %{…%} 的C代码;
-
放置在 框架代码的前或后;
-
格式
%code[place]{}
–top, provides, requires
1.2.6. yy宏
-
yyerror()
用于报错; 可以报告出行号和最近的记号;
产生一个错误信息; -
YYABORT;
无法继续, 立即返回;–存在错误;
立即返回非零值; -
YYACCEPT
使 yyparse()立即返回 一个零值; --成功;
–无法判定输入结束, 而解析有效; -
YYBACKUP
当前记号移除, 替换为另一个; -
yyparse()
语法分析器的入口函数;
忘记上次分析可能拥有的任何状态重新开始分析;lex产生的 词法分析器 yylex(), 继续上次的分析;
1.3. rules 规则
1.3.1. 优先级与结合性
- 优先级声明
%left 左声明
%right 右声明
%nonassoc --声明没有结合性的操作符
操作符按照优先级的 升序 被声明
--后声明的具有更高的优先级;
- 注意:
- 每条规则可以有各自的 优先级和结合性; --%prec
- 尽量使用优先级解决问题;
1.3.2. 左递归与右递归
1.3.3. 继承属性($0)
1.4. 二义性和冲突
1.4.1. 二义性
-
解决方法:
- GLR分析: 允许无限向前查看: --%glr-parser
-
LALR 分析算法: --常用
1.4.2. 冲突
1.4.2.1. shift/reduce 移进/归约
- 含义:
- 一个输入的字符串存在两种可能的语法分析器:
- 其中一条结束–归约reduce
- 另一条不结束–移进shift
是一种严重的错误, 必须解决;
- 解决:
- 涉及优先级问题: – 优先级与结合性;
1.4.2.2. reduce/reduce 归约/归约
- 含义
- 同一个几号可以结束两条不同的规则;
1.4.2.3. %expect N
- 含义
- 预期的 reduce/reduce 冲突; – 其实语法存在错误
- 使用 GLR语法分析器 才推荐使用该特性;
1.5. 程序错误
1.5.1. bison程序问题
-
无限递归
-
%prec 互换记号的优先级
-
嵌入动作
可能导致 移进/归约 冲突;
1.5.2. 错误记号和错误恢复
2. LEX
flex程序的相关;
posix的lex
token 与 lex.h 中实际的SQL语句中的关键字相对应;
参考:
- flex与bison中文版
2.1. 上下文相关性
2.1.1. 左上下文相关
三种方法: 特殊的行首模式字符 起始状态 显式代码