Although it is easy to use Flex and Bison generators, it is difficult to make these programs produce user-friendly syntax and semantic error messages. This article describes the error handling features of Flex and Bison, and shows you how to use them, and then describes some of their flaws in detail.
Brief introduction
As UNIX® developers know, Flex and Bison are very powerful and well suited to developing lexical and syntactic parsers, especially language compilers and interpreters. If we are not familiar with the tools they implement-Lex and yacc--, for one, refer to the links in the Resources section of this article for Flex and Bison documentation, and other articles that describe both programs.
This article describes some of the more advanced topics: features and techniques used to better implement error handling capabilities in compilers and interpreters. To showcase these technologies, I used a sample program Ccalc, which implements an enhanced calculator based on the computer in the Bison manual. We can download Ccalc and related files from the download section later in this article.
Enhancements include the use of many variables. In Ccalc, a variable is defined by the first time it is used in initialization, for example, a = 3. If the variable is used before initialization, it generates a semantic error, creates the variable with a value of 0来, and prints a message.
Sample source file
The sample source code includes 7 files:
CCALC.C: Main program, and some functions for input, output and error handling
Ccalc.h: Includes definitions of all modules
CMATH.C: Mathematical Functions
Input grammars used by Parse.y:bison
Lex.l:flex's input
Makefile: a simple makefile
Defs.txt: Sample Input file
This program receives two parameters:
-debug: Generating Debug output
FileName: enter filename; default value is Defs.txt
Settings used by Bison
To handle variable names and actual values, the semantic types of Bison must be enhanced:
Listing 1. Better semantic type of Bison
/* generate include-file with symbols and types */
%defines
/* a more advanced semantic type */
%union {
double value;
char *string;
}