Make a reentrant parser with Flex and Bison(Flex&Bison的线程安全)

转载自:http://www.lemoda.net/c/reentrant-parser/index.html

Making a reentrant (thread-safe) parser with Flex and Bison involves several stages.

To eliminate global variables from Flex, use the following line:

This changes yylex () to yylex (void *). The argument to yylex contains initialized memory for the lexer which is initialized using yylex_init:

and then release the memory after finishing the lexing:

In the flex documentation, this is given as yyscan_t, but it’s void *.

 

If the lexer is combined with a Bison parser, add

This makes Bison send yylex another argument to use instead of using the global variable yylval:

You can then use yylval in the Flex lexer, and it will refer to whatever is passed in as the first argument to yylex above.

 

The type of yylvalYYSTYPE, is also needed, so run Bison with the -d option to create the file yy.tab.h which defines it for you, and include this file into the lex file using the top section:

See C Scanners with Bison Parsers – Flex manual for more details.

 

In the Bison input file, add

to make a reentrant parser,

to tell it to send the lexer an extra argument, and

to add another argument to yyparse, which is the thing to pass in to Flex.

 

The above is already enough to create a reentrant parser. If you also need to pass in something to Bison, you can add a member

with

then use a preprocessor macro like

in the Bison preamble to make Bison send the scanner. In this case, use

 

To use private data in the Flex lexer, set its value with yylex_set_extra:

after calling yyinit_lexer. Here scanner is the data passed to yyinit_lexer. In the preamble of the Flex file, add

The data in user_data is then available in the lexer as yyextra:

See Extra Data – Flex manual.

Leave a Reply

Your email address will not be published.