use v5.10;
use warnings;
use Regexp::Grammars;
use re 'eval';
my $metagrammar = q{
<RegexGrammar>
<token: RegexGrammar>
\A
<ActivePattern= RuleBody>
<[Definitions= Ruledef]>*
\z
<token: Ruledef>
\< <Obj=(obj|)> <Type=(rule|token)> \s*+ : \s*+ <Rulename=IDENT> \>
<Body=RuleBody>
<token: RuleBody>
<[Std=StdRegex]>+ % <[NonStd=Translatable]>
<token: StdRegex>
<MATCH= ([^<]*+ .*?)>
<token: Translatable>
<Subrule= SeparatedList>
| <Subrule= SubruleCall>
| <Directive>
<token: Directive>
\< debug \s*+ : \s*+
<Debug=(?: off | run | jump | step | continue | match | try )>
\s*+ \>
|
\< logfile \s*+ : \s*+ <Log=(\S+)> \s*+ \>
<token: SeparatedList>
<Subrule= SubruleCall>
<ws1= (\s*+)>
\*\*
<ws2= (\s*+)>
(?: <Separator= SubruleCall>
| <Separator= PARENS>
)
<token: SubruleCall>
<WS=(\s++)>
|
\<
(?: <Noncapturing=(\.?)> <Subrule=IDENT>
| \[ \s*+ <Subrule=IDENT> \s*+ \]
| <Alias=IDENT> \s*+ = \s*+ <Subrule=IDENT> \s*+
| \[ <Alias=IDENT> \s*+ = \s*+ <Subrule=IDENT> \s*+ \]
|
<Noncapturing= (\.?)>
<Alias= IDENT>
\s*+ = \s*+
( <Action= PARENBLOCK> | <Subpattern= PARENS> )
\s*+
)
\>
<token: IDENT>
[^\W\d]\w*+
<token: CHARSET>
(?> \[ \^?+ \]?+ [^]]*+ \] )
<token: PARENBLOCK>
\(\?\{ (?: \\\\. | <.BRACES> | <.PARENS> | <.CHARSET> | [^][()\\\\]++ )* \}\)
<token: PARENS>
\( (?: \\\\. | <.PARENS> | <.CHARSET> | [^][()\\\\]++ )* \)
<token: BRACES>
\{ (?: \\\\. | <.BRACES> | [^{}\\\\]++ )* \}
};
my $parser = qr{
$metagrammar
}xms;
#use Data::Dumper 'Dumper'; warn Dumper [ $parser ];
if ($metagrammar =~ $parser) {
my $structure = $/{RegexGrammar};
use Data::Dumper 'Dumper';
say Dumper $structure;
}