(bison.info)Pure Calling


Prev: Token Positions Up: Lexical

Calling Conventions for Pure Parsers
------------------------------------

   When you use the Bison declaration `%pure_parser' to request a pure,
reentrant parser, the global communication variables `yylval' and
`yylloc' cannot be used.  (Note: A Pure (Reentrant) Parser.)
In such parsers the two global variables are replaced by pointers
passed as arguments to `yylex'.  You must declare them as shown here,
and pass the information back by storing it through those pointers.

     int
     yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
     {
       ...
       *lvalp = value;  /* Put value onto Bison stack.  */
       return INT;      /* Return the type of the token.  */
       ...
     }

   If the grammar file does not use the `@' constructs to refer to
textual positions, then the type `YYLTYPE' will not be defined.  In
this case, omit the second argument; `yylex' will be called with only
one argument.

   If you use a reentrant parser, you can optionally pass additional
parameter information to it in a reentrant way.  To do so, define the
macro `YYPARSE_PARAM' as a variable name.  This modifies the `yyparse'
function to accept one argument, of type `void *', with that name.

   When you call `yyparse', pass the address of an object, casting the
address to `void *'.  The grammar actions can refer to the contents of
the object by casting the pointer value back to its proper type and
then dereferencing it.  Here's an example.  Write this in the parser:

     %{
     struct parser_control
     {
       int nastiness;
       int randomness;
     };
     
     #define YYPARSE_PARAM parm
     %}

Then call the parser like this:

     struct parser_control
     {
       int nastiness;
       int randomness;
     };
     
     ...
     
     {
       struct parser_control foo;
       ...  /* Store proper data in `foo'.  */
       value = yyparse ((void *) &foo);
       ...
     }

In the grammar actions, use expressions like this to refer to the data:

     ((struct parser_control *) parm)->randomness

   If you wish to pass the additional parameter data to `yylex', define
the macro `YYLEX_PARAM' just like `YYPARSE_PARAM', as shown here:

     %{
     struct parser_control
     {
       int nastiness;
       int randomness;
     };
     
     #define YYPARSE_PARAM parm
     #define YYLEX_PARAM parm
     %}

   You should then define `yylex' to accept one additional
argument--the value of `parm'.  (This makes either two or three
arguments in total, depending on whether an argument of type `YYLTYPE'
is passed.)  You can declare the argument as a pointer to the proper
object type, or you can declare it as `void *' and access the contents
as shown above.

   You can use `%pure_parser' to request a reentrant parser without
also using `YYPARSE_PARAM'.  Then you should call `yyparse' with no
arguments, as usual.


automatically generated by info version 1.5

Dirfile and infopages generated Sat Dec 3 02:07:54 2005