I've just added a <PGE::Text::bracketed> subrule to PGE,
which is roughly analogous to the "bracketed" function in 
Perl 5's Text::Balanced.  

Like most PGE subrules, PGE::Text::bracketed can be called
as a subrule in a rule expression or directly via a subroutine call.
Thus, to extract quote-delimited text from a string:

    .local pmc bracketed
    bracketed = find_global "PGE::Text", "bracketed"

    $P0 = bracketed("'this quoted string' and other stuff", "'")

returns a match object into $P0 that contains C< 'this quoted string' >.
Delimiters can be escaped, thus

    $P0 = bracketed("'Don\'t do that,' he said", "'")

returns a match object corresponding to C< 'Don\'t do that,' >.

PGE::Text::bracketed also understands balanced delimiters of (), [],
<>, and {}, as long as they are properly nested:

    $P0 = bracketed("{ match (this) please } but not this", "(){}")
    print $P0                # outputs { match (this) please }

    $P0 = bracketed("{ match (this please }", "(){}")
    # match fails, "(" has no closing paren

    $P0 = bracketed("{ match \(this please }", "(){}")
    # succeeds, paren is escaped

Quotes can be included in the delimiter to surround unbalanced
delimiters:

    $P0 = bracketed("{ The '(' paren is quoted }", "{}()")   # match fails
    $P0 = bracketed("{ The '(' paren is quoted }", "{}()'")  # match succeeds

Lastly, PGE::Text::bracketed can be used as a subrule in rule expressions:

    .local pmc p6rule, rulesub
    p6rule = find_global "PGE", "p6rule"
    rulesub = p6rule(":w <ident> \:= <PGE::Text::bracketed> ")

    $P0 = rulesub(" a := ( a + b(3) - 4 ) ; "
    # $P0['ident'] == 'a'
    # $P0['PGE::Text::bracketed'] == '( a + b(3) - 4 )'

At the moment there's not a mechanism to specify an alternate set
of delimiters from within a subrule, but this should be available in
the near future as a subrule parameter:

     <PGE::Text::balanced: {}()[]>     # delimited by {}, (), []
     <PGE::Text::balanced("<'\"")>     # delimited by <>, ", '

Comments, questions, suggestions, and tests (in t/p6rules/text_brk.t)
welcomed!

Pm

Reply via email to