#! /usr/bin/perl -w
-# Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc.
#
# This file is part of Bison, the GNU Compiler Compiler.
#
| directives & directives -- Concatenation
| [ directives> ] -- Optional
| ( directives> ) -- Parentheses
+ | %b PATH -- Use bison at PATH for this bench
| #d NAME[=VALUE] -- %code { #define NAME [VALUE] }
| %d NAME[=VALUE] -- %define NAME ["VALUE"]
| %s skeleton -- %skeleton "skeleton"
sub directives($@)
{
my ($bench, @directive) = @_;
- my $res = "/* Directives for bench `$bench'. */\n";
+ my $res = "/* Directives for bench '$bench'. */\n";
$res .= join ("\n", @directive) . "\n";
- $res .= "/* End of directives for bench `$bench'. */\n";
+ $res .= "/* End of directives for bench '$bench'. */\n";
return $res;
}
or die;
print $out <<EOF;
%error-verbose
-%debug
%{
#include <stdio.h>
#include <stdlib.h>
{
use Text::Wrap;
print $out wrap ("| ", " ",
- (map { "\"$_\"" } (1 .. $size)),
- " END \n"),
+ (map { "\"$_\"" } (1 .. $size)),
+ " END \n"),
" { \$\$ = $size; }\n";
};
print $out ";\n";
int
main (void)
{
+#if YYDEBUG
yydebug = !!getenv ("YYDEBUG");
+#endif
return yyparse ();
}
EOF
or die;
print $out <<EOF;
%{
+#include <assert.h>
#include <stdio.h>
-
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
%token <ival> NUM "number"
%type <ival> exp
-%nonassoc '=' /* comparison */
+%nonassoc '=' /* comparison */
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
static int
power (int base, int exponent)
{
+ assert (0 <= exponent);
int res = 1;
- if (exponent < 0)
- exit (3);
for (/* Niente */; exponent; --exponent)
res *= base;
return res;
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 $token_ctor = grep { /%define "?api.token.constructor"?/ } @directive;
my $out = new IO::File ">$base.y"
or die;
print $out <<EOF;
#define STAGE_MAX ($max * 10) // max = $max
-#define USE_LEX_SYMBOL $lex_symbol
+#define USE_TOKEN_CTOR $token_ctor
#define USE_VARIANTS $variant
// Prototype of the yylex function providing subsequent tokens.
static
-#if USE_LEX_SYMBOL
+#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex();
#else
- yy::parser::token_type yylex(yy::parser::semantic_type* yylval,
- yy::parser::location_type* yylloc);
+ yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
+ yy::parser::location_type* yyllocp);
#endif
// Conversion to string.
%%
result:
- text { /* Throw away the result. */ }
+ text { /* Throw away the result. */ }
;
text:
- /* nothing */ { /* This will generate an empty string */ }
-| text TEXT { std::swap ($$, $2); }
-| text NUMBER { $$ = string_cast($2); }
+ /* nothing */ { /* This will generate an empty string */ }
+| text TEXT { std::swap ($$, $2); }
+| text NUMBER { $$ = string_cast($2); }
;
EOF
}
%%
result:
- text { delete $1; }
+ text { delete $1; }
;
text:
- /* nothing */ { $$ = new std::string; }
-| text TEXT { delete $1; $$ = $2; }
-| text NUMBER { delete $1; $$ = new std::string (string_cast ($2)); }
+ /* nothing */ { $$ = new std::string; }
+| text TEXT { delete $1; $$ = $2; }
+| text NUMBER { delete $1; $$ = new std::string (string_cast ($2)); }
;
EOF
}
#
static
-#if USE_LEX_SYMBOL
+#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex()
#else
-yy::parser::token_type yylex(yy::parser::semantic_type* yylval,
- yy::parser::location_type* yylloc)
+yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
+ yy::parser::location_type* yyllocp)
#endif
{
typedef yy::parser::location_type location_type;
++stage;
if (stage == STAGE_MAX)
{
-#if USE_LEX_SYMBOL
+#if USE_TOKEN_CTOR
return yy::parser::make_END_OF_FILE (location_type ());
#else
- *yylloc = location_type ();
+ *yyllocp = location_type ();
return token::END_OF_FILE;
#endif
}
else if (stage % 2)
{
-#if USE_LEX_SYMBOL
+#if USE_TOKEN_CTOR
return yy::parser::make_NUMBER (stage, location_type ());
#else
# if defined ONE_STAGE_BUILD
- yylval->build(stage);
+ yylvalp->build(stage);
# elif USE_VARIANTS
- yylval->build<int>() = stage;
+ yylvalp->build<int>() = stage;
# else
- yylval->ival = stage;
+ yylvalp->ival = stage;
# endif
- *yylloc = location_type ();
+ *yyllocp = location_type ();
return token::NUMBER;
#endif
}
else
{
-#if USE_LEX_SYMBOL
+#if USE_TOKEN_CTOR
return yy::parser::make_TEXT ("A string.", location_type ());
#else
# if defined ONE_STAGE_BUILD
- yylval->build(std::string("A string."));
+ yylvalp->build(std::string("A string."));
# elif USE_VARIANTS
- yylval->build<std::string>() = std::string("A string.");
+ yylvalp->build<std::string>() = std::string("A string.");
# else
- yylval->sval = new std::string("A string.");
+ yylvalp->sval = new std::string("A string.");
# endif
- *yylloc = location_type ();
+ *yyllocp = location_type ();
return token::TEXT;
#endif
}
my $compiler = $language eq 'C++' ? $cxx : $cc;
- run "$bison $base.y -o $base.c";
+ my $my_bison = `sed -ne '/%bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
+ run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
run "$compiler -o $base $cflags $base.c";
}
[
%d variant
&
- [ #d ONE_STAGE_BUILD | %d lex_symbol ]
+ [ #d ONE_STAGE_BUILD | %d api.token.constructor ]
]
)
);
@res = ("%skeleton \"$token[0]\"");
shift @token;
}
+ elsif ($token[0] eq '%b')
+ {
+ shift @token;
+ @res = ("/*\n%bison \"$token[0]\"\\\n*/");
+ shift @token;
+ }
else
{
@res = $token[0];