On Sat, Aug 11, 2007 at 07:05:29PM -0400, Joel E. Denny wrote:
> On Sat, 4 Aug 2007, Bob Rossi wrote:
>
> > +A push parser is typically useful when the parser is part of a
> > +main event loop in the clients application. Especially when
> > +the event loop needs to be triggered within a certain time period.
> > +This is often the case with a GUI application.
>
> "clients" -> "client's"
OK.
> The sentence starting with "Especially" is a sentence fragment.
OK.
> > +a pure parser (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). The only
> > +time you should create an impure push parser is to have backwards
> > +compatibility with the Yacc pull mode interface. Unless you know
>
> Let's say "with the impure Yacc pull mode interface".
OK.
> > [EMAIL PROTECTED]
> > +int yystatus;
> > +yypstate *yyps = yypstate_new ();
> > +do @{
> > + yystatus = yypush_parse (yyps, yylex ());
> > [EMAIL PROTECTED] while (yystatus == YYPUSH_MORE);
> > +yypstate_delete (yyps);
> > [EMAIL PROTECTED] example
>
> In this and your other examples, symbols named by users (yystatus, yyps)
> should not start with yy. The yy namespace is reserved for Bison symbols.
> (I'll correct this in the test suite.)
OK.
> Also, the pure examples will not compile because they don't pass a
> semantic value to yypush_parse. Please test each of your examples.
Oops, you are right, ok, I compiled these.
> > +stream. It is possible to yypush_parse tokens to select a subgrammar and
> > +then yypull_parse the rest of the input stream. If you would like to
> > +switch back and forth between between parsing styles, you would have to
> > write
> > +your own yypull_parse function that knows when to quit looking for input.
> > +An example of using the yypull_parse function would look like this:
>
> @code around the function names.
OK.
> > [EMAIL PROTECTED] {Function} yypstate_delete
> > +The function to delete a parser instance, produced by Bison in push mode;
> > +call this function to delete the memory associate with a parser.
>
> "associated".
OK.
> Please post an updated patch and then commit it. Don't forget to update
> the date in the ChangeLog entry. Also, I believe the entry was wider than
> 80 columns. If you could reformat, that would be best.
OK, great! I've done all that. I don't have commit priviledges, so
here's the patch, please commit it.
> Thanks for all your hard work, Bob.
Well, I really appreciate all your work. I'm thinking this wouldn't have
gotten done otherwise!
What is next? I could provide an example for the manual if it's
necessary. What I'm really interested is getting push.c moved to yacc.c.
I'm not really interested in using this feature until I know it'll get
into the next version of bison.
Thanks,
Bob Rossi
2007-08-12 Bob Rossi <[EMAIL PROTECTED]>
* doc/bison.texinfo (Push Decl): Document the push parser.
(Table of Symbols): Ditto.
(Pure Decl): Ditto.
(Decl Summary): Ditto.
(Multiple Parsers, Push Parser Function, Pull Parser Function,
Parser Create Function, Parser Delete Function):
Add new push parser symbols.
(Table of Symbols): Document push-parser, push-pull-parser,
yypush_parse,
yypull_parse, yypstate_new and yypstate_delete.
Index: doc/bison.texinfo
===================================================================
RCS file: /sources/bison/bison/doc/bison.texinfo,v
retrieving revision 1.233
diff -u -r1.233 bison.texinfo
--- doc/bison.texinfo 12 Aug 2007 02:12:29 -0000 1.233
+++ doc/bison.texinfo 13 Aug 2007 01:56:22 -0000
@@ -224,6 +224,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
@@ -3978,6 +3979,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
@@ -4510,8 +4512,9 @@
@code{yylloc} become local variables in @code{yyparse}, and a different
calling convention is used for the lexical analyzer function
@code{yylex}. @xref{Pure Calling, ,Calling Conventions for Pure
-Parsers}, for the details of this. The variable @code{yynerrs} also
-becomes local in @code{yyparse} (@pxref{Error Reporting, ,The Error
+Parsers}, for the details of this. The variable @code{yynerrs}
+becomes local in @code{yyparse} in pull mode but it becomes a member
+of yypstate in push mode. (@pxref{Error Reporting, ,The Error
Reporting Function @code{yyerror}}). The convention for calling
@code{yyparse} itself is unchanged.
@@ -4519,6 +4522,112 @@
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
[EMAIL PROTECTED] %push-parser
+
+A pull parser is called once and it takes control until all its input
+is completely parsed. A push parser, on the other hand, is called
+each time a new token is made available.
+
+A push parser is typically useful when the parser is part of a
+main event loop in the client's application. This is typically
+a requirement of a GUI, when the main event loop needs to be triggered
+within a certain time period.
+
+Normally, Bison generates a pull parser. The Bison declaration
[EMAIL PROTECTED] says that you want the parser to be a push parser.
+It looks like this:
+
[EMAIL PROTECTED]
+%push-parser
[EMAIL PROTECTED] example
+
+In almost all cases, you want to ensure that your push parser is also
+a pure parser (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). The only
+time you should create an impure push parser is to have backwards
+compatibility with the impure Yacc pull mode interface. Unless you know
+what you are doing, your declarations should look like this:
+
[EMAIL PROTECTED]
+%pure-parser
+%push-parser
[EMAIL PROTECTED] example
+
+There is a major notable functional difference between the pure push parser
+and the impure push parser. It is acceptable for a pure push parser to have
+many parser instances, of the same type of parser, in memory at the same time.
+An impure push parser should only use one parser at a time.
+
+When a push parser is selected, Bison will generate some new symbols in
+the generated parser. @code{yypstate} is a structure that the generated
+parser uses to store the parser's state. @code{yypstate_new} is the
+function that will create a new parser instance. @code{yypstate_delete}
+will free the resources associated with the corresponding parser instance.
+Finally, @code{yypush_parse} is the function that should be called whenever a
+token is available to provide the parser. A trivial example
+of using a pure push parser would look like this:
+
[EMAIL PROTECTED]
+int status;
+yypstate *ps = yypstate_new ();
+do @{
+ status = yypush_parse (ps, yylex (), NULL);
[EMAIL PROTECTED] while (status == YYPUSH_MORE);
+yypstate_delete (ps);
[EMAIL PROTECTED] example
+
+If the user decided to use an impure push parser, a few things about
+the generated parser will change. The @code{yychar} variable becomes
+a global variable instead of a variable in the @code{yypush_parse} function.
+For this reason, the signature of the @code{yypush_parse} function is
+changed to remove the token as a parameter. A nonreentrant push parser
+example would thus look like this:
+
[EMAIL PROTECTED]
+extern int yychar;
+int status;
+yypstate *ps = yypstate_new ();
+do @{
+ yychar = yylex ();
+ status = yypush_parse (ps);
[EMAIL PROTECTED] while (status == YYPUSH_MORE);
+yypstate_delete (ps);
[EMAIL PROTECTED] example
+
+That's it. Notice the next token is put into the global variable @code{yychar}
+for use by the next invocation of the @code{yypush_parse} function.
+
+Bison also supports both the push parser interface along with the pull parser
+interface in the same generated parser. In order to get this functionality,
+you should replace the @code{%push-parser} declaration with the
[EMAIL PROTECTED] declaration. Doing this will create all of the
+symbols mentioned earlier along with the two extra symbols, @code{yyparse}
+and @code{yypull_parse}. @code{yyparse} can be used exactly as it normally
+would be used. However, the user should note that it is implemented in the
+generated parser by calling @code{yypull_parse}. This makes the
[EMAIL PROTECTED] function that is generated with the @code{%push-pull-parser}
+declaration slower than the normal @code{yyparse} function. If the user
+calls the @code{yypull_parse} function it will parse the rest of the input
+stream. It is possible to @code{yypush_parse} tokens to select a subgrammar
+and then @code{yypull_parse} the rest of the input stream. If you would like
+to switch back and forth between between parsing styles, you would have to
+write your own @code{yypull_parse} function that knows when to quit looking
+for input. An example of using the @code{yypull_parse} function would look
+like this:
+
[EMAIL PROTECTED]
+yypstate *ps = yypstate_new ();
+yypull_parse (ps); /* Will call the lexer */
+yypstate_delete (ps);
[EMAIL PROTECTED] example
+
+Adding the @code{%pure-parser} declaration does exactly the same thing to the
+generated parser with @code{%push-pull-parser} as it did for
[EMAIL PROTECTED]
+
@node Decl Summary
@subsection Bison Declaration Summary
@cindex Bison declaration summary
@@ -4797,10 +4906,13 @@
in C parsers
is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
@code{yylval}, @code{yychar}, @code{yydebug}, and
-(if locations are used) @code{yylloc}. For example, if you use
[EMAIL PROTECTED] "c_"}, the names become @code{c_parse}, @code{c_lex},
-and so on. In C++ parsers, it is only the surrounding namespace which is
-named @var{prefix} instead of @samp{yy}.
+(if locations are used) @code{yylloc}. If you use a push parser,
[EMAIL PROTECTED], @code{yypull_parse}, @code{yypstate},
[EMAIL PROTECTED] and @code{yypstate_delete} will
+also be renamed. For example, if you use @samp{%name-prefix "c_"}, the
+names become @code{c_parse}, @code{c_lex}, and so on. In C++ parsers,
+it is only the surrounding namespace which is named @var{prefix} instead
+of @samp{yy}.
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
@end deffn
@@ -4830,6 +4942,16 @@
(Reentrant) Parser}).
@end deffn
[EMAIL PROTECTED] {Directive} %push-parser
+Bison declaration to request a push parser.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
[EMAIL PROTECTED] deffn
+
[EMAIL PROTECTED] {Directive} %push-pull-parser
+Bison declaration to request a push and a pull parser.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
[EMAIL PROTECTED] deffn
+
@deffn {Directive} %require "@var{version}"
Require version @var{version} or higher of Bison. @xref{Require Decl, ,
Require a Version of Bison}.
@@ -4913,8 +5035,11 @@
The precise list of symbols renamed is @code{yyparse}, @code{yylex},
@code{yyerror}, @code{yynerrs}, @code{yylval}, @code{yylloc},
[EMAIL PROTECTED] and @code{yydebug}. For example, if you use @samp{-p c},
-the names become @code{cparse}, @code{clex}, and so on.
[EMAIL PROTECTED] and @code{yydebug}. If you use a push parser,
[EMAIL PROTECTED], @code{yypull_parse}, @code{yypstate},
[EMAIL PROTECTED] and @code{yypstate_delete} will also be renamed.
+For example, if you use @samp{-p c}, the names become @code{cparse},
[EMAIL PROTECTED], and so on.
@strong{All the other variables and macros associated with Bison are not
renamed.} These others are not global; there is no conflict if the same
@@ -4943,6 +5068,12 @@
@menu
* Parser Function:: How to call @code{yyparse} and what it returns.
+* Push Parser Function:: How to call @code{yypush_parse} and what it returns.
+* Pull Parser Function:: How to call @code{yypull_parse} and what it returns.
+* Parser Create Function:: How to call @code{yypstate_new} and what it
+ returns.
+* Parser Delete Function:: How to call @code{yypstate_delete} and what it
+ returns.
* Lexical:: You must supply a function @code{yylex}
which reads tokens.
* Error Reporting:: You must supply a function @code{yyerror}.
@@ -5025,6 +5156,61 @@
exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @}
@end example
[EMAIL PROTECTED] Push Parser Function
[EMAIL PROTECTED] The Push Parser Function @code{yypush_parse}
[EMAIL PROTECTED] yypush_parse
+
+You call the function @code{yypush_parse} to parse a single token. This
+function is available if either the @code{%push-parser} or
[EMAIL PROTECTED] declaration is used.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
+
[EMAIL PROTECTED] int yypush_parse (yypstate *yyps)
+The value returned by @code{yypush_parse} is the same as for yyparse with the
+following exception. @code{yypush_parse} will return YYPUSH_MORE if more input
+is required to finish parsing the grammar.
[EMAIL PROTECTED] deftypefun
+
[EMAIL PROTECTED] Pull Parser Function
[EMAIL PROTECTED] The Pull Parser Function @code{yypull_parse}
[EMAIL PROTECTED] yypull_parse
+
+You call the function @code{yypull_parse} to parse the rest of the input
+stream. This function is available if the @code{%push-pull-parser}
+declaration is used.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
+
[EMAIL PROTECTED] int yypull_parse (yypstate *yyps)
+The value returned by @code{yypull_parse} is the same as for @code{yyparse}.
[EMAIL PROTECTED] deftypefun
+
[EMAIL PROTECTED] Parser Create Function
[EMAIL PROTECTED] The Parser Create Function @code{yystate_new}
[EMAIL PROTECTED] yypstate_new
+
+You call the function @code{yypstate_new} to create a new parser instance.
+This function is available if either the @code{%push-parser} or
[EMAIL PROTECTED] declaration is used.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
+
[EMAIL PROTECTED] yypstate *yypstate_new (void)
+The fuction will return a valid parser instance if there was memory available
+or NULL if no memory was available.
[EMAIL PROTECTED] deftypefun
+
[EMAIL PROTECTED] Parser Delete Function
[EMAIL PROTECTED] The Parser Delete Function @code{yystate_delete}
[EMAIL PROTECTED] yypstate_delete
+
+You call the function @code{yypstate_delete} to delete a parser instance.
+This function is available if either the @code{%push-parser} or
[EMAIL PROTECTED] declaration is used.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
+
[EMAIL PROTECTED] void yypstate_delete (yypstate *yyps)
+This function will reclaim the memory associated with a parser instance.
+After this call, you should no longer attempt to use the parser instance.
[EMAIL PROTECTED] deftypefun
@node Lexical
@section The Lexical Analyzer Function @code{yylex}
@@ -9264,6 +9450,16 @@
@xref{Pure Decl, ,A Pure (Reentrant) Parser}.
@end deffn
[EMAIL PROTECTED] {Directive} %push-parser
+Bison declaration to request a push parser.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
[EMAIL PROTECTED] deffn
+
[EMAIL PROTECTED] {Directive} %push-pull-parser
+Bison declaration to request a push and a pull parser.
[EMAIL PROTECTED] Decl, ,A Push Parser}.
[EMAIL PROTECTED] deffn
+
@deffn {Directive} %require "@var{version}"
Require version @var{version} or higher of Bison. @xref{Require Decl, ,
Require a Version of Bison}.
@@ -9438,7 +9634,8 @@
@deffn {Variable} yynerrs
Global variable which Bison increments each time it reports a syntax error.
-(In a pure parser, it is a local variable within @code{yyparse}.)
+(In a pure parser, it is a local variable within @code{yyparse}. In a
+pure push parser, it is a member of yypstate.)
@xref{Error Reporting, ,The Error Reporting Function @code{yyerror}}.
@end deffn
@@ -9447,6 +9644,33 @@
parsing. @xref{Parser Function, ,The Parser Function @code{yyparse}}.
@end deffn
[EMAIL PROTECTED] {Function} yypstate_delete
+The function to delete a parser instance, produced by Bison in push mode;
+call this function to delete the memory associated with a parser.
[EMAIL PROTECTED] Delete Function, ,The Parser Delete Function
[EMAIL PROTECTED]
[EMAIL PROTECTED] deffn
+
[EMAIL PROTECTED] {Function} yypstate_new
+The function to create a parser instance, produced by Bison in push mode;
+call this function to create a new parser.
[EMAIL PROTECTED] Create Function, ,The Parser Create Function
[EMAIL PROTECTED]
[EMAIL PROTECTED] deffn
+
[EMAIL PROTECTED] {Function} yypull_parse
+The parser function produced by Bison in push mode; call this function to
+parse the rest of the input stream.
[EMAIL PROTECTED] Parser Function, ,The Pull Parser Function
[EMAIL PROTECTED]
[EMAIL PROTECTED] deffn
+
[EMAIL PROTECTED] {Function} yypush_parse
+The parser function produced by Bison in push mode; call this function to
+parse a single token. @xref{Push Parser Function, ,The Push Parser Function
[EMAIL PROTECTED]
[EMAIL PROTECTED] deffn
+
@deffn {Macro} YYPARSE_PARAM
An obsolete macro for specifying the name of a parameter that
@code{yyparse} should accept. The use of this macro is deprecated, and