Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi! I am trying to match C++ templates:
#!/usr/bin/perl $cparens = qr/ (?<intern> \< (?: [^<>]++ | (?$+{intern}) )*+ \> ) /x; $ks="BinaryNode<OpAdd1<OpAdd2>,OpMulAdd2<OpMulAdd>>"; if ($ks =~ m/ ([^<>]++) \<(?'part1'[^<>]++(?:$cparens)?) \,(?'part2'[^<>]++(?:$cparens)?) \> /x) { print "ok\n"; } print "p1 $+{part1}\n"; print "p2 $+{part2}\n";

This matches as supposed and prints the part1 and part2 of the toplevel template:

p1 OpAdd1<OpAdd2>

p2 OpMulAdd2<OpMulAdd>

But, when I add one more level of recursion, like adding to one of the parts:

p1

p2

it doesn't match anymore!

I don't follow this logic. Does anybody know why this behaviour is shown?

Frank

Replies are listed 'Best First'.
Re: recursive pattern
by ikegami (Patriarch) on Jan 05, 2010 at 22:28 UTC

    What's with people not checking for errors and warnings when their code doesn't work?

    Use of uninitialized value $+{"intern"} in regexp compilation at a.pl +line 6.

    It actually fails when any recursion is needed. The initial expression doesn't actually exercise the recursive path, which is why it works.

    The problem results in $cparens containing

    (?x-ism: (?<intern> \< (?: [^<>]++ | (?) )*+ \> ) )
    Replace
    (?$+{intern})
    with
    (?&intern)