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

Reply via email to