use strict;
use warnings;
use PPR::X;
use Data::Dumper;

my $grammar_re = $PPR::X::GRAMMAR;
# `@rulenames` contains all the rule names in `$PPR::X::GRAMMAR`,
# e.g., EntireDocument, Term, etc.
my @rule_names = $grammar_re =~ /<PerlStd([^>]+)>/msg;
my @extraction_re_parts = map {
	my $name = $_;
	qq{
		(?<Perl$name>
			(?{ local \$parent = \\%match })
			(?{ local %match = ( name => $name => , position => pos(), parent => \$parent, ) })
			( (?>(?&PerlStd$name)) )
			(?{ \$match{text} = \$^N })
			(?{ push \@matches, \\%match })
		|
			(?!)
		)
	};
} grep $_ !~ /^(Label|PodSequence|OWS|NWS)$/, @rule_names;

our (@matches, $parent, %match);
my $re = do {
	use re 'eval';
	my $combined = qq{
		\\A (?>(?&PerlEntireDocument)) \\Z

		(?(DEFINE)
			@extraction_re_parts
		)

		$grammar_re
	};
	qr{$combined}xms;
};
{
	local (@matches, $parent, %match);
	my $code = <>;
	if( $code =~ $re ) {
		print Dumper(\@matches);
	}
}
