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

Reply via email to