【MySQL源码】yacc & Lex

目录

1. YACC

1.1. YACC概述–bison

  1. yacc(Yet Another Compiler Compiler),是一个经典的生成语法分析器的工具。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。
  2. Bison 基本上与 Yacc 兼容,并且在 Yacc 之上进行了改进。它经常和 Flex (一个自动的词法分析器生成器)一起使用。
  3. 此软件的源代码是可自由获得的,在 GPL 下发布。

参考资料:

  1. YACC(BISON)使用指南
  2. 书籍推荐:
    1. flex与bison 中文版
    2. yacc与lex 中文版

1.2. 语法规则

1.2.1. 结构

YACC文件格式
yacc文件分为三部分:

… definitions …(%{}%)

%%
… rules …
%%
… subroutines …

  1. bison语法的结束标记 $end

  2. 其他
    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 块

  1. 用来定义部分 可以使用 %{…%} 的C代码;

  2. 放置在 框架代码的前或后;

  3. 格式
    %code[place]{

    }

    –top, provides, requires

1.2.6. yy宏

  1. yyerror()
    用于报错; 可以报告出行号和最近的记号;
    产生一个错误信息;

  2. YYABORT;
    无法继续, 立即返回;–存在错误;
    立即返回非零值;

  3. YYACCEPT
    使 yyparse()立即返回 一个零值; --成功;
    –无法判定输入结束, 而解析有效;

  4. YYBACKUP
    当前记号移除, 替换为另一个;

  5. yyparse()
    语法分析器的入口函数;
    忘记上次分析可能拥有的任何状态重新开始分析;

    lex产生的 词法分析器 yylex(), 继续上次的分析;


1.3. rules 规则

1.3.1. 优先级与结合性

  1. 优先级声明
%left  左声明
%right 右声明
%nonassoc  --声明没有结合性的操作符

操作符按照优先级的 升序 被声明
   --后声明的具有更高的优先级;

  1. 注意:
    1. 每条规则可以有各自的 优先级和结合性; --%prec
    2. 尽量使用优先级解决问题;

1.3.2. 左递归与右递归


1.3.3. 继承属性($0)


1.4. 二义性和冲突

1.4.1. 二义性

  1. 解决方法:

    1. GLR分析: 允许无限向前查看: --%glr-parser
  2. LALR 分析算法: --常用

1.4.2. 冲突

1.4.2.1. shift/reduce 移进/归约
  1. 含义:
    1. 一个输入的字符串存在两种可能的语法分析器:
    2. 其中一条结束–归约reduce
    3. 另一条不结束–移进shift

是一种严重的错误, 必须解决;

  1. 解决:
    1. 涉及优先级问题: – 优先级与结合性;
1.4.2.2. reduce/reduce 归约/归约
  1. 含义
    1. 同一个几号可以结束两条不同的规则;
1.4.2.3. %expect N
  1. 含义
    1. 预期的 reduce/reduce 冲突; – 其实语法存在错误
    2. 使用 GLR语法分析器 才推荐使用该特性;

1.5. 程序错误

1.5.1. bison程序问题

  1. 无限递归

  2. %prec 互换记号的优先级

  3. 嵌入动作
    可能导致 移进/归约 冲突;

1.5.2. 错误记号和错误恢复


2. LEX

flex程序的相关;
posix的lex

token 与 lex.h 中实际的SQL语句中的关键字相对应;

参考:

  1. flex与bison中文版

2.1. 上下文相关性

2.1.1. 左上下文相关

三种方法: 特殊的行首模式字符 起始状态 显式代码

2.1.2. 右上下问相关


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值