Next: , Previous: Accessor Methods, Up: Reentrant Detail

19.4.6 Extra Data

User-specific data can be stored in yyextra.

In a reentrant scanner, it is unwise to use global variables to communicate with or maintain state between different pieces of your program. However, you may need access to external data or invoke external functions from within the scanner actions. Likewise, you may need to pass information to your scanner (e.g., open file descriptors, or database connections). In a non-reentrant scanner, the only way to do this would be through the use of global variables. Flex allows you to store arbitrary, “extra” data in a scanner. This data is accessible through the accessor methods yyget_extra and yyset_extra from outside the scanner, and through the shortcut macro yyextra from within the scanner itself. They are defined as follows:

         #define YY_EXTRA_TYPE  void*
         YY_EXTRA_TYPE  yyget_extra ( yyscan_t scanner );
         void           yyset_extra ( YY_EXTRA_TYPE arbitrary_data , yyscan_t scanner);

In addition, an extra form of yylex_init is provided, yylex_init_extra. This function is provided so that the yyextra value can be accessed from within the very first yyalloc, used to allocate the scanner itself.

By default, YY_EXTRA_TYPE is defined as type void *. You may redefine this type using %option extra-type="your_type" in the scanner:

         /* An example of overriding YY_EXTRA_TYPE. */
         #include <sys/stat.h>
         #include <unistd.h>
         %option reentrant
         %option extra-type="struct stat *"
         __filesize__     printf( "%ld", yyextra->st_size  );
         __lastmod__      printf( "%ld", yyextra->st_mtime );
         void scan_file( char* filename )
             yyscan_t scanner;
             struct stat buf;
             FILE *in;
             in = fopen( filename, "r" );
             stat( filename, &buf );
             yylex_init_extra( buf, &scanner );
             yyset_in( in, scanner );
             yylex( scanner );
             yylex_destroy( scanner );
             fclose( in );