In <[EMAIL PROTECTED]>, Mark-Jason Dominus writes:
:
:> : it looks worse and dumps core.
:>
:> That's because the first non-paren forces it to recurse into the
:> second branch until you hit REG_INFTY or overflow the stack. Swap
:> second and third branches and you have a better chance:
:
:I think something else goes wrong there too.
:
:
:> $re = qr{...}
:> (I haven't checked that there aren't other problems with it, though.)
:
:Try this:
:
: "(x)(y)" -~ /^$re$/;
:
:This should match, but it dumps core. I don't think there is infinite
:recursion, although I might be mistaken.
Ah, I see it: this longwindedly recurses into the third branch forever.
In general, whenever a regexp can recurse back into itself without
consuming any characters first, you're likely to get infinite recursion.
I've lost context on the original aim, but you might want:
$re = qr{
(?> [^()]+ )
|
(?:
\( (??{$re}) \)
)+
}x;
.. or possibly:
$re = qr{
(:
(?> [^()]+ )
|
\( (??{$re}) \)
)+
}x;
:Anyway, Snobol has a nice heuristic to prevent infinite recursion in
:cases like this, but I'm not sure it's applicable to the way the Perl
:regex engine works. I will think about it.
It is probably worth adding the heuristic above: anytime you recurse
into the same re at the same position, there is an infinite loop.
Ah, except if another eval is modifying, I guess:
$re = qr{
(?{ $c++ ? 'foo' : '' })
|
(??{ $re }) (??{ $re })
}x;
And no, I have no idea what strings that will match. That's what makes
this job so much fun. :)
Hugo