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:
option extra-type="void *"
YY_EXTRA_TYPE yyget_extra ( yyscan_t scanner );
void yyset_extra ( YY_EXTRA_TYPE arbitrary_data , yyscan_t scanner);
In these declarations, YY_EXTRA_TYPE is as before a placeholder for the type
specifier in the scanner’s extra-type option.
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.
In the default C/C++ back end, the extra field in your scanner state
structure is defined as type void *; in other target languages
it might be a generic type, or no such field might be generated at
all. In back ends which support this extra field, you may redefine
the 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]