On Fri, Sep 15, 2006 at 08:58:04AM -0700, Paul Eggert wrote:
> Thanks again for all this work! (Now for the hard part: the
> documentation. :-)
OK, I'm generally not as good at this, but I would like to get better.
Let me know if this is a good starting point.
2006-09-16 Bob Rossi <[EMAIL PROTECTED]>
* doc/bison.texinfo (Bison declarations): Add Push Decl.
Thanks,
Bob Rossi
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.
[EMAIL PROTECTED] Push Decl
[EMAIL PROTECTED] A Push Parser
[EMAIL PROTECTED] push parser
[EMAIL PROTECTED] %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:
+
[EMAIL PROTECTED]
+%push-parser
[EMAIL PROTECTED] 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
[EMAIL PROTECTED] and can be released using the @code{free} C standard
+library call. The communication variables @code{yychar}, @code{yylval},
[EMAIL PROTECTED] 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},
[EMAIL PROTECTED] 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:
+
[EMAIL PROTECTED]
+int
+yyparse (void)
[EMAIL PROTECTED]
+ 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;
[EMAIL PROTECTED]
[EMAIL PROTECTED] 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