Alt-Acme-Math-XS-CPP
view release on metacpan or search on metacpan
inc/Inline/CPP/Parser/RecDescent.pm view on Meta::CPAN
# the repetition specifier.'
# Hence various hash keys may or may not need trailing '(s?)' depending on
# the version of Parse::RecDescent we are using.
require Parse::RecDescent;
# Deal with Parse::RecDescent's version numbers for development
# releases (eg, '1.96_000') resulting in a warning about non-numeric in >
# comparison.
{ # Lexical scope.
# Eval away the underscore. "1.96_000" => "1.96000".
# Use that "stable release" version number as the basis for our numeric
# comparison.
my $stable_version = eval $Parse::RecDescent::VERSION; ## no critic (eval)
($class_part, $class_decl, $star)
= map { ($stable_version > 1.89) ? "$_(s?)" : $_ }
qw ( class_part class_decl star );
} # End lexical scope.
#============================================================================
# Regular expressions to match code blocks, numbers, strings, parenthesized
# expressions, function calls, and macros. The more complex regexes are only
# implemented in 5.6.0 and above, so they're in eval-blocks.
#
# These are all adapted from the output of Damian Conway's excellent
# Regexp::Common module. In future, Inline::CPP may depend directly on it,
# but for now I'll just duplicate the code.
use vars qw( $code_block $string $number $parens $funccall );
#============================================================================
# $RE{balanced}{-parens=>q|{}()[]"'|}
eval <<'END'; ## no critic (eval)
$code_block = qr'(?-xism:(?-xism:(?:[{](?:(?>[^][)(}{]+)|(??{$Inline::CPP::Parser::RecDescent::code_block}))*[}]))|(?-xism:(?-xism:(?:[(](?:(?>[^][)(}{]+)|(??{$Inline::CPP::Parser::RecDescent::code_block}))*[)]))|(?-xism:(?-xism:(?:[[](?:(?>[^][)(}{]...
END
$code_block = qr'{[^}]*}' if $@; # For the stragglers: here's a lame regexp.
# $RE{balanced}{-parens=>q|()"'|}
eval <<'END'; ## no critic (eval)
$parens = qr'(?-xism:(?-xism:(?:[(](?:(?>[^)(]+)|(??{$Inline::CPP::Parser::RecDescent::parens}))*[)]))|(?-xism:(?!)))';
END
$parens = qr'\([^)]*\)' if $@; # For the stragglers: here's another
# $RE{quoted}
$string
= qr'(?:(?:\")(?:[^\\\"]*(?:\\.[^\\\"]*)*)(?:\")|(?:\')(?:[^\\\']*(?:\\.[^\\\']*)*)(?:\')|(?:\`)(?:[^\\\`]*(?:\\.[^\\\`]*)*)(?:\`))';
# $RE{num}{real}|$RE{num}{real}{-base=>16}|$RE{num}{int}
$number
= qr'(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))|(?:(?i)(?:[+-]?)(?:(?=[0123456789ABCDEF]|[.])(?:[0123456789ABCDEF]*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:...
$funccall
= qr/(?:[_a-zA-Z][_a-zA-Z0-9]*::)*[_a-zA-Z][_a-zA-Z0-9]*(?:$Inline::CPP::Parser::RecDescent::parens)?/;
#============================================================================
# Inline::CPP's grammar
#============================================================================
sub grammar {
return <<'END';
{ use Data::Dumper; }
{
sub handle_class_def {
my ($thisparser, $def) = @_;
# print "Found a class: $def->[0]\n";
my $class = $def->[0];
my @parts;
for my $part (@{$def->[1]}) { push @parts, @$_ for @$part }
push @{$thisparser->{data}{classes}}, $class
unless defined $thisparser->{data}{class}{$class};
$thisparser->{data}{class}{$class} = \@parts;
# print "Class $class:\n", Dumper \@parts;
Inline::CPP::Parser::RecDescent::typemap($thisparser, $class);
[$class, \@parts];
}
sub handle_typedef {
my ($thisparser, $t) = @_;
my ($name, $type) = @{$t}{qw(name type)};
# print "found a typedef: $name => $type\n";
# XXX: this doesn't handle non-class typedefs that we could handle,
# e.g. "typedef int my_int_t"
if ($thisparser->{data}{class}{$type}
&& !exists($thisparser->{data}{class}{$name})) {
push @{$thisparser->{data}{classes}}, $name;
$thisparser->{data}{class}{$name} = $thisparser->{data}{class}{$type};
Inline::CPP::Parser::RecDescent::typemap($thisparser, $name);
}
$t;
}
sub handle_enum {
my ($thisparser, $t) = @_;
$t;
}
}
code: part(s) {1}
part: comment
| typedef
{
handle_typedef($thisparser, $item[1]);
1;
}
| enum
{
my $t = handle_enum($thisparser, $item[1]);
push @{$thisparser->{data}{enums}}, $t;
1;
}
| class_def
{
handle_class_def($thisparser, $item[1]);
1;
}
| function_def
{
# print "found a function: $item[1]->{name}\n";
my $name = $item[1]->{name};
( run in 0.524 second using v1.01-cache-2.11-cpan-39bf76dae61 )