3 PGE::Text - rules for extracting delimited text sequences from strings
7 The various rules in this module may be used to extract delimited
8 strings from within PGE rules. (They can of course be called directly,
13 .namespace [ "PGE::Text" ]
15 .include "cclass.pasm"
19 $P0 = subclass 'PGE::Grammar', 'PGE::Text'
22 =head2 Available rules
26 =item C<bracketed(PMC target, string delim)>
28 Extracts a balanced-bracket-delimited substring from the
29 current position of C<target> using the delimiters specified
30 by C<delim>, and returns a C<Match> object containing the result
36 .param pmc tgt # target to match
37 .param string delim :optional # optional delimiters
38 .param int has_delim :opt_flag
39 .param pmc adverbs :slurpy :named # named options
40 .local pmc mob # return match object
41 .local string target # target as string
42 .local string bal, bra, ket # balanced brackets
43 .local string delim_bra, delim_ket # delims for this match
44 .local string lookket # closing bracket char
45 .local int from, pos # current match position
46 .local int balanced # in balanced match
47 .local pmc stack # lookket backtracking
49 stack = new 'ResizableStringArray'
50 $P0 = get_hll_global ['PGE'], 'Match'
51 (mob, pos, target) = $P0.'new'(tgt)
54 if has_delim goto mkdelims
57 mkdelims: # set up delimiters
58 delim_bra = '' # list of open delims
59 delim_ket = '' # list of close delims
60 bal = '{}()[]<>' # list of balance delims
61 bra = '{{(([[<<' # balanced openers
62 ket = '}}))]]>>' # balanced closers
63 $I0 = length delim # length of delim string
66 if $I0 < 0 goto extract
67 $S0 = substr delim, $I0, 1
69 if $I1 < 0 goto mkdelims_2
70 $S1 = substr bra, $I1, 1
72 $S1 = substr ket, $I1, 1
81 $S0 = substr target, pos, 1
82 if $S0 == "\\" goto end # leading escape fails
83 $I0 = index delim_bra, $S0
84 if $I0 < 0 goto end # no leading delim fails
88 $S0 = substr target, pos, 1 # check current pos
89 if $S0 == '' goto fail # end of string -> fail
90 if $S0 == "\\" goto escape # skip escaped pos
91 if $S0 == lookket goto close # end of current nest
92 if balanced < 0 goto skip # skip to next char
93 $I0 = index delim_bra, $S0 # open new nest?
95 $I0 = index delim_ket, $S0 # unbalanced nest?>
98 inc pos # move to next char
101 pos += 2 # skip escape + char
103 open: # open new nesting
104 push stack, lookket # save current nest
105 lookket = substr delim_ket, $I0, 1 # search to end of nest
106 balanced = index bra, $S0 # is this a balanced nest?
107 inc pos # skip open char
108 goto next # continue scanning
109 close: # close current nesting
110 lookket = pop stack # restore previous nest
111 balanced = 1 # we're balancing again
112 inc pos # skip close char
113 if lookket != '' goto next # still nested?
114 mob.'to'(pos) # set end of match
115 $I0 = from + 1 # create delim-less submatch
117 $P0 = mob.'new'(mob, 'pos' => $I0)
129 Patrick Michaud (pmichaud@pobox.com) is the author and maintainer.
130 Patches and suggestions should be sent to the Perl 6 compiler list
131 (perl6-compiler@perl.org).
139 # vim: expandtab shiftwidth=4 ft=pir: