Next: , Previous: Makefiles and Flex, Up: Appendices

A.2 C Scanners with Bison Parsers

This section describes the flex features useful when integrating flex with GNU bison1. Skip this section if you are not using bison with your scanner. Here we discuss only the flex half of the flex and bison pair. We do not discuss bison in any detail. For more information about generating bison parsers, see Top.

A compatible bison scanner is generated by declaring ‘%option bison-bridge’ or by supplying ‘--bison-bridge’ when invoking flex from the command line. This instructs flex that the macro yylval may be used. The data type for yylval, YYSTYPE, is typically defined in a header file, included in section 1 of the flex input file. For a list of functions and macros available, See bison-functions.

The declaration of yylex becomes,

           int yylex ( YYSTYPE * lvalp, yyscan_t scanner );

If %option bison-locations is specified, then the declaration becomes,

           int yylex ( YYSTYPE * lvalp, YYLTYPE * llocp, yyscan_t scanner );

Note that the macros yylval and yylloc evaluate to pointers. Support for yylloc is optional in bison, so it is optional in flex as well. The following is an example of a flex scanner that is compatible with bison.

         /* Scanner for "C" assignment statements... sort of. */
         #include ""  /* Generated by bison. */
         %option bison-bridge bison-locations
         [[:digit:]]+  { yylval->num = atoi(yytext);   return NUMBER;}
         [[:alnum:]]+  { yylval->str = strdup(yytext); return STRING;}
         "="|";"       { return yytext[0];}
         .  {}

As you can see, there really is no magic here. We just use yylval as we would any other variable. The data type of yylval is generated by bison, and included in the file Here is the corresponding bison parser:

         /* Parser to convert "C" assignments to lisp. */
         /* Pass the argument to yyparse through to yylex. */
         #define YYPARSE_PARAM scanner
         #define YYLEX_PARAM   scanner
         %union {
             int num;
             char* str;
         %token <str> STRING
         %token <num> NUMBER
             STRING '=' NUMBER ';' {
                 printf( "(setf %s %d)", $1, $3 );


[1] The features described here are purely optional, and are by no means the only way to use flex with bison. We merely provide some glue to ease development of your parser-scanner pair.