[svn:parrot] r41630 - branches/pct-rx/compilers/pct/src/Regex
pmichaud at svn.parrot.org
pmichaud at svn.parrot.org
Sat Oct 3 05:50:11 UTC 2009
Author: pmichaud
Date: Sat Oct 3 05:50:10 2009
New Revision: 41630
URL: https://trac.parrot.org/parrot/changeset/41630
Log:
[pct-rx]: Refactor Cursor.!matchify, add Cursor.!subrule, other cleanups.
Modified:
branches/pct-rx/compilers/pct/src/Regex/Cursor.pir
branches/pct-rx/compilers/pct/src/Regex/P6Regex.pir
Modified: branches/pct-rx/compilers/pct/src/Regex/Cursor.pir
==============================================================================
--- branches/pct-rx/compilers/pct/src/Regex/Cursor.pir Sat Oct 3 03:53:01 2009 (r41629)
+++ branches/pct-rx/compilers/pct/src/Regex/Cursor.pir Sat Oct 3 05:50:10 2009 (r41630)
@@ -217,23 +217,28 @@
.end
-=item !matchify(pos)
+=item !matchify([name] [, 'pos'=>pos])
Generate a successful match at pos.
=cut
.sub '!matchify' :method
- .param int pos
.param string name :optional
.param int has_name :opt_flag
+ .param pmc pos :named('pos') :optional
+ .param int has_pos :opt_flag
+
+ unless has_pos goto pos_0
+ setattribute self, '$!pos', pos
+ goto pos_done
+ pos_0:
+ pos = getattribute self, '$!pos'
+ pos_done:
.local pmc match
match = self.'MATCH'()
-
- $P0 = box pos
- setattribute match, '$!to', $P0
- setattribute self, '$!pos', $P0
+ setattribute match, '$!to', pos
.local pmc action
unless has_name goto action_done
@@ -270,20 +275,23 @@
.end
-=item !match_bind(subcur, names :slurpy)
+=item !match_bind(bindval, names :slurpy)
-Bind C<subcur>'s match object as submatches of the current cursor
+Bind C<bindval>'s match object as submatches of the current cursor
under C<names>.
=cut
.sub '!match_bind' :method
- .param pmc subcur
+ .param pmc bindval
.param pmc names :slurpy
- .local pmc match, submatch, names_it
+ .local pmc match, names_it
match = self.'MATCH'()
- submatch = subcur.'MATCH'()
+ $I0 = isa bindval, ['Regex';'Cursor']
+ unless $I0 goto have_bindval
+ bindval = bindval.'MATCH'()
+ have_bindval:
names_it = iter names
names_loop:
unless names_it goto names_done
@@ -292,10 +300,10 @@
if null $P1 goto bind_1
$I0 = isa $P1, ['ResizablePMCArray']
unless $I0 goto bind_1
- push $P1, submatch
+ push $P1, bindval
goto names_loop
bind_1:
- match[$P0] = submatch
+ match[$P0] = bindval
goto names_loop
names_done:
.end
@@ -537,6 +545,42 @@
.end
+=item !subrule(subname [, bindnames :slurpy] [, pos :named('pos')] )
+
+Perform a subrule match on C<name>, binding any successful
+match objects into C<bindnames>. If the subrule successfully
+matches, then the cursor invocant is updated to the end of
+the subrule match, otherwise the cursor is unchanged.
+Returns the cursor from the attempted subrule match.
+
+=cut
+
+.sub '!subrule' :method
+ .param string subname
+ .param pmc bindnames :slurpy
+ .param pmc pos :named('pos') :optional
+ .param int has_pos :opt_flag
+
+ unless has_pos goto pos_done
+ setattribute self, '$!pos', pos
+ pos_done:
+
+ # invoke the subrule
+ .local pmc subcur
+ subcur = self.subname()
+ # if the subrule failed, we're done
+ unless subcur goto done
+ # update current cursor's position
+ pos = getattribute subcur, '$!pos'
+ setattribute self, '$!pos', pos
+ # bind any results
+ unless bindnames goto done
+ self.'!match_bind'(subcur, bindnames :flat)
+ done:
+ .return (subcur, pos)
+.end
+
+
=item !symtoken_add(name, sym)
Add a regex C<name> for matching fixed-string C<sym> tokens to
@@ -591,7 +635,7 @@
pos += $I0
pass:
.local pmc match
- match = cur.'!matchify'(pos)
+ match = cur.'!matchify'('pos'=>pos)
match['sym'] = sym
fail:
.return (cur)
Modified: branches/pct-rx/compilers/pct/src/Regex/P6Regex.pir
==============================================================================
--- branches/pct-rx/compilers/pct/src/Regex/P6Regex.pir Sat Oct 3 03:53:01 2009 (r41629)
+++ branches/pct-rx/compilers/pct/src/Regex/P6Regex.pir Sat Oct 3 05:50:10 2009 (r41630)
@@ -44,15 +44,12 @@
.local int pos
cur = self.'!cursor_start'()
cur.'!match_arrays'('noun')
- noun = cur.'quantified_atom'()
+ noun = cur.'!subrule'('quantified_atom', 'noun')
unless noun goto fail
noun_quant_1:
- pos = noun.'pos'()
- cur.'!match_bind'(noun, 'noun')
- cur.'!cursor_pos'(pos)
- noun = cur.'quantified_atom'()
+ noun = cur.'!subrule'('quantified_atom', 'noun')
if noun goto noun_quant_1
- cur.'!matchify'(pos, 'termish')
+ cur.'!matchify'('termish')
fail:
.return (cur)
.end
@@ -62,6 +59,7 @@
token quantified_atom {
<atom>
+ <quantifier>?
}
=cut
@@ -73,15 +71,15 @@
.return ()
peek_done:
- .local pmc cur, atom
+ .local pmc cur, atom, quantifier
.local int pos
cur = self.'!cursor_start'()
- atom = cur.'atom'()
+ cur.'!match_arrays'('quantifier')
+ atom = cur.'!subrule'('atom', 'atom')
unless atom goto fail
- $P0 = atom.'MATCH'()
- cur.'!match_bind'(atom, 'atom')
- pos = atom.'pos'()
- cur.'!matchify'(pos, 'quantified_atom')
+ quantifier = cur.'!subrule'('quantifier', 'quantifier')
+ done:
+ cur.'!matchify'('quantified_atom')
fail:
.return (cur)
.end
@@ -121,13 +119,55 @@
if len == 1 goto word_done
dec eow
word_done:
- cur.'!matchify'(eow, 'atom')
+ cur.'!matchify'('atom', 'pos'=>eow)
.return (cur)
metachar:
.return (cur)
.end
+
+=item quantifier
+
+ proto token quantifier { ... }
+ token quantifier:sym<*> { <sym> <quantmod> }
+ token quantifier:sym<+> { <sym> <quantmod> }
+ token quantifier:sym<?> { <sym> <quantmod> }
+
+=cut
+
+.sub 'quantifier' :method
+ .tailcall self.'!protoregex'('quantifier')
+.end
+
+.sub 'quantifier:sym<*>' :method
+ .param pmc peek :named('peek') :optional
+
+ if null peek goto peek_done
+ .return ('*')
+ peek_done:
+
+ .local pmc cur, quantmod
+ .local string target
+ .local int pos
+ (cur, pos, target) = self.'!cursor_start'()
+ $S0 = substr target, pos, 1
+ if $S0 != '*' goto fail
+ inc pos
+ cur.'!match_bind'('*', 'sym')
+ goto done
+ cur.'!cursor_pos'(pos)
+ quantmod = cur.'quantmod'()
+ unless quantmod goto fail
+ pos = quantmod.'pos'()
+ cur.'!match_bind'(quantmod, 'quantmod')
+ done:
+ cur.'!matchify'('pos'=>pos)
+ fail:
+ .return (cur)
+.end
+
+
=back
=head1 AUTHORS
More information about the parrot-commits
mailing list