in reply to Re^4: Perl regexp matching is slow??
in thread Perl regexp matching is slow??

abigail mentioned something similar, but i havent gotten my head around what is really needed. If i had a better idea id be able to given a better estimate of when it could be done by. For instance there is a considerable amount of data on the stack after a match that might be useful for this purpose, i just dont really have a good grip on the problem to make any useful suggestions.

---
$world=~s/war/peace/g

Replies are listed 'Best First'.
Re^6: Perl regexp matching is slow??
by educated_foo (Vicar) on Feb 28, 2007 at 03:23 UTC

    The inspiration comes from Parse::RecDescent's "autotree" directive, which basically constructs a parse tree by collecting submatches into a hash (keyed by submatch name) and blessing that into a package named according to the parent rule, e.g. A ::= B C creates an object of type A with two fields B and C.

    I think a much less blessed scheme would be appropriate for the regex engine, in which numbered submatches are collected into match variables @/ and %/. For @/, each capturing group generates a capture:

    • If the capturing group is quantified, it is an arrayref of captures, one for each repetition.
    • Otherwise, if the capturing group contains no submatches, the capture is a string containing the captured text.
    • Otherwise, $/[0] contains the captured text, and @/[1..N] contain the captures for nested groups $1 ... $N, where the indices are numbered starting from the first nested submatch.
    Similarly, for %/, each capturing group yields a hash capture:
    • $/{0} is the entire text.
    • If (?'NAME'...) has no subcaptures, $/{NAME} is the captured text.
    • Otherwise if (?'NAME'...) is quantified, $/{NAME} is an arrayref of hash captures, one entry for each repetition.
    • Otherwise, $/{NAME} is a hash capture.
    • (maybe) $/{1} through $/{N} are like $/{NAME}, but for all captures, not just named ones.
    For example, I believe the above rules should yield:
    $sexp = qr/ (?<sexp> \s* \( \s* (?&sexp)* \s* \) \s* | \s* (?<atom>\w+) \s* )/x; '(A (B C))' =~ /$sexp/; ## AFTERWARDS %/ = (sexp => { 0 => '(A (B C))', sexp => [{ 0 => 'A', atom => 'A' }, { 0 => '(B C)', sexp => [{ 0 => 'B', atom => 'B' }, { 0 => 'C', atom => 'C' }] }]}; @/ = ('(A (B C))', [['A', 'A'], ['(B C)', [['B', 'B'], ['C', 'C']]]]);

    There are probably some obvious oversights here, but I'll try to get the Regexp::Parser version of this working to shake the bugs out.