#! /usr/bin/perl -w
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of Bison, the GNU Compiler Compiler.
#
=over 4
-=item I<fusion>
-
-Test F<lalr1.cc> with three stacks against F<lalr1-fusion.cc> which
-uses a single one.
-
=item I<push>
Test the push parser vs. the pull interface. Use the C parser.
or die;
print $out <<EOF;
%error-verbose
-%debug
%{
#include <stdio.h>
#include <stdlib.h>
int
main (void)
{
+#if YYDEBUG
yydebug = !!getenv ("YYDEBUG");
+#endif
return yyparse ();
}
EOF
int count = 0;
int status;
+#if YYDEBUG
+ yydebug = !!getenv ("YYDEBUG");
+#endif
+
input = fopen ("calc.input", "r");
if (!input)
{
my ($base, $max, @directive) = @_;
my $directives = directives ($base, @directive);
my $variant = grep { /%define "?variant"?/ } @directive;
+ my $lex_symbol = grep { /%define "?lex_symbol"?/ } @directive;
my $out = new IO::File ">$base.y"
or die;
print $out <<EOF;
%language "C++"
%defines
+%locations
$directives
%code requires // *.h
#include <iostream>
#include <sstream>
-// Prototype of the yylex function providing subsequent tokens.
-static yy::parser::token_type yylex(yy::parser::semantic_type* yylval);
-
#define STAGE_MAX ($max * 10) // max = $max
+#define USE_LEX_SYMBOL $lex_symbol
#define USE_VARIANTS $variant
-#if USE_VARIANTS
-# define IF_VARIANTS(True, False) True
-#else
-# define IF_VARIANTS(True, False) False
-#endif
-#ifdef ONE_STAGE_BUILD
-# define IF_ONE_STAGE_BUILD(True, False) True
+ // Prototype of the yylex function providing subsequent tokens.
+ static
+#if USE_LEX_SYMBOL
+ yy::parser::symbol_type yylex();
#else
-# define IF_ONE_STAGE_BUILD(True, False) False
+ yy::parser::token_type yylex(yy::parser::semantic_type* yylval,
+ yy::parser::location_type* yylloc);
#endif
// Conversion to string.
return o.str ();
}
}
+
+%token END_OF_FILE 0
EOF
if ($variant)
%token <int> NUMBER
%printer { std::cerr << "Number: " << $$; } <int>
%printer { std::cerr << "Text: " << $$; } <std::string>
-%token END_OF_FILE 0
%type <std::string> text result
%%
%token <ival> NUMBER
%printer { std::cerr << "Number: " << $$; } <ival>
%printer { std::cerr << "Text: " << *$$; } <sval>
-%token END_OF_FILE 0
%type <sval> text result
%%
print $out <<'EOF';
%%
+#
+
static
-yy::parser::token_type
-yylex(yy::parser::semantic_type* yylval)
+#if USE_LEX_SYMBOL
+yy::parser::symbol_type yylex()
+#else
+yy::parser::token_type yylex(yy::parser::semantic_type* yylval,
+ yy::parser::location_type* yylloc)
+#endif
{
+ typedef yy::parser::location_type location_type;
+ typedef yy::parser::token token;
static int stage = -1;
++stage;
if (stage == STAGE_MAX)
- return yy::parser::token::END_OF_FILE;
+ {
+#if USE_LEX_SYMBOL
+ return yy::parser::make_END_OF_FILE (location_type ());
+#else
+ *yylloc = location_type ();
+ return token::END_OF_FILE;
+#endif
+ }
else if (stage % 2)
{
-#if USE_VARIANTS
-# ifdef ONE_STAGE_BUILD
+#if USE_LEX_SYMBOL
+ return yy::parser::make_NUMBER (stage, location_type ());
+#else
+# if defined ONE_STAGE_BUILD
yylval->build(stage);
-# else
+# elif USE_VARIANTS
yylval->build<int>() = stage;
-# endif
-#else
+# else
yylval->ival = stage;
+# endif
+ *yylloc = location_type ();
+ return token::NUMBER;
#endif
- return yy::parser::token::NUMBER;
}
else
{
-#if USE_VARIANTS
-# ifdef ONE_STAGE_BUILD
+#if USE_LEX_SYMBOL
+ return yy::parser::make_TEXT ("A string.", location_type ());
+#else
+# if defined ONE_STAGE_BUILD
yylval->build(std::string("A string."));
-# else
+# elif USE_VARIANTS
yylval->build<std::string>() = std::string("A string.");
-# endif
-#else
+# else
yylval->sval = new std::string("A string.");
+# endif
+ *yylloc = location_type ();
+ return token::TEXT;
#endif
- return yy::parser::token::TEXT;
}
abort();
}
// Mandatory error function
void
-yy::parser::error(const yy::parser::location_type& yylloc,
- const std::string& message)
+yy::parser::error(const yy::parser::location_type& loc, const std::string& msg)
{
- std::cerr << yylloc << ": " << message << std::endl;
+ std::cerr << loc << ": " << msg << std::endl;
}
int main(int argc, char *argv[])
qw(
[ %d api.pure ]
&
- [ %d api.push_pull=both ]
+ [ %d api.push-pull=both ]
));
}
=item C<bench_variant_parser ()>
-Bench the C++ lalr1.cc parser using Boost.Variants or %union.
+Bench the C++ lalr1.cc parser using variants or %union.
=cut
{
bench ('list',
qw(
- [ %debug ]
- &
- [ %d variant
- &
- [ #d VARIANT_DESTROY ]
+ [
+ %d variant
&
- [ #d ONE_STAGE_BUILD ]
+ [ #d ONE_STAGE_BUILD | %d lex_symbol ]
]
)
);
}
-######################################################################
-
-=item C<bench_fusion_parser ()>
-
-Bench the C++ lalr1.cc parser using Boost.Variants or %union.
-
-=cut
-
-sub bench_fusion_parser ()
-{
- bench ('list',
- qw(
- %s lalr1-split.cc
- |
- %s lalr1.cc
- )
- );
-}
-
############################################################################
sub help ($)
{
for my $lhs (@lhs)
{
- push @res, "$lhs\n$rhs";
+ push @res, $lhs . ($lhs && $rhs ? "\n" : "") . $rhs;
}
}
}
# Support -b: predefined benches.
my %bench =
(
- "fusion" => \&bench_fusion_parser,
"push" => \&bench_push_parser,
"variant" => \&bench_variant_parser,
);