+######################################################################
+
+=item C<bench_push_parser ()>
+
+Bench the C push parser against the pull parser, pure and impure
+interfaces.
+
+=cut
+
+sub bench_push_parser ()
+{
+ 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'],
+ )
+ );
+}
+
+######################################################################
+
+=item C<bench_variant_parser ()>
+
+Bench the C++ lalr1.cc parser using Boost.Variants or %union.
+
+=cut
+
+sub bench_variant_parser ()
+{
+ bench_grammar
+ ('variant',
+ (
+ "f-union" => ['%skeleton "lalr1.cc"'],
+ "f-uni-deb" => ['%skeleton "lalr1.cc"', '%debug'],
+ "f-var" => ['%skeleton "lalr1.cc"', '%define variant'],
+ "f-var-deb" => ['%skeleton "lalr1.cc"', '%debug', '%define variant'],
+ "f-var-dtr" => ['%skeleton "lalr1.cc"', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"],
+ "f-var-deb-dtr" => ['%skeleton "lalr1.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"],
+ "f-var-deb-dtr-ass" => ['%skeleton "lalr1.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}", "%define assert"],
+ )
+ );
+}
+
+######################################################################
+
+=item C<bench_fusion_parser ()>
+
+Bench the C++ lalr1.cc parser using Boost.Variants or %union.
+
+=cut
+
+sub bench_fusion_parser ()
+{
+ bench_grammar
+ ('variant',
+ (
+ "split" => ['%skeleton "lalr1-split.cc"'],
+ "fused" => ['%skeleton "lalr1.cc"'],
+ )
+ );
+}
+
+############################################################################
+
+sub help ($)
+{
+ my ($verbose) = @_;
+ use Pod::Usage;
+ # See <URL:http://perldoc.perl.org/pod2man.html#NOTES>.
+ pod2usage( { -message => "Bench Bison parsers",
+ -exitval => 0,
+ -verbose => $verbose,
+ -output => \*STDOUT });
+}
+
+######################################################################
+
+sub getopt ()
+{
+ use Getopt::Long;
+ my %option = (
+ "c|cflags=s" => \$cflags,
+ "h|help" => sub { help ($verbose) },
+ "i|iterations=i" => \$iterations,
+ "q|quiet" => sub { --$verbose },
+ "v|verbose" => sub { ++$verbose },
+ );
+ Getopt::Long::Configure ("bundling", "pass_through");
+ GetOptions (%option)
+ or exit 1;
+}
+
+######################################################################
+
+getopt;
+verbose 1, "Using bison=$bison.\n";
+verbose 1, "Using cc=$cc.\n";
+verbose 1, "Using cxx=$cxx.\n";
+verbose 1, "Using cflags=$cflags.\n";
+
+for my $b (@ARGV)
+{
+ verbose 1, "Running benchmark $b.\n";
+ bench_fusion_parser() if $b eq "fusion";
+ bench_push_parser() if $b eq "push";
+ bench_variant_parser() if $b eq "variant";
+}