### 引言
本文介绍查询解析的第二步:语法分析。语法分析是从词法分析器中获得带有属性的token后,根据tokens的属性匹配语法规则,最后获得一棵分析树。本文首先介绍词法分析基本原理,然后介绍海山数据库中使用的yacc工具,最后对语法分析gram.y进行解析。
基本原理
语法分析器识别模式的方法主要分为两种:自顶而下的分析方法和自底而上的分析方法。自顶而下的方法从分析树的根节点开始向叶节点构建,自底而上的方法反之,从叶节点开始构建。两种分析方法中,语法分析树总是按照从左到右的方式被扫描,每次通过词法分析器获得一个词法单元,如下图所示:

语法分析器依次从词法分析器中获得词法单元,类似于词法分析器中依次读入字符,然后从词法单元中匹配语法规则。
海山数据库中使用的yacc工具采用自底向上的方法,因此本文主要介绍该类方法。
在介绍该方法的具体实现之前,首先介绍文法的概念。
文法:
文法是描述词法、语法规则的工具。用一组规则严格定义句子的结构,一个例子如下:
E -> E + T | T
T -> T * F | F
F -> (E) | id
E是开始符号,代表了所描述语言的最顶层结构。所有合法的句子都是从开始符号开始推导得到的。
这里的每一个表达式被称为产生式,式中的|为或,表示E可以被E+T或者T替换。
产生式中的
E、T、F是非终结符号,相当于一个非叶节点,如T可以被进一步展开为T * F | F,而这里的id,+,*,(,)是终结符号,相当于一个叶节点,无法再被展开。
自底向上的文法分析过程可以被看做输入tokens规约为文法开始符号的过程。
假设由词法分析器获得的tokens属性为id*id,自底向上的分析流程如下:
第一次规约将最左边的id规约为F,得到F*id;
第二次规约将F规约为T,生成T*id;
第三次规约将id规约为F,得到T*F;
第四次规约将T*F规约为T;
第五次将T规约为E,到达文法开始符,规约结束。
在具体的实现中,采用了移入-规约的语法分析技术,使用一个栈来保存文法符号,使用输入缓存区来存放将要进行语法分析的其他符号,上面的例子具体的实现方式如下图所示:
| step | 栈 | 输入 | 动作 |
|---|---|---|---|
| 1 | $ | id*id | 移入 |
| 2 | $id | *id | 按照F ->id规约 |
| 3 | $F | *id | 按照T -> F规约 |
| 4 | $T | *id | 移入 |
| 5 | $T* |

最低0.47元/天 解锁文章
1736

被折叠的 条评论
为什么被折叠?



