* etc/bench.pl.in (parse_dirs): Support %d and #d with arguments.
(&bench_push_parser, bench_variant_parser): Use this feature.
(&eat): New.
Use it.
+2008-11-11 Akim Demaille <demaille@gostai.com>
+
+ Bench: syntactic sugar for %define/#define.
+ * etc/bench.pl.in (parse_dirs): Support %d and #d with arguments.
+ (&bench_push_parser, bench_variant_parser): Use this feature.
+ (&eat): New.
+ Use it.
+
2008-11-11 Akim Demaille <demaille@gostai.com>
Less memory pressure on the "list" bench.
2008-11-11 Akim Demaille <demaille@gostai.com>
Less memory pressure on the "list" bench.
| directives & directives -- Concatenation
| [ directives> ] -- Optional
| ( directives> ) -- Parentheses
| directives & directives -- Concatenation
| [ directives> ] -- Optional
| ( directives> ) -- Parentheses
+ | #d NAME[=VALUE] -- %code { #define NAME [VALUE] }
+ | %d NAME[=VALUE] -- %define NAME ["VALUE"]
| %s skeleton -- %skeleton "skeleton"
| %s skeleton -- %skeleton "skeleton"
- | #d definition -- %code { #define definition }
| directive
Parentheses only group to override precedence. For instance:
| directive
Parentheses only group to override precedence. For instance:
sub bench_push_parser ()
{
bench ('calc',
sub bench_push_parser ()
{
bench ('calc',
- (
- '[', '%define api.pure', ']',
- '&',
- '[', '%define api.push_pull "both"', ']'
+ qw(
+ [ %d api.pure ]
+ &
+ [ %d api.push_pull=both ]
&
[ #d VARIANT_DESTROY ]
&
&
[ #d VARIANT_DESTROY ]
&
######################################################################
######################################################################
+# The end of the directives to parse.
+my $eod = "end of directives";
# The list of tokens parsed by the following functions.
my @token;
# The list of tokens parsed by the following functions.
my @token;
+# eat ($EXPECTED)
+# ---------------
+# Check that the current token is $EXPECTED, and move to the next.
+sub eat ($)
+{
+ my ($expected) = @_;
+ die "expected $expected, unexpected: $token[0] (@token)\n"
+ unless $token[0] eq $expected;
+ shift @token;
+}
+
# Parse directive specifications:
# expr: term (| term)*
# term: fact (& fact)*
# fact: ( expr ) | [ expr ] | dirs
# Parse directive specifications:
# expr: term (| term)*
# term: fact (& fact)*
# fact: ( expr ) | [ expr ] | dirs
-# dirs: %s SKELETON | #d DEFINE | directive
+# dirs: %s SKELETON | #d NAME[=VALUE] | %d NAME[=VALUE] | directive
verbose 3, "Parsing: @token\n";
my @res = parse_expr ();
verbose 3, "Parsing: @token\n";
my @res = parse_expr ();
- die "expected end of directives, unexpected: @token"
- if defined $token[0];
return @res;
}
sub parse_expr ()
{
my @res = parse_term ();
return @res;
}
sub parse_expr ()
{
my @res = parse_term ();
- while (defined $token[0] && $token[0] eq '|')
+ while ($token[0] eq '|')
# Alternation.
push @res, parse_term ();
}
# Alternation.
push @res, parse_term ();
}
sub parse_term ()
{
my @res = parse_fact ();
sub parse_term ()
{
my @res = parse_fact ();
- while (defined $token[0] && $token[0] eq '&')
+ while ($token[0] eq '&')
# Cartesian product.
my @lhs = @res;
@res = ();
# Cartesian product.
my @lhs = @res;
@res = ();
- die "unexpected $token[0], expected )"
- unless $token[0] eq ')';
- shift @token;
}
elsif ($token[0] eq '[')
{
}
elsif ($token[0] eq '[')
{
@res = (parse_expr (), '');
@res = (parse_expr (), '');
- die "unexpected $token[0], expected ]"
- unless $token[0] eq ']';
- shift @token;
unless defined $token[0];
if ($token[0] eq '#d')
unless defined $token[0];
if ($token[0] eq '#d')
+ {
+ eat ('#d');
+ $token[0] =~ s/(.*?)=(.*)/$1 $2/;
+ @res = ("%code {\n#define $token[0]\n}");
+ shift @token;
+ }
+ elsif ($token[0] eq '%d')
- @res = ("%code {\n#define\n}");
+ $token[0] =~ s/(.*?)=(.*)/$1 "$2"/;
+ @res = ("%define $token[0]");
shift @token;
}
elsif ($token[0] eq '%s')
shift @token;
}
elsif ($token[0] eq '%s')