#
# recursive pattern/function
#
our ($sequence, $pattern);
{
my $fail = qr/(?{ die "Malformed escape sequence: '$_'\n" })/;
my $esc = qr/ \\(?=[\\<>]) /x;
my $code = qr/ [A-Za-z0-9] /x;
my $body = qr/ (??{ $sequence }) | \\. | [^\\>] /x;
$sequence = qr/ ($code) < ($body*) (?: > | \Z $fail) /x;
$pattern = qr/ $sequence | ($esc) /x;
}
sub expand_escapes {
my ($string, $map) = @_;
my $replace = sub {
my ($code, $body, $esc) = ($1, $2, $3);
return "" if $esc;
my $inside = expand_escapes($body, $map);
if (my $func = $map->{$code}) {
return $func->($inside);
}
warn "Undefined escape code: '$code'\n";
return $inside;
};
$string =~ s{ $pattern }{ &$replace }exg;
$string
}
|