[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