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

I'm trying to separate c function content from the function definition, and have *almost* got it. This code works in this example
my $np; $np= qr{ \{ (?: (?> [^ \{\} ]+) | (??{$np}) )* \} }x; my $text = "functio{1{2*3}}"; my $funcpat = qr/(\w+)($np)/ms; if ($text =~/^$funcpat/ms){ print "\n\nmatches\n"; print "$1\n"; print "$2\n"; print $text;
however, if I split the function over multiple line, like it will encounter in the wild, I can't match, even though I've added the -ms to cover multiple lines, like here:
my $np; $np= qr{ \{ (?: (?> [^ \{\} ]+) | (??{$np}) )* \} }x; my $text = " functio { 1 {2*3} }"; my $funcpat = qr/(\w+)($np)/ms; if ($text =~/^$funcpat/ms){ print "\n\nmatches\n"; print "$1\n"; print "$2\n"; print $text;
Has anyone got any ideas as to what is going wrong? Cheers.

Replies are listed 'Best First'.
Re: qr//ms problem
by idsfa (Vicar) on Jul 14, 2005 at 14:36 UTC

    This is a much harder problem than you think. Try using Regexp::Common::balanced to strip out the code blocks. Unfortunately, your pattern still won't get you function names for valid C source code like:

    int foo(int bar, char ** baz) { ... }
    Maybe something like:
    (\w+)\s*$RE{balanced}{-parens=>'()'}[^{]*$RE{balanced}{-parens=>'{}'}

    Though that will still have problems for some older C code.

    Updated: Looking though CPAN finds C::Scan, which looks like it does what you want to do.

    my $c = new C::Scan 'filename' => $filename; my $arrayref = $c->fdecls;

    Updated 2: I'm a bit confused as to why you are implementing the only answer of your previous version of the same question that was stated flat out not to work by the poster.


    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. -- Cyrus H. Gordon
Re: qr//ms problem
by Eimi Metamorphoumai (Deacon) on Jul 14, 2005 at 15:01 UTC
    Others have provided answers to what you should have asked, but I'll answer what you really asked. The answer is that qr// creates a precompiled regexp with all the modifiers set. So when you create $np, you need to specify the /ms there. If you were to print out $np, you'd see that it starts with (?x-ism:, meaning that it overrides any modifiers you specify later on (so that it has its own self-contained meaning).
      True. However, it's moot in this case because there are no "." for /s to affect, and no "^" or "$" for /m to affect. Moving or adding those modifiers won't help.
Re: qr//ms problem
by blazar (Canon) on Jul 14, 2005 at 14:48 UTC