Blame lib/Parse/Yapp.pm

Packit 292bd0
#
Packit 292bd0
# Module Parse::Yapp.pm.
Packit 292bd0
#
Packit 292bd0
# Copyright © 1998, 1999, 2000, 2001, Francois Desarmenien.
Packit 292bd0
# Copyright © 2017 William N. Braswell, Jr.
Packit 292bd0
# All Rights Reserved.
Packit 292bd0
#
Packit 292bd0
# See the Copyright section at the end of the Parse/Yapp.pm pod section
Packit 292bd0
# for usage and distribution rights.
Packit 292bd0
#
Packit 292bd0
#
Packit 292bd0
package Parse::Yapp;
Packit 292bd0
Packit 292bd0
use strict;
Packit 292bd0
use vars qw($VERSION @ISA);
Packit 292bd0
@ISA = qw(Parse::Yapp::Output);
Packit 292bd0
Packit 292bd0
use Parse::Yapp::Output;
Packit 292bd0
Packit 292bd0
# CORRELATION #py001: $VERSION must be changed in both Parse::Yapp & Parse::Yapp::Driver
Packit 292bd0
our $VERSION = '1.21';
Packit 292bd0
Packit 292bd0
1;
Packit 292bd0
Packit 292bd0
__END__
Packit 292bd0
Packit 292bd0
=encoding UTF-8
Packit 292bd0
Packit 292bd0
=head1 NAME
Packit 292bd0
Packit 292bd0
Parse::Yapp - Perl extension for generating and using LALR parsers. 
Packit 292bd0
Packit 292bd0
=head1 SYNOPSIS
Packit 292bd0
Packit 292bd0
  yapp -m MyParser grammar_file.yp
Packit 292bd0
Packit 292bd0
  ...
Packit 292bd0
Packit 292bd0
  use MyParser;
Packit 292bd0
Packit 292bd0
  $parser=new MyParser();
Packit 292bd0
  $value=$parser->YYParse(yylex => \&lexer_sub, yyerror => \&error_sub);
Packit 292bd0
Packit 292bd0
  $nberr=$parser->YYNberr();
Packit 292bd0
Packit 292bd0
  $parser->YYData->{DATA}= [ 'Anything', 'You Want' ];
Packit 292bd0
Packit 292bd0
  $data=$parser->YYData->{DATA}[0];
Packit 292bd0
Packit 292bd0
=head1 DESCRIPTION
Packit 292bd0
Packit 292bd0
Parse::Yapp (Yet Another Perl Parser compiler) is a collection of modules
Packit 292bd0
that let you generate and use yacc like thread safe (reentrant) parsers with
Packit 292bd0
perl object oriented interface.
Packit 292bd0
Packit 292bd0
The script yapp is a front-end to the Parse::Yapp module and let you
Packit 292bd0
easily create a Perl OO parser from an input grammar file.
Packit 292bd0
Packit 292bd0
=head2 The Grammar file
Packit 292bd0
Packit 292bd0
=over 4
Packit 292bd0
Packit 292bd0
=item C<Comments>
Packit 292bd0
Packit 292bd0
Through all your files, comments are either Perl style, introduced by I<#>
Packit 292bd0
up to the end of line, or C style, enclosed between  I</*> and I<*/>.
Packit 292bd0
Packit 292bd0
Packit 292bd0
=item C<Tokens and string literals>
Packit 292bd0
Packit 292bd0
Packit 292bd0
Through all the grammar files, two kind of symbols may appear:
Packit 292bd0
I<Non-terminal> symbols, called also I<left-hand-side> symbols,
Packit 292bd0
which are the names of your rules, and I<Terminal> symbols, called
Packit 292bd0
also I<Tokens>.
Packit 292bd0
Packit 292bd0
Tokens are the symbols your lexer function will feed your parser with
Packit 292bd0
(see below). They are of two flavours: symbolic tokens and string
Packit 292bd0
literals.
Packit 292bd0
Packit 292bd0
Non-terminals and symbolic tokens share the same identifier syntax:
Packit 292bd0
Packit 292bd0
		[A-Za-z][A-Za-z0-9_]*
Packit 292bd0
Packit 292bd0
String literals are enclosed in single quotes and can contain almost
Packit 292bd0
anything. They will be output to your parser file double-quoted, making
Packit 292bd0
any special character as such. '"', '$' and '@' will be automatically
Packit 292bd0
quoted with '\', making their writing more natural. On the other hand,
Packit 292bd0
if you need a single quote inside your literal, just quote it with '\'.
Packit 292bd0
Packit 292bd0
You cannot have a literal I<'error'> in your grammar as it would
Packit 292bd0
confuse the driver with the I<error> token. Use a symbolic token instead.
Packit 292bd0
In case you inadvertently use it, this will produce a warning telling you
Packit 292bd0
you should have written it I<error> and will treat it as if it were the
Packit 292bd0
I<error> token, which is certainly NOT what you meant.
Packit 292bd0
Packit 292bd0
Packit 292bd0
=item C<Grammar file syntax>
Packit 292bd0
Packit 292bd0
It is very close to yacc syntax (in fact, I<Parse::Yapp> should compile
Packit 292bd0
a clean I<yacc> grammar without any modification, whereas the opposite
Packit 292bd0
is not true).
Packit 292bd0
Packit 292bd0
This file is divided in three sections, separated by C<%%>:
Packit 292bd0
Packit 292bd0
	header section
Packit 292bd0
	%%
Packit 292bd0
	rules section
Packit 292bd0
	%%
Packit 292bd0
	footer section
Packit 292bd0
Packit 292bd0
=over 4
Packit 292bd0
Packit 292bd0
=item B<The Header Section> section may optionally contain:
Packit 292bd0
Packit 292bd0
=over
Packit 292bd0
Packit 292bd0
=item *
Packit 292bd0
Packit 292bd0
One or more code blocks enclosed inside C<%{> and C<%}> just like in
Packit 292bd0
yacc. They may contain any valid Perl code and will be copied verbatim
Packit 292bd0
at the very beginning of the parser module. They are not as useful as
Packit 292bd0
they are in yacc, but you can use them, for example, for global variable
Packit 292bd0
declarations, though you will notice later that such global variables can
Packit 292bd0
be avoided to make a reentrant parser module.
Packit 292bd0
Packit 292bd0
=item *
Packit 292bd0
Packit 292bd0
Precedence declarations, introduced by C<%left>, C<%right> and C<%nonassoc>
Packit 292bd0
specifying associativity, followed by the list of tokens or litterals
Packit 292bd0
having the same precedence and associativity.
Packit 292bd0
The precedence being the latter declared will be having the highest level.
Packit 292bd0
(see the yacc or bison manuals for a full explanation of how they work,
Packit 292bd0
as they are implemented exactly the same way in Parse::Yapp)
Packit 292bd0
Packit 292bd0
=item *
Packit 292bd0
Packit 292bd0
C<%start> followed by a rule's left hand side, declaring this rule to
Packit 292bd0
be the starting rule of your grammar. The default, when C<%start> is not
Packit 292bd0
used, is the first rule in your grammar section.
Packit 292bd0
Packit 292bd0
=item *
Packit 292bd0
Packit 292bd0
C<%token> followed by a list of symbols, forcing them to be recognized
Packit 292bd0
as tokens, generating a syntax error if used in the left hand side of
Packit 292bd0
a rule declaration.
Packit 292bd0
Note that in Parse::Yapp, you I<don't> need to declare tokens as in yacc: any
Packit 292bd0
symbol not appearing as a left hand side of a rule is considered to be
Packit 292bd0
a token.
Packit 292bd0
Other yacc declarations or constructs such as C<%type> and C<%union> are
Packit 292bd0
parsed but (almost) ignored.
Packit 292bd0
Packit 292bd0
=item *
Packit 292bd0
Packit 292bd0
C<%expect> followed by a number, suppress warnings about number of Shift/Reduce
Packit 292bd0
conflicts when both numbers match, a la bison.
Packit 292bd0
Packit 292bd0
=back
Packit 292bd0
Packit 292bd0
=back
Packit 292bd0
Packit 292bd0
=item B<The Rule Section> contains your grammar rules:
Packit 292bd0
Packit 292bd0
A rule is made of a left-hand-side symbol, followed by a C<':'> and one
Packit 292bd0
or more right-hand-sides separated by C<'|'> and terminated by a C<';'>:
Packit 292bd0
Packit 292bd0
    exp:    exp '+' exp
Packit 292bd0
        |   exp '-' exp
Packit 292bd0
        ;
Packit 292bd0
Packit 292bd0
A right hand side may be empty:
Packit 292bd0
Packit 292bd0
    input:  #empty
Packit 292bd0
        |   input line
Packit 292bd0
        ;
Packit 292bd0
Packit 292bd0
(if you have more than one empty rhs, Parse::Yapp will issue a warning,
Packit 292bd0
as this is usually a mistake, and you will certainly have a reduce/reduce
Packit 292bd0
conflict)
Packit 292bd0
Packit 292bd0
Packit 292bd0
A rhs may be followed by an optional C<%prec> directive, followed
Packit 292bd0
by a token, giving the rule an explicit precedence (see yacc manuals
Packit 292bd0
for its precise meaning) and optional semantic action code block (see
Packit 292bd0
below).
Packit 292bd0
Packit 292bd0
    exp:   '-' exp %prec NEG { -$_[1] }
Packit 292bd0
        |  exp '+' exp       { $_[1] + $_[3] }
Packit 292bd0
        |  NUM
Packit 292bd0
        ;
Packit 292bd0
Packit 292bd0
Note that in Parse::Yapp, a lhs I<cannot> appear more than once as
Packit 292bd0
a rule name (This differs from yacc).
Packit 292bd0
Packit 292bd0
Packit 292bd0
=item C<The footer section>
Packit 292bd0
Packit 292bd0
may contain any valid Perl code and will be appended at the very end
Packit 292bd0
of your parser module. Here you can write your lexer, error report
Packit 292bd0
subs and anything relevant to you parser.
Packit 292bd0
Packit 292bd0
=item C<Semantic actions>
Packit 292bd0
Packit 292bd0
Semantic actions are run every time a I<reduction> occurs in the
Packit 292bd0
parsing flow and they must return a semantic value.
Packit 292bd0
Packit 292bd0
They are (usually, but see below C<In rule actions>) written at
Packit 292bd0
the very end of the rhs, enclosed with C<{ }>, and are copied verbatim
Packit 292bd0
to your parser file, inside of the rules table.
Packit 292bd0
Packit 292bd0
Be aware that matching braces in Perl is much more difficult than
Packit 292bd0
in C: inside strings they don't need to match. While in C it is
Packit 292bd0
very easy to detect the beginning of a string construct, or a
Packit 292bd0
single character, it is much more difficult in Perl, as there
Packit 292bd0
are so many ways of writing such literals. So there is no check
Packit 292bd0
for that today. If you need a brace in a double-quoted string, just
Packit 292bd0
quote it (C<\{> or C<\}>). For single-quoted strings, you will need
Packit 292bd0
to make a comment matching it I<in th right order>.
Packit 292bd0
Sorry for the inconvenience.
Packit 292bd0
Packit 292bd0
    {
Packit 292bd0
        "{ My string block }".
Packit 292bd0
        "\{ My other string block \}".
Packit 292bd0
        qq/ My unmatched brace \} /.
Packit 292bd0
        # Force the match: {
Packit 292bd0
        q/ for my closing brace } /
Packit 292bd0
        q/ My opening brace { /
Packit 292bd0
        # must be closed: }
Packit 292bd0
    }
Packit 292bd0
Packit 292bd0
All of these constructs should work.
Packit 292bd0
Packit 292bd0
Packit 292bd0
In Parse::Yapp, semantic actions are called like normal Perl sub calls,
Packit 292bd0
with their arguments passed in C<@_>, and their semantic value are
Packit 292bd0
their return values.
Packit 292bd0
Packit 292bd0
$_[1] to $_[n] are the parameters just as $1 to $n in yacc, while
Packit 292bd0
$_[0] is the parser object itself.
Packit 292bd0
Packit 292bd0
Having $_[0] being the parser object itself allows you to call
Packit 292bd0
parser methods. That's how the yacc macros are implemented:
Packit 292bd0
Packit 292bd0
	yyerrok is done by calling $_[0]->YYErrok
Packit 292bd0
	YYERROR is done by calling $_[0]->YYError
Packit 292bd0
	YYACCEPT is done by calling $_[0]->YYAccept
Packit 292bd0
	YYABORT is done by calling $_[0]->YYAbort
Packit 292bd0
Packit 292bd0
All those methods explicitly return I<undef>, for convenience.
Packit 292bd0
Packit 292bd0
    YYRECOVERING is done by calling $_[0]->YYRecovering
Packit 292bd0
Packit 292bd0
Four useful methods in error recovery sub
Packit 292bd0
Packit 292bd0
    $_[0]->YYCurtok
Packit 292bd0
    $_[0]->YYCurval
Packit 292bd0
    $_[0]->YYExpect
Packit 292bd0
    $_[0]->YYLexer
Packit 292bd0
Packit 292bd0
return respectivly the current input token that made the parse fail,
Packit 292bd0
its semantic value (both can be used to modify their values too, but
Packit 292bd0
I<know what you are doing> ! See I<Error reporting routine> section for
Packit 292bd0
an example), a list which contains the tokens the parser expected when
Packit 292bd0
the failure occurred and a reference to the lexer routine.
Packit 292bd0
Packit 292bd0
Note that if C<$_[0]-E<gt>YYCurtok> is declared as a C<%nonassoc> token,
Packit 292bd0
it can be included in C<$_[0]-E<gt>YYExpect> list whenever the input
Packit 292bd0
try to use it in an associative way. This is not a bug: the token
Packit 292bd0
IS expected to report an error if encountered.
Packit 292bd0
Packit 292bd0
To detect such a thing in your error reporting sub, the following
Packit 292bd0
example should do the trick:
Packit 292bd0
Packit 292bd0
        grep { $_[0]->YYCurtok eq $_ } $_[0]->YYExpect
Packit 292bd0
    and do {
Packit 292bd0
        #Non-associative token used in an associative expression
Packit 292bd0
    };
Packit 292bd0
Packit 292bd0
Accessing semantics values on the left of your reducing rule is done
Packit 292bd0
through the method
Packit 292bd0
Packit 292bd0
    $_[0]->YYSemval( index )
Packit 292bd0
Packit 292bd0
where index is an integer. Its value being I<1 .. n> returns the same values
Packit 292bd0
than I<$_[1] .. $_[n]>, but I<-n .. 0> returns values on the left of the rule
Packit 292bd0
being reduced (It is related to I<$-n .. $0 .. $n> in yacc, but you
Packit 292bd0
cannot use I<$_[0]> or I<$_[-n]> constructs in Parse::Yapp for obvious reasons)
Packit 292bd0
Packit 292bd0
Packit 292bd0
There is also a provision for a user data area in the parser object,
Packit 292bd0
accessed by the method:
Packit 292bd0
Packit 292bd0
    $_[0]->YYData
Packit 292bd0
Packit 292bd0
which returns a reference to an anonymous hash, which let you have
Packit 292bd0
all of your parsing data held inside the object (see the Calc.yp
Packit 292bd0
or ParseYapp.yp files in the distribution for some examples).
Packit 292bd0
That's how you can make you parser module reentrant: all of your
Packit 292bd0
module states and variables are held inside the parser object.
Packit 292bd0
Packit 292bd0
Note: unfortunately, method calls in Perl have a lot of overhead,
Packit 292bd0
      and when YYData is used, it may be called a huge number
Packit 292bd0
      of times. If your are not a *real* purist and efficiency
Packit 292bd0
      is your concern, you may access directly the user-space
Packit 292bd0
      in the object: $parser->{USER} wich is a reference to an
Packit 292bd0
      anonymous hash array, and then benchmark.
Packit 292bd0
Packit 292bd0
If no action is specified for a rule, the equivalant of a default
Packit 292bd0
action is run, which returns the first parameter:
Packit 292bd0
Packit 292bd0
   { $_[1] }
Packit 292bd0
Packit 292bd0
=item C<In rule actions>
Packit 292bd0
Packit 292bd0
It is also possible to embed semantic actions inside of a rule:
Packit 292bd0
Packit 292bd0
    typedef:    TYPE { $type = $_[1] } identlist { ... } ;
Packit 292bd0
Packit 292bd0
When the Parse::Yapp's parser encounter such an embedded action, it modifies
Packit 292bd0
the grammar as if you wrote (although @x-1 is not a legal lhs value):
Packit 292bd0
Packit 292bd0
    @x-1:   /* empty */ { $type = $_[1] };
Packit 292bd0
    typedef:    TYPE @x-1 identlist { ... } ;
Packit 292bd0
Packit 292bd0
where I<x> is a sequential number incremented for each "in rule" action,
Packit 292bd0
and I<-1> represents the "dot position" in the rule where the action arises.
Packit 292bd0
Packit 292bd0
In such actions, you can use I<$_[1]..$_[n]> variables, which are the
Packit 292bd0
semantic values on the left of your action.
Packit 292bd0
Packit 292bd0
Be aware that the way Parse::Yapp modifies your grammar because of
Packit 292bd0
I<in rule actions> can produce, in some cases, spurious conflicts
Packit 292bd0
that wouldn't happen otherwise.  
Packit 292bd0
Packit 292bd0
=item C<Generating the Parser Module>
Packit 292bd0
Packit 292bd0
Now that you grammar file is written, you can use yapp on it
Packit 292bd0
to generate your parser module:
Packit 292bd0
Packit 292bd0
    yapp -v Calc.yp
Packit 292bd0
Packit 292bd0
will create two files F<Calc.pm>, your parser module, and F<Calc.output>
Packit 292bd0
a verbose output of your parser rules, conflicts, warnings, states
Packit 292bd0
and summary.
Packit 292bd0
Packit 292bd0
What your are missing now is a lexer routine.
Packit 292bd0
Packit 292bd0
=item C<The Lexer sub>
Packit 292bd0
Packit 292bd0
is called each time the parser need to read the next token.
Packit 292bd0
Packit 292bd0
It is called with only one argument that is the parser object itself,
Packit 292bd0
so you can access its methods, specially the
Packit 292bd0
Packit 292bd0
    $_[0]->YYData
Packit 292bd0
Packit 292bd0
data area.
Packit 292bd0
Packit 292bd0
It is its duty to return the next token and value to the parser.
Packit 292bd0
They C<must> be returned as a list of two variables, the first one
Packit 292bd0
is the token known by the parser (symbolic or literal), the second
Packit 292bd0
one being anything you want (usually the content of the token, or the
Packit 292bd0
literal value) from a simple scalar value to any complex reference,
Packit 292bd0
as the parsing driver never use it but to call semantic actions:
Packit 292bd0
Packit 292bd0
    ( 'NUMBER', $num )
Packit 292bd0
or
Packit 292bd0
    ( '>=', '>=' )
Packit 292bd0
or
Packit 292bd0
    ( 'ARRAY', [ @values ] )
Packit 292bd0
Packit 292bd0
When the lexer reach the end of input, it must return the C<''>
Packit 292bd0
empty token with an undef value:
Packit 292bd0
Packit 292bd0
     ( '', undef )
Packit 292bd0
Packit 292bd0
Note that your lexer should I<never> return C<'error'> as token
Packit 292bd0
value: for the driver, this is the error token used for error
Packit 292bd0
recovery and would lead to odd reactions.
Packit 292bd0
Packit 292bd0
Now that you have your lexer written, maybe you will need to output
Packit 292bd0
meaningful error messages, instead of the default which is to print
Packit 292bd0
'Parse error.' on STDERR.
Packit 292bd0
Packit 292bd0
So you will need an Error reporting sub.
Packit 292bd0
Packit 292bd0
=item C<Error reporting routine>
Packit 292bd0
Packit 292bd0
If you want one, write it knowing that it is passed as parameter
Packit 292bd0
the parser object. So you can share information with the lexer
Packit 292bd0
routine quite easily.
Packit 292bd0
Packit 292bd0
You can also use the C<$_[0]-E<gt>YYErrok> method in it, which will
Packit 292bd0
resume parsing as if no error occurred. Of course, since the invalid
Packit 292bd0
token is still invalid, you're supposed to fix the problem by
Packit 292bd0
yourself.
Packit 292bd0
Packit 292bd0
The method C<$_[0]-E<gt>YYLexer> may help you, as it returns a reference
Packit 292bd0
to the lexer routine, and can be called as
Packit 292bd0
Packit 292bd0
    ($tok,$val)=&{$_[0]->Lexer}
Packit 292bd0
Packit 292bd0
to get the next token and semantic value from the input stream. To
Packit 292bd0
make them current for the parser, use:
Packit 292bd0
Packit 292bd0
    ($_[0]->YYCurtok, $_[0]->YYCurval) = ($tok, $val)
Packit 292bd0
Packit 292bd0
and know what you're doing...
Packit 292bd0
Packit 292bd0
=item C<Parsing>
Packit 292bd0
Packit 292bd0
Now you've got everything to do the parsing.
Packit 292bd0
Packit 292bd0
First, use the parser module:
Packit 292bd0
Packit 292bd0
    use Calc;
Packit 292bd0
Packit 292bd0
Then create the parser object:
Packit 292bd0
Packit 292bd0
    $parser=new Calc;
Packit 292bd0
Packit 292bd0
Now, call the YYParse method, telling it where to find the lexer
Packit 292bd0
and error report subs:
Packit 292bd0
Packit 292bd0
    $result=$parser->YYParse(yylex => \&Lexer,
Packit 292bd0
                           yyerror => \&ErrorReport);
Packit 292bd0
Packit 292bd0
(assuming Lexer and ErrorReport subs have been written in your current
Packit 292bd0
package)
Packit 292bd0
Packit 292bd0
The order in which parameters appear is unimportant.
Packit 292bd0
Packit 292bd0
Et voila.
Packit 292bd0
Packit 292bd0
The YYParse method will do the parse, then return the last semantic
Packit 292bd0
value returned, or undef if error recovery cannot recover.
Packit 292bd0
Packit 292bd0
If you need to be sure the parse has been successful (in case your
Packit 292bd0
last returned semantic value I<is> undef) make a call to:
Packit 292bd0
Packit 292bd0
    $parser->YYNberr()
Packit 292bd0
Packit 292bd0
which returns the total number of time the error reporting sub has been called.
Packit 292bd0
Packit 292bd0
=item C<Error Recovery>
Packit 292bd0
Packit 292bd0
in Parse::Yapp is implemented the same way it is in yacc.
Packit 292bd0
Packit 292bd0
=item C<Debugging Parser>
Packit 292bd0
Packit 292bd0
To debug your parser, you can call the YYParse method with a debug parameter:
Packit 292bd0
Packit 292bd0
    $parser->YYParse( ... , yydebug => value, ... )
Packit 292bd0
Packit 292bd0
where value is a bitfield, each bit representing a specific debug output:
Packit 292bd0
Packit 292bd0
    Bit Value    Outputs
Packit 292bd0
    0x01         Token reading (useful for Lexer debugging)
Packit 292bd0
    0x02         States information
Packit 292bd0
    0x04         Driver actions (shifts, reduces, accept...)
Packit 292bd0
    0x08         Parse Stack dump
Packit 292bd0
    0x10         Error Recovery tracing
Packit 292bd0
Packit 292bd0
To have a full debugging output, use
Packit 292bd0
Packit 292bd0
    debug => 0x1F
Packit 292bd0
Packit 292bd0
Debugging output is sent to STDERR, and be aware that it can produce
Packit 292bd0
C<huge> outputs.
Packit 292bd0
Packit 292bd0
=item C<Standalone Parsers>
Packit 292bd0
Packit 292bd0
By default, the parser modules generated will need the Parse::Yapp
Packit 292bd0
module installed on the system to run. They use the Parse::Yapp::Driver
Packit 292bd0
which can be safely shared between parsers in the same script.
Packit 292bd0
Packit 292bd0
In the case you'd prefer to have a standalone module generated, use
Packit 292bd0
the C<-s> switch with yapp: this will automagically copy the driver
Packit 292bd0
code into your module so you can use/distribute it without the need
Packit 292bd0
of the Parse::Yapp module, making it really a C<Standalone Parser>.
Packit 292bd0
Packit 292bd0
If you do so, please remember to include Parse::Yapp's copyright notice
Packit 292bd0
in your main module copyright, so others can know about Parse::Yapp module.
Packit 292bd0
Packit 292bd0
=item C<Source file line numbers>
Packit 292bd0
Packit 292bd0
by default will be included in the generated parser module, which will help
Packit 292bd0
to find the guilty line in your source file in case of a syntax error.
Packit 292bd0
You can disable this feature by compiling your grammar with yapp using
Packit 292bd0
the C<-n> switch.
Packit 292bd0
Packit 292bd0
=back
Packit 292bd0
Packit 292bd0
=head1 BUGS AND SUGGESTIONS
Packit 292bd0
Packit 292bd0
If you find bugs, think of anything that could improve Parse::Yapp
Packit 292bd0
or have any questions related to it, feel free to contact the author.
Packit 292bd0
Packit 292bd0
=head1 AUTHOR
Packit 292bd0
Packit 292bd0
William N. Braswell, Jr. <wbraswell_cpan@NOSPAM.nym.hush.com>
Packit 292bd0
(Remove "NOSPAM".)
Packit 292bd0
Packit 292bd0
=head1 SEE ALSO
Packit 292bd0
Packit 292bd0
yapp(1) perl(1) yacc(1) bison(1).
Packit 292bd0
Packit 292bd0
=head1 COPYRIGHT
Packit 292bd0
Packit 292bd0
The Parse::Yapp module and its related modules and shell scripts are copyright:
Packit 292bd0
Copyright © 1998, 1999, 2000, 2001, Francois Desarmenien.
Packit 292bd0
Copyright © 2017 William N. Braswell, Jr.
Packit 292bd0
Packit 292bd0
You may use and distribute them under the terms of either
Packit 292bd0
the GNU General Public License or the Artistic License,
Packit 292bd0
as specified in the Perl README file.
Packit 292bd0
Packit 292bd0
If you use the "standalone parser" option so people don't need to install
Packit 292bd0
Parse::Yapp on their systems in order to run you software, this copyright
Packit 292bd0
noticed should be included in your software copyright too, and the copyright
Packit 292bd0
notice in the embedded driver should be left untouched.
Packit 292bd0
Packit 292bd0
=cut