Index: doc/bison.texinfo =================================================================== RCS file: /sources/bison/bison/doc/bison.texinfo,v retrieving revision 1.205 diff -u -r1.205 bison.texinfo --- doc/bison.texinfo 11 Sep 2006 18:56:58 -0000 1.205 +++ doc/bison.texinfo 16 Sep 2006 14:47:23 -0000 @@ -223,6 +223,7 @@ * Expect Decl:: Suppressing warnings about parsing conflicts. * Start Decl:: Specifying the start symbol. * Pure Decl:: Requesting a reentrant parser. +* Push Decl:: Requesting a push parser. * Decl Summary:: Table of all Bison declarations. Parser C-Language Interface @@ -3710,6 +3711,7 @@ * Expect Decl:: Suppressing warnings about parsing conflicts. * Start Decl:: Specifying the start symbol. * Pure Decl:: Requesting a reentrant parser. +* Push Decl:: Requesting a push parser. * Decl Summary:: Table of all Bison declarations. @end menu @@ -4226,6 +4228,92 @@ You can generate either a pure parser or a nonreentrant parser from any valid grammar. address@hidden Push Decl address@hidden A Push Parser address@hidden push parser address@hidden %push-parser + +A @dfn{pull parser} is invoked one time and will itself call the lexical +analyzer to get the tokens that it requires in order to satisfy the grammar. +A @dfn{push parser} on the other hand expects that the caller of the parser +will call the lexical analyzer and pass the token to the parser over and +over until there are no more tokens to be received. There are some obvious +trade offs between these two style parsers that should be explained. + +A pull parser is invoked one time, and if the input grammar is large, this +operation could take a lot of time. This may not be acceptable for programs +that are interactive with the user. A push parser is invoked over and over +with the tokens that the caller has aquired. Each time the parser is +invoked with one of these tokens it is most likely going to return very +quickly. This describes how an interactive program would be able to parse +a large set of data for a grammar and still be responsive. That is, the +caller is able to execute any code it desires between calls to the parser. + +When a pull parser is invoked, it is expected that the input to the parser +is already available. That way, when the parser is looking for input, it +will get it. However, a push parser can be invoked when data arrives +since the caller is responsible for getting the next token. If the caller +is waiting for data to arrive over the internet, or waiting for user input to +get the next token, it can wait until that token is available and then pass +it along to the parser. The parser does not care where the input comes from +or how much time has elapsed between invoking it. + +In general, the pull parser is much more efficient. If the pull and push +parser are invoked with the same input, the pull parser will out perform +the push parser, because less function calls are required, and the push +parser has a small initialization overhead associated with each invocation +of it. + +Normally, Bison generates a pull parser. This is suitable for most uses. +Alternatively, you can generate a push, reentrant parser. The Bison +declaration @code{%push-parser} says that you want the parser to be +a push parser. It looks like this: + address@hidden +%push-parser address@hidden example + +The result is that Bison will generate a @code{yypushparse} function that +can be used to invoke the push parser. The @code{yypushparse} function +should be invoked with each token that the user aquires. Bison will also +generate an opaque type @code{yypvars} that is used to represent the parser +results. The @code{yypvars} structure can be initialized with address@hidden and can be released using the @code{free} C standard +library call. The communication variables @code{yychar}, @code{yylval}, address@hidden and @code{yynerrs} become data members of the @code{yypvars} +structure. These variables can not be directly accessed and must be +accessed via the functions @code{yyresult_get}, @code{yychar_set}, address@hidden or @code{yylloc_set}. All push parsers that Bison +generates are reentrant. When the push parser option is used, Bison will +change the semantics of the function @code{yyparse}. @code{yypares} will +still exist, but it will simply call the push parser. This is done as a +convience, to allow existing Bison grammars to work. Here is an +example showing these things: + address@hidden +int +yyparse (void) address@hidden + struct yypvars *ctx = yypvarsinit (); + int status; + do @{ + yychar_set (ctx, yylex ()); + yylval_set (ctx, yylval); +#ifdef YYLTYPE_IS_TRIVIAL + yylloc_set (ctx, yylloc); +#endif + yypushparse (ctx); + status = yyresult_get (ctx); + @} while (status == 4); + free (ctx); + return status; address@hidden address@hidden example + +Whether the parser is a pull or push parser has nothing to do with the +grammar rules. You can generate either a pull or push parser from any +valid grammar. + @node Decl Summary @subsection Bison Declaration Summary @cindex Bison declaration summary