Next: About yyscan_t, Previous: Accessing Variables with Reentrant Scanners, Up: The Reentrant API in Detail [Contents][Index]
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 ); }
Next: About yyscan_t, Previous: Accessing Variables with Reentrant Scanners, Up: The Reentrant API in Detail [Contents][Index]