尽管使用Flex和Linux Bison生成程序非常简单,但是要让这些程序产生用户友好的语法和语义错误消息却很困难。本文将介绍Flex和Linux Bison的错误处理特性,并展示如何使用它们,然后详细介绍它们的一些缺陷。
简介
正如UNIX®开发人员所了解的那样,Flex和Linux 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:简单的makefiledefs.txt:示例输入文件这个程序接收两个参数:
-debug:产生调试输出filename:输入文件名;默认值为defs.txtBison使用的设置为了处理变量名和实际值,Bison的语义类型必须进行增强:
清单1.更好的Linux Bison语义类型
- /*generateinclude-filewithsymbolsandtypes*/
- %defines
- /*amoreadvancedsemantictype*/
- %union{
- doublevalue;
- char*string;
- }
有些文法规则可以产生特定的语义类型,这需要像清单2中一样对Bison进行声明。要获得一个可移植性更好的Bison文法版本,我们需要重新定义+-*/()符号。下面这个例子没有使用左括号(,而是使用了结束符符号LBRACE,这是由词法分析提供的。另外,操作符的优先顺序也必须进行声明。
对于Flex来说,所生成的代码通常都依赖于平台所使用的代码页(codepage)。尽管我们可以使用其他代码页,但是必须要对输入进行转换。因此与Bison代码不同,Flex代码尚不能进行移植。
【编辑推荐】