Previous: Token Locations, Up: Lexical


4.6.4 Calling Conventions for Pure Parsers

When you use the Bison declaration %define api.pure full to request a pure, reentrant parser, the global communication variables yylval and yylloc cannot be used. (See 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 locations, 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 wish to pass additional arguments to yylex, use %lex-param just like %parse-param (see Parser Function). To pass additional arguments to both yylex and yyparse, use %param.

— Directive: %lex-param {argument-declaration} ...

Specify that argument-declaration are additional yylex argument declarations. You may pass one or more such declarations, which is equivalent to repeating %lex-param.

— Directive: %param {argument-declaration} ...

Specify that argument-declaration are additional yylex/yyparse argument declaration. This is equivalent to ‘%lex-param {argument-declaration} ... %parse-param {argument-declaration} ...’. You may pass one or more declarations, which is equivalent to repeating %param.

For instance:

     %lex-param   {scanner_mode *mode}
     %parse-param {parser_mode *mode}
     %param       {environment_type *env}

results in the following signatures:

     int yylex   (scanner_mode *mode, environment_type *env);
     int yyparse (parser_mode *mode, environment_type *env);

If ‘%define api.pure full’ is added:

     int yylex   (YYSTYPE *lvalp, scanner_mode *mode, environment_type *env);
     int yyparse (parser_mode *mode, environment_type *env);

and finally, if both ‘%define api.pure full’ and %locations are used:

     int yylex   (YYSTYPE *lvalp, YYLTYPE *llocp,
                  scanner_mode *mode, environment_type *env);
     int yyparse (parser_mode *mode, environment_type *env);