Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

parsing make like syntax

2 views
Skip to first unread message

Yuri Shtil

unread,
Jan 11, 2012, 6:52:56 PM1/11/12
to recde...@perl.org
Hi,

I need to parse make variable reference like syntax:

$($(foo))

$(foo) should be detected first, replaced (let's say with bar) and resultant string $(bar) should be parsed the same way.
There can be any number of nested references like

$(abc$(foo)def)

Any suggestions how to define rules for this?

I used Regexp::Common to detect balanced parenthesis.


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

jtb...@cpan.org

unread,
Jan 11, 2012, 7:48:59 PM1/11/12
to recde...@perl.org
I've assumed that you have your value to be substituted in a scalar
variable, that substitutions allowed to introduce new variable
references ( $($(foo)) with foo="$(bar) => $($(bar)) which would then
substitute bar)

I've also assumed that variable names can only contain characters
matching \w. This means that the innermost substitutions (the innermost
ones) should match m/$\(\w+\)/.

Something like this should work:

my %subst = ( foo => '$(bar)',
bar => 'baz',
abcbazdef => 'HELLO',
);
my $val = '$(abc$(foo)def)';

while ($val =~ s/\$\((\w+)\)/$subst{$1}/e) {
print "VAL $val\n";
}

print "$val\n";

I've left out any error checking for undefined values in %subst and the
like.

Using Parse::RecDescent to do this directly would require that you
define a rule something like the following, with $skip probably set to '':

varvalue: '$(' /\w+/ ')'
| '$(' /MATCHALLOWEDLITERAL/ substitution /MATCHALLOWEDLITERAL/ ')'
| /MATCHALLOWEDLITERAL/

The downside of this is that you probably won't be able to easily handle
all cases of recursive substitutions as shown above. You may be able to
modify $text in the actions for the first two rules above, and make it
work. But I'm assuming you've already got a rule that contains
/$RE{balanced}{-parens=>'()'}/, and providing a modified version of the
example action above probably gets you where you want to go.

Jeremy
0 new messages