Blame yapp

Packit 292bd0
#!/usr/bin/perl
Packit 292bd0
#
Packit 292bd0
# yapp -- Front end to the Parse::Yapp module
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
# (see the pod text in Parse::Yapp module for use and distribution rights)
Packit 292bd0
#
Packit 292bd0
#
Packit 292bd0
Packit 292bd0
=encoding UTF-8
Packit 292bd0
Packit 292bd0
=head1 NAME
Packit 292bd0
Packit 292bd0
yapp - A perl frontend to the Parse::Yapp module
Packit 292bd0
Packit 292bd0
Packit 292bd0
=head1 SYNOPSYS
Packit 292bd0
Packit 292bd0
yapp [options] I<grammar>[.yp]
Packit 292bd0
Packit 292bd0
yapp I<-V>
Packit 292bd0
Packit 292bd0
yapp I<-h>
Packit 292bd0
Packit 292bd0
Packit 292bd0
=head1 DESCRIPTION
Packit 292bd0
Packit 292bd0
yapp is a frontend to the Parse::Yapp module, which lets you compile
Packit 292bd0
Parse::Yapp grammar input files into Perl LALR(1) OO parser modules.
Packit 292bd0
Packit 292bd0
Packit 292bd0
=head1 OPTIONS
Packit 292bd0
Packit 292bd0
Options, as of today, are all optionals :-)
Packit 292bd0
Packit 292bd0
=over 4
Packit 292bd0
Packit 292bd0
=item I<-v>
Packit 292bd0
Packit 292bd0
Creates a file F<grammar>.output describing your parser. It will
Packit 292bd0
show you a summary of conflicts, rules, the DFA (Deterministic
Packit 292bd0
Finite Automaton) states and overall usage of the parser.
Packit 292bd0
Packit 292bd0
=item I<-s>
Packit 292bd0
Packit 292bd0
Create a standalone module in which the driver is included.
Packit 292bd0
Note that if you have more than one parser module called from
Packit 292bd0
a program, to have it standalone, you need this option only
Packit 292bd0
for one of your parser module.
Packit 292bd0
Packit 292bd0
=item I<-n>
Packit 292bd0
Packit 292bd0
Disable source file line numbering embedded in your parser module.
Packit 292bd0
I don't know why one should need it, but it's there.
Packit 292bd0
Packit 292bd0
=item I<-m module>
Packit 292bd0
Packit 292bd0
Gives your parser module the package name (or name space or module name or
Packit 292bd0
class name or whatever-you-call-it) of F<module>.  It defaults to F<grammar>
Packit 292bd0
Packit 292bd0
=item I<-o outfile>
Packit 292bd0
Packit 292bd0
The compiled output file will be named F<outfile> for your parser module.
Packit 292bd0
It defaults to F<grammar>.pm or, if you specified the option
Packit 292bd0
I<-m A::Module::Name> (see below), to F<Name.pm>, in the current
Packit 292bd0
working directory.
Packit 292bd0
Packit 292bd0
=item I<-t filename>
Packit 292bd0
Packit 292bd0
The I<-t filename> option allows you to specify a file which should be 
Packit 292bd0
used as template for generating the parser output.  The default is to 
Packit 292bd0
use the internal template defined in F<Parse::Yapp::Output.pm>.
Packit 292bd0
For how to write your own template and which substitutions are available,
Packit 292bd0
have a look to the module F<Parse::Yapp::Output.pm> : it should be obvious. 
Packit 292bd0
Packit 292bd0
=item I<-b shebang>
Packit 292bd0
Packit 292bd0
If you work on systems that understand so called I<shebangs>, and your
Packit 292bd0
generated parser is directly an executable script, you can specifie one
Packit 292bd0
with the I<-b> option, ie:
Packit 292bd0
Packit 292bd0
    yapp -b '/usr/local/bin/perl -w' -o myscript.pl myscript.yp
Packit 292bd0
Packit 292bd0
This will output a file called F<myscript.pl> whose very first line is:
Packit 292bd0
Packit 292bd0
    #!/usr/local/bin/perl -w
Packit 292bd0
Packit 292bd0
The argument is mandatory, but if you specify an empty string, the value
Packit 292bd0
of I<$Config{perlpath}> will be used instead.
Packit 292bd0
Packit 292bd0
=item I<grammar>
Packit 292bd0
Packit 292bd0
The input grammar file. If no suffix is given, and the file does not exists,
Packit 292bd0
an attempt to open the file with a suffix of  F<.yp> is tried before exiting.
Packit 292bd0
Packit 292bd0
=item I<-V>
Packit 292bd0
Packit 292bd0
Display current version of Parse::Yapp and gracefully exits.
Packit 292bd0
Packit 292bd0
=item I<-h>
Packit 292bd0
Packit 292bd0
Display the usage screen.
Packit 292bd0
Packit 292bd0
=back
Packit 292bd0
Packit 292bd0
=head1 BUGS
Packit 292bd0
Packit 292bd0
None known now :-)
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 COPYRIGHT
Packit 292bd0
Packit 292bd0
Copyright © 1998, 1999, 2000, 2001, Francois Desarmenien.
Packit 292bd0
Copyright © 2017 William N. Braswell, Jr.
Packit 292bd0
Packit 292bd0
See Parse::Yapp(3) for legal use and distribution rights
Packit 292bd0
Packit 292bd0
=head1 SEE ALSO
Packit 292bd0
Packit 292bd0
Parse::Yapp(3) Perl(1) yacc(1) bison(1)
Packit 292bd0
Packit 292bd0
Packit 292bd0
=cut
Packit 292bd0
Packit 292bd0
require 5.004;
Packit 292bd0
Packit 292bd0
use File::Basename;
Packit 292bd0
use Getopt::Std;
Packit 292bd0
use Config;
Packit 292bd0
use Parse::Yapp;
Packit 292bd0
Packit 292bd0
use strict;
Packit 292bd0
Packit 292bd0
use vars qw ( $opt_n $opt_m $opt_V $opt_v $opt_o $opt_h $opt_s $opt_t $opt_b);
Packit 292bd0
Packit 292bd0
sub Usage {
Packit 292bd0
	my($prog)=(fileparse($0,'\..*'))[0];
Packit 292bd0
	die <
Packit 292bd0
Packit 292bd0
Usage:	$prog [options] grammar[.yp]
Packit 292bd0
  or	$prog -V
Packit 292bd0
  or	$prog -h
Packit 292bd0
Packit 292bd0
    -m module   Give your parser module the name <module>
Packit 292bd0
                default is <grammar>
Packit 292bd0
    -v          Create a file <grammar>.output describing your parser
Packit 292bd0
    -s          Create a standalone module in which the driver is included
Packit 292bd0
    -n          Disable source file line numbering embedded in your parser
Packit 292bd0
    -o outfile  Create the file <outfile> for your parser module
Packit 292bd0
                Default is <grammar>.pm or, if -m A::Module::Name is
Packit 292bd0
                specified, Name.pm
Packit 292bd0
    -t filename Uses the file <filename> as a template for creating the parser
Packit 292bd0
                module file.  Default is to use internal template defined
Packit 292bd0
                in Parse::Yapp::Output
Packit 292bd0
    -b shebang  Adds '#!<shebang>' as the very first line of the output file
Packit 292bd0
Packit 292bd0
    grammar     The grammar file. If no suffix is given, and the file
Packit 292bd0
                does not exists, .yp is added
Packit 292bd0
Packit 292bd0
    -V          Display current version of Parse::Yapp and gracefully exits
Packit 292bd0
    -h          Display this help screen
Packit 292bd0
Packit 292bd0
EOF
Packit 292bd0
}
Packit 292bd0
Packit 292bd0
my($nbargs)=@ARGV;
Packit 292bd0
Packit 292bd0
	getopts('Vhvsnb:m:t:o:')
Packit 292bd0
or	Usage;
Packit 292bd0
Packit 292bd0
   (  ($opt_V and $nbargs > 1)
Packit 292bd0
    or $opt_h)
Packit 292bd0
and Usage;
Packit 292bd0
Packit 292bd0
	$opt_V
Packit 292bd0
and do {
Packit 292bd0
Packit 292bd0
    @ARGV == 0 or  Usage;
Packit 292bd0
Packit 292bd0
    print "This is Parse::Yapp version $Parse::Yapp::Driver::VERSION.\n";
Packit 292bd0
    exit(0);
Packit 292bd0
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
Packit 292bd0
# -t <filename> ($opt_t) option allows a file to be specified which 
Packit 292bd0
# contains a 'template' to be used when generating the parser; 
Packit 292bd0
# if defined, we open and read the file.   
Packit 292bd0
Packit 292bd0
	$opt_t
Packit 292bd0
and do {
Packit 292bd0
    local $/ = undef;
Packit 292bd0
    local *TFILE;
Packit 292bd0
    open(TFILE, $opt_t)
Packit 292bd0
	or die "Cannot open template file $opt_t: $!\n";
Packit 292bd0
    $opt_t = <TFILE>;
Packit 292bd0
    close(TFILE);
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
    @ARGV == 1
Packit 292bd0
or  Usage;
Packit 292bd0
Packit 292bd0
my($filename)=$ARGV[0];
Packit 292bd0
my($base,$path,$sfx)=fileparse($filename,'\..*');
Packit 292bd0
Packit 292bd0
	-r "$filename"
Packit 292bd0
or	do {
Packit 292bd0
		$sfx eq '.yp'
Packit 292bd0
	or	$filename.='.yp';
Packit 292bd0
Packit 292bd0
		-r "$filename"
Packit 292bd0
	or	die "Cannot open $filename for reading.\n";
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
my($parser)=new Parse::Yapp(inputfile => $filename);
Packit 292bd0
Packit 292bd0
my($warnings)=$parser->Warnings();
Packit 292bd0
Packit 292bd0
	$warnings
Packit 292bd0
and	print STDERR $warnings;
Packit 292bd0
Packit 292bd0
	$opt_v
Packit 292bd0
and	do {
Packit 292bd0
	my($output)="$path$base.output";
Packit 292bd0
	my($tmp);
Packit 292bd0
Packit 292bd0
		open(OUT,">$output")
Packit 292bd0
	or	die "Cannot create $base.output for writing.\n";
Packit 292bd0
Packit 292bd0
		$tmp=$parser->Warnings()
Packit 292bd0
	and	print	OUT "Warnings:\n---------\n$tmp\n";
Packit 292bd0
		$tmp=$parser->Conflicts()
Packit 292bd0
	and	print	OUT "Conflicts:\n----------\n$tmp\n";
Packit 292bd0
	print	OUT "Rules:\n------\n";
Packit 292bd0
	print	OUT $parser->ShowRules()."\n";
Packit 292bd0
	print	OUT "States:\n-------\n";
Packit 292bd0
	print	OUT $parser->ShowDfa()."\n";
Packit 292bd0
	print	OUT "Summary:\n--------\n";
Packit 292bd0
	print	OUT $parser->Summary();
Packit 292bd0
Packit 292bd0
	close(OUT);
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
my($outfile)="$path$base.pm";
Packit 292bd0
my($package)="$base";
Packit 292bd0
Packit 292bd0
	$opt_m
Packit 292bd0
and	do {
Packit 292bd0
    $package=$opt_m;
Packit 292bd0
    $package=~/^(?:(?:[^:]|:(?!:))*::)*(.*)$/;
Packit 292bd0
    $outfile="$1.pm";
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
	$opt_o
Packit 292bd0
and	$outfile=$opt_o;
Packit 292bd0
Packit 292bd0
$opt_s = $opt_s ? 1 : 0;
Packit 292bd0
Packit 292bd0
$opt_n = $opt_n ? 0 : 1;
Packit 292bd0
Packit 292bd0
	open(OUT,">$outfile")
Packit 292bd0
or	die "Cannot open $outfile for writing.\n";
Packit 292bd0
Packit 292bd0
    defined($opt_b)
Packit 292bd0
and do {
Packit 292bd0
        $opt_b
Packit 292bd0
    or  $opt_b = $Config{perlpath};
Packit 292bd0
    print OUT "#!$opt_b\n";
Packit 292bd0
};
Packit 292bd0
Packit 292bd0
print OUT $parser->Output(classname  => $package,
Packit 292bd0
                          standalone => $opt_s,
Packit 292bd0
                          linenumbers => $opt_n,
Packit 292bd0
                          template    => $opt_t,
Packit 292bd0
                         );
Packit 292bd0
Packit 292bd0
Packit 292bd0
close(OUT);
Packit 292bd0