尽管使用 Flex 和 Bison 生成程式很简单,但是要让这些程式产生用户友好的语法和语义错误消息却很困难。本文将介绍 Flex 和 Bison 的错误处理特性,并展示如何使用他们,然后周详介绍他们的一些缺陷。
简介
正如 UNIX® 研发人员所了解的那样,Flex 和 Bison 的功能很强大,很适合研发词法和语法解析器,尤其是语言编译器和解释器。假如我们不熟悉他们所实现的工具 —— 分别是 Lex 和 Yacc —— 能够参考一下本文 参考资料 一节中有关 Flex 和 Bison 文档的链接,连同其他介绍这两个程式的文章。
本文介绍了更高级的一些主题:用来在编译器和解释器中更好地实现错误处理能力的特性和技术。为了展示这些技术,我使用了一个示例程式 ccalc,他基于 Bison 手册中的电脑实现了一个增强的计算器。我们能够从本文后面 下载 一节下载 ccalc 和相关文档。
增强包括使用了很多变量。在 ccalc 中,变量是通过在初始化中首次使用时定义的,例如 a = 3。假如变量是在初始化之前使用的,那就会产生语义错误,使用值为 0 来创建这个变量,并打印一条消息。
示例源文档
示例源代码中包括 7 个文档:
- ccalc.c:主程式,连同一些进行输入、输出和错误处理的函数
- ccalc.h:包括了对任何模块的定义
- cmath.c:数学函数
- parse.y:Bison 使用的输入文法
- lex.l:Flex 的输入
- makefile:简单的 makefile
- defs.txt:示例输入文档
这个程式接收两个参数:
-debug:产生调试输出filename:输入文档名;默认值为defs.txt
Bison 使用的配置
为了处理变量名和实际值,Bison 的语义类型必须进行增强:
清单 1. 更好的 Bison 语义类型
/* generate include-file with symbols and types */
辠ines
/* a more advanced semantic type */
%union {
double value;
char *string;
}
|
有些文法规则能够产生特定的语义类型,这需要像清单 2 中相同对 Bison 进行声明。要获得一个可移植性更好的 Bison 文法版本,我们需要重新定义 -*/() 符号。下面这个例子没有使用左括号 (,而是使用了结束符符号 LBRACE,这是由词法分析提供的。另外,操作符的优先顺序也必须进行声明。
对于 Flex 来说,所生成的代码通常都依赖于平台所使用的代码页(codepage)。尽管我们能够使用其他代码页,但是必须要对输入进行转换。因此和 Bison 代码不同,Flex 代码尚不能进行移植。
清单 2. Bison 声明
/* terminal symbols */
%token <string> IDENTIFIER
%token <value> VALUE
%type <value> expression
/* operator-precedence
* top-0: -
* 1: * /
* 2: -
*/
%left ADD SUB
%left MULT DIV
%left NEG
%start program
|
这段文法和 Bison 手册很类似,不同之处在于他使用了名字作为终端符号和标识符的简写形式。标识符是在赋值语句中进行定义和初始化的,并且能够在任何允许使用的地方使用。清单 3 给出了一个示例文法:
清单 3. 示例 Bison 文法
program
: statement SEMICOLON program
| statement SEMICOLON
| statement error SEMICOLON program
;
statement
: IDENTIFIER ASSIGN expression
| expression
;
expression
: LBRACE expression RBRACE
| SUB expression %prec NEG
| expression ADD expression
| expression SUB expression
| expression MULT expression
| expression DIV expression
| VALUE
| IDENTIFIER
;
|
program 的第三个输出让这个分析程式能够获得错误,从中搜索分号,然后继续执行(通常错误对于解析器来说都是很严重的)。
为了让这个例子更加有趣,规则体中的真正数学函数都是以单独函数的形式实现的。在进行高级文法分析时,我们要尽量确保规则简短,并使用函数来实现一些不会直接处理解析的过程:
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




