I know how to do basic regexp-based parsing with (?(DEFINE)...) blocks and named groups that recurse into those definitions, like in the example in the perlre man page. I think after such a parsing match only information about the top-level tokens is available, but I would like to be able to modify the lower-level tokens in the text I'm matching against. So let's say I have a parsing regexp that at the top level can contain statements or expressions, and these can contain identifiers, and I want to change all identifiers to upper case in the text (not only in the parse tree), how would I do that? Would it be better to use a module for that?
Edit as suggested by Rolf:
I got this idea when my colleague complained that Golang forces casing conventions on users and I noticed that I don't know enough about regexes to, say, change just the case of identifiers. And I thought, if I can get the Go grammar into Perl, then I might sometimes have some scripting fun at my day job. I've seen the regexp JSON parser and I like how close this looks to an ANTLR grammar and I guess if using a module for tree data structures, then even the $^R manipulations might become readable, though I've never seen an example of that? If I went down that route, then I could probably use some trickery with using \substr instead of $^N to save substring references to the original string into the $^R syntax tree, though I can see that becoming an unmaintainable mess. Using m/\G.../gc to do the parsing seems like a lot of typing for a grammar that is already several hundred lines in ANTLR form.
Here's a simple code example of a parsing regexp. And here is the Go ANTLR grammar that I would like to translate.
#!/usr/bin/perl -w
use v5.20;
use re 'strict';
$_ = 'my$a=5;';
my $re = qr/
(?<statements>(?&statement)*)
(?(DEFINE)
(?<statement> my \$ (?&identifier) = \d ; )
(?<identifier> [a-z] )
)/x;
$_ =~ $re;
say $+{statements};
# Assuming I do the $^R and $^N stuff to create a parse tree, then it
+would be nice, if I could write something like:
# ${$r->{statements}[0]->{identifier}} = 'b';
# in order to change $_ to "my$b=5;"
# similar in spirit to substring references:
# my $s = \substr $_, 3, 1;
# $$s = 'b';