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);

By default, YY_EXTRA_TYPE is defined as type void *. You will have to cast yyextra and the return value from yyget_extra to the appropriate value each time you access the extra data. To avoid casting, you may override the default type by defining YY_EXTRA_TYPE in section 1 of your scanner:

     
         /* An example of overriding YY_EXTRA_TYPE. */
         %{
         #include <sys/stat.h>
         #include <unistd.h>
         #define YY_EXTRA_TYPE  struct stat*
         %}
         %option reentrant
         %%
     
         __filesize__     printf( "%ld", yyextra->st_size  );
         __lastmod__      printf( "%ld", yyextra->st_mtime );
         %%
         void scan_file( char* filename )
         {
             yyscan_t scanner;
             struct stat buf;
     
             yylex_init ( &scanner );
             yyset_in( fopen(filename,"r"), scanner );
     
             stat( filename, &buf);
             yyset_extra( &buf, scanner );
             yylex ( scanner );
             yylex_destroy( scanner );
        }