# $Id: README,v 1.3 1996/12/17 01:42:26 jake Exp $

		       ------------------------
		       Perl 5 Byacc Patches 0.5
		       ------------------------

This is a set of patches to perl-byacc1.8.2 which cause it to generate
a Perl 5 class implementing a parser (instead of a file full of global
data and procedures). It's nice if you want to be squeaky clean, and
very nice if you have a need for multiple parsers or multiple
instances of a parser in one program.


			  How to install it
			  -----------------

1. Get perl-byacc1.8.2 and unpack it. See

     ftp://ftp.sterling.com/local/perl-byacc.tar.Z

2. Copy reader.c and skeleton.c from this directory to the
   perl-byacc1.8.2 directory.

3. Compile perl-byacc1.8.2 as usual.


			    How to use it
			    -------------

You must write your parser a little differently:

  1. Your .y file must begin with a package declaration (and any
     imports you need):

     %{
     package Parser;
     }

  2. Your .y file must end with '1;' since the generated file is a
     module.

  3. Your &yylex and &yyerror procedures can (optionally) take an
     extra argument, which is passed from &yyparse (see below).

  4. Your &yylex procedure no longer side-effects $yylval; instead,
     it must return a list containing the token and the value.

  5. Your top-level rule can assign a value to $$, and this value will
     be returned as the value of &yyparse (see below).

  6. The file that byacc writes is still called 'y.tab.pl', so you'll
     probably need to add something to your Makefile to rename it (so
     'use' works).

And you must write the code that uses the parser differently too:

  1. Use 'use Parser' (or whatever package you put in your .y file)
     instead of 'require "y.tab.pl"'.

  2. Create a new parser object with

     $p = Parser->new($yylex, $yyerror, $yydebug);

     The first two arguments are references to your &yylex and
     &yyerror procedures, respectively. The third is true or false to
     enable or disable debugging output.

     I can't really remember why I made the procedures parameters, but
     it must have seemed like a good idea at the time. If you think of
     a good use for it let me know.

  3. Start a parse by calling

     $val = $p->yyparse($s);

     Here $s is an optional "stream" argument which represents the
     state of the text you're scanning. Depending on what you want to
     do, this could be a filehandle reference, a string, some object
     you cooked up, or whatever.

     The argument is passed down to &yylex and &yyerror. &yylex should
     use it to get characters, and &yyerror should examine it to
     generate a meaningful message.

  4. $p->yyparse returns the value that your top-level rule assigned
     to $$, instead of true or false to indicate success or
     failure. This obviates the need to side-effect global variables
     to return values from the parser. You should use exceptions to
     handle error conditions.


			       Example
			       -------

I've included an ultra-simple calculator as an example. Type 'make' to
build the parser.


			       Copying
			       -------

This code is in the public domain--use it and redistribute it as you
like. I would appreciate acknowledgement of some kind (or at the very
least an email) if you use it in something that is widely used or
distributed.


			  Bugs and feedback
			  -----------------

Send them to Jake Donham (jaked@well.com). I'd love to hear from you
if you find these patches useful.
