Permalink
Browse files

Add backtracking into subrule code. Split !cursor_next from Cursor.ne…

…xt .
  • Loading branch information...
pmichaud committed Jul 19, 2010
1 parent b796e3d commit a1c5ce3baead01a2d53fce9d5c887c84f6e49ad7
Showing with 43 additions and 11 deletions.
  1. +21 −1 src/PAST/Compiler-Regex.pir
  2. +22 −10 src/Regex/Cursor.pir
@@ -1101,8 +1101,9 @@ Perform a subrule call.
negate = node.'negate'()
testop = self.'??!!'(negate, 'if', 'unless')
- .local pmc subtype
+ .local pmc subtype, backtrack
subtype = node.'subtype'()
+ backtrack = node.'backtrack'()
ops.'push_pirop'('inline', subpost, subtype, negate, 'inline'=>" # rx subrule %0 subtype=%1 negate=%2")
@@ -1111,8 +1112,27 @@ Perform a subrule call.
ops.'push_pirop'('callmethod', subpost, cur, posargs :flat, namedargs :flat, 'result'=>'$P10')
ops.'push_pirop'(testop, '$P10', fail)
if subtype == 'zerowidth' goto done
+ if backtrack != 'r' goto subrule_backtrack
if subtype == 'method' goto subrule_pos
self.'!cursorop'(ops, '!mark_push', 0, 0, CURSOR_FAIL, 0, '$P10')
+ goto subrule_named
+ subrule_backtrack:
+ .local string rxname
+ .local pmc backlabel, passlabel
+ rxname = self.'unique'('rxsubrule')
+ $S0 = concat rxname, '_back'
+ backlabel = self.'post_new'('Label', 'result'=>$S0)
+ $S0 = concat rxname, '_pass'
+ passlabel = self.'post_new'('Label', 'result'=>$S0)
+ ops.'push_pirop'('goto', passlabel)
+ ops.'push'(backlabel)
+ ops.'push_pirop'('callmethod', '"!cursor_next"', '$P10', 'result'=>'$P10')
+ ops.'push_pirop'(testop, '$P10', fail)
+ ops.'push'(passlabel)
+ ops.'push_pirop'('set_addr', '$I10', backlabel)
+ self.'!cursorop'(ops, '!mark_push', 0, 0, pos, '$I10', '$P10')
+ if subtype == 'method' goto subrule_pos
+ subrule_named:
ops.'push'(name)
ops.'push_pirop'('callmethod', '"!cursor_names"', '$P10', name)
subrule_pos:
View
@@ -219,15 +219,8 @@ Return the next match from a successful Cursor.
=cut
.sub 'next' :method
- .local pmc regex, cur, match
- regex = getattribute self, '&!regex'
- if null regex goto cur_fail
- cur = self.regex()
- goto cur_done
- cur_fail:
- cur = self.'!cursor_start'()
- cur.'!cursor_fail'()
- cur_done:
+ .local pmc cur, match
+ cur = self.'!cursor_next'()
match = cur.'MATCH'()
.return (match)
.end
@@ -406,7 +399,7 @@ with a "real" Match object when requested.
=item !cursor_backtrack()
-Configure this cursor for backtracking via .next.
+Configure this cursor for backtracking via C<!cursor_next>.
=cut
@@ -417,6 +410,25 @@ Configure this cursor for backtracking via .next.
.end
+=item !cursor_next()
+
+Continue a regex match from where the current cursor left off.
+
+=cut
+
+.sub '!cursor_next' :method
+ .local pmc regex, cur
+ regex = getattribute self, '&!regex'
+ if null regex goto fail
+ cur = self.regex()
+ .return (cur)
+ fail:
+ cur = self.'!cursor_start'()
+ cur.'!cursor_fail'()
+ .return (cur)
+.end
+
+
=item !cursor_caparray(caparray :slurpy)
Set the list of subcaptures that produce arrays to C<caparray>.

0 comments on commit a1c5ce3

Please sign in to comment.