|
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 |
|