X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/2e7944cbb21e10c130192f733abc1af5cd8b6eb7..7484f1d4f3a173a2d8a5f08b8b561d31118c29e1:/etc/bench.pl.in diff --git a/etc/bench.pl.in b/etc/bench.pl.in index d7d258d8..87bb53bc 100755 --- a/etc/bench.pl.in +++ b/etc/bench.pl.in @@ -1,24 +1,32 @@ #! /usr/bin/perl -w -# Copyright (C) 2006 Free Software Foundation, Inc. -# +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# # This file is part of Bison, the GNU Compiler Compiler. -# -# Bison is free software; you can redistribute it and/or modify +# +# This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# Bison is distributed in the hope that it will be useful, +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License -# along with autoconf; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. - +# along with this program. If not, see . + +=head1 NAME + +bench.pl - perform benches on Bison parsers. + +=head1 SYNOPSIS + + ./bench.pl + +=cut + use IO::File; use Benchmark qw (:all); @@ -27,6 +35,36 @@ my $cc = $ENV{'CC'} || 'gcc'; ################################################################## +=head2 Functions + +=over 4 + +=item C + +Create a large triangular grammar which looks like : + + input: + exp { if ($1 != 0) abort (); $$ = $1; } + | input exp { if ($2 != $1 + 1) abort (); $$ = $2; } + ; + + exp: + END { $$ = 0; } + | "1" END { $$ = 1; } + | "1" "2" END { $$ = 2; } + | "1" "2" "3" END { $$ = 3; } + | "1" "2" "3" "4" END { $$ = 4; } + | "1" "2" "3" "4" "5" END { $$ = 5; } + ; + +C<$base> is the base name for the file to create (C<$base.y>). +C<$max> is the number of such rules (here, 5). You may pass +additional Bison C<$directives>. + +The created parser is self contained: it includes its scanner, and +source of input. +=cut + sub triangular_grammar ($$$) { my ($base, $max, $directives) = @_; @@ -114,6 +152,15 @@ EOF ################################################################## +=item C + +Generate the input file C<$base.input> for the calc parser. The input +is composed of two expressions. The first one is using left recursion +only and consumes no stack. The second one requires a deep stack. +These two expressions are repeated C<$max> times in the output file. + +=cut + sub calc_input ($$) { my ($base, $max) = @_; @@ -127,6 +174,13 @@ sub calc_input ($$) } ################################################################## +=item C + +Generate a Bison file C<$base.y> that for a calculator parser in C. +Pass the additional Bison C<$directives>. C<$max> is ignored, but +left to have the same interface as C. + +=cut sub calc_grammar ($$$) { @@ -272,9 +326,7 @@ yylex (void) /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') - { - - } + continue; /* process numbers */ if (c == '.' || isdigit (c)) @@ -331,6 +383,12 @@ EOF ################################################################## +=item C + +Compile C<$base.y> to an executable C<$base> using the C compiler. + +=cut + sub compile ($) { my ($base) = @_; @@ -340,23 +398,29 @@ sub compile ($) or die; } -sub bench_grammar ($) +=item C + +Generate benches for C<$gram>. C<$gram> should be C or +C. C<%bench> is a hash of the form: + + C<$name> => C<$directives> + +where C<$name> is the name of the bench, and C<$directives> are the +Bison directive to use for this bench. All the benches are compared +against each other, repeated 50 times. + +=cut + +sub bench_grammar ($%) { - my ($gram) = @_; - my %test = - ( - "yacc.c-pull-impure" => '', - "yacc.c-pull-pure" => '%pure-parser', - "push.c-pull-impure" => '%skeleton "push.c"', - "push.c-pull-pure" => '%skeleton "push.c" %pure-parser', - "push.c-push-impure" => '%skeleton "push.c" %push-parser', - "push.c-push-pure" => '%skeleton "push.c" %push-parser %pure-parser', - ); - + my ($gram, %test) = @_; + + # Set up the benches as expected by timethese. my %bench; while (my ($name, $directives) = each %test) { print STDERR "$name\n"; + # Call the Bison input file generator. my $generator = "$gram" . "_grammar"; &$generator ($name, 200, $directives); compile ($name); @@ -364,13 +428,36 @@ sub bench_grammar ($) } print "$gram:\n"; + # Run the benches. my $res = timethese (50, \%bench, 'nop'); + # Output the result. cmpthese ($res, 'nop'); } -print STDERR "Using $bison, $cc.\n"; -calc_input ('calc', 200); -bench_grammar ('calc'); + +=item C + +Bench the C push parser against the pull parser, pure and impure +interfaces. + +=cut + +sub bench_push_parser () +{ + print STDERR "Using $bison, $cc.\n"; + calc_input ('calc', 200); + bench_grammar + ('calc', + ( + "pull-impure" => '', + "pull-pure" => '%define api.pure', + "push-impure" => '%define api.push_pull "both"', + "push-pure" => '%define api.push_pull "both" %define api.pure', + ) + ); +} + +bench_push_parser(); ### Setup "GNU" style for perl-mode and cperl-mode. ## Local Variables: