[svn:parrot] r41546 - in branches/pct-rx: compilers/pct/src/PAST examples/regex

pmichaud at svn.parrot.org pmichaud at svn.parrot.org
Tue Sep 29 04:57:39 UTC 2009


Author: pmichaud
Date: Tue Sep 29 04:57:37 2009
New Revision: 41546
URL: https://trac.parrot.org/parrot/changeset/41546

Log:
[pct-rx]:  Add frugal quantifier.

Added:
   branches/pct-rx/examples/regex/04-frugal-past.nqp
Modified:
   branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir

Modified: branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir
==============================================================================
--- branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir	Tue Sep 29 03:48:34 2009	(r41545)
+++ branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir	Tue Sep 29 04:57:37 2009	(r41546)
@@ -311,7 +311,7 @@
     (cur, pos, rep, fail) = self.'!rxregs'('cur pos rep fail')
 
     .local string qname
-    .local pmc ops, q1label, q2label, q2reg, cpost
+    .local pmc ops, q1label, q2label, btreg, cpost
     $S0 = concat 'quant', backtrack
     qname = self.'unique'($S0)
     ops = self.'post_new'('Ops', 'node'=>node)
@@ -319,7 +319,6 @@
     q1label = self.'post_new'('Label', 'result'=>$S0)
     $S0 = concat qname, '_done'
     q2label = self.'post_new'('Label', 'result'=>$S0)
-    q2reg = self.'uniquereg'('I')
     cpost = self.'concat'(node)
 
     $S0 = max
@@ -332,10 +331,12 @@
     $S0 = '*'
   have_s0:
     ops.'push_pirop'('inline', qname, min, $S0, 'inline'=>'  # rx %0 ** %1..%2')
-    ops.'push_pirop'('set_addr', q2reg, q2label)
 
+  if backtrack == 'f' goto frugal
 
   greedy:
+    btreg = self.'uniquereg'('I')
+    ops.'push_pirop'('set_addr', btreg, q2label)
     .local int needmark
     .local string peekcut
     needmark = needrep
@@ -346,15 +347,15 @@
   greedy_1:
     if min == 0 goto greedy_2
     unless needmark goto greedy_loop
-    ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, -1, q2reg)
+    ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, -1, btreg)
     goto greedy_loop
   greedy_2:
-    ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, q2reg)
+    ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, btreg)
   greedy_loop:
     ops.'push'(q1label)
     ops.'push'(cpost)
     unless needmark goto greedy_3
-    ops.'push_pirop'('callmethod', peekcut, cur, q2reg, 'result'=>rep)
+    ops.'push_pirop'('callmethod', peekcut, cur, btreg, 'result'=>rep)
     unless needrep goto greedy_3
     ops.'push_pirop'('inc', rep)
   greedy_3:
@@ -362,7 +363,7 @@
     ops.'push_pirop'('ge', rep, max, q2label)
   greedy_4:
     unless max != 1 goto greedy_5
-    ops.'push_pirop'('callmethod', '"!mark_push"', cur, rep, pos, q2reg)
+    ops.'push_pirop'('callmethod', '"!mark_push"', cur, rep, pos, btreg)
     ops.'push_pirop'('goto', q1label)
   greedy_5:
     ops.'push'(q2label)
@@ -370,6 +371,39 @@
     ops.'push_pirop'('lt', rep, min, fail)
   greedy_6:
     .return (ops)
+
+  frugal:
+    .local pmc ireg
+    ireg = self.'uniquereg'('I')
+    if min == 0 goto frugal_1
+    unless needrep goto frugal_2
+    ops.'push_pirop'('set', rep, 0)
+    goto frugal_2
+  frugal_1:
+    ops.'push_pirop'('set_addr', '$I10', q1label)
+    ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, '$I10')
+    ops.'push_pirop'('goto', q2label)
+  frugal_2:
+    ops.'push'(q1label)
+    unless needrep goto frugal_3
+    ops.'push_pirop'('set', ireg, rep)
+  frugal_3:
+    ops.'push'(cpost)
+    unless needrep goto frugal_4
+    ops.'push_pirop'('add', rep, ireg, 1)
+  frugal_4:
+    unless min > 1 goto frugal_5
+    ops.'push_pirop'('lt', rep, min, q1label)
+  frugal_5:
+    unless max > 1 goto frugal_6
+    ops.'push_pirop'('ge', rep, max, q2label)
+  frugal_6:
+    unless max != 1 goto frugal_7
+    ops.'push_pirop'('set_addr', '$I10', q1label)
+    ops.'push_pirop'('callmethod', '"!mark_push"', cur, ireg, pos, '$I10')
+  frugal_7:
+    ops.'push'(q2label)
+    .return (ops)
 .end
 
 =back

Added: branches/pct-rx/examples/regex/04-frugal-past.nqp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/pct-rx/examples/regex/04-frugal-past.nqp	Tue Sep 29 04:57:37 2009	(r41546)
@@ -0,0 +1,55 @@
+# nqp
+
+say("# regex { 'foo'*? }");
+my $past :=
+  PAST::Regex.new(
+    PAST::Regex.new(
+      PAST::Regex.new('foo', :pasttype('literal')),
+      :pasttype('quant'),
+      :backtrack('f')
+    ),
+    PAST::Regex.new(:pasttype('pass')),
+  );
+say(PAST::Compiler.compile($past, :target('pir')));
+
+say("# regex { 'foo'+? }");
+my $past :=
+  PAST::Regex.new(
+    PAST::Regex.new(
+      PAST::Regex.new('foo', :pasttype('literal')),
+      :pasttype('quant'),
+      :backtrack('f'),
+      :min(1)
+    ),
+    PAST::Regex.new(:pasttype('pass')),
+  );
+say(PAST::Compiler.compile($past, :target('pir')));
+
+say("# regex { 'foo'?? }");
+my $past :=
+  PAST::Regex.new(
+    PAST::Regex.new(
+      PAST::Regex.new('foo', :pasttype('literal')),
+      :pasttype('quant'),
+      :backtrack('f'),
+      :max(1)
+    ),
+    PAST::Regex.new(:pasttype('pass')),
+  );
+say(PAST::Compiler.compile($past, :target('pir')));
+
+say("# regex { 'foo' **? 5..9 }");
+my $past :=
+  PAST::Regex.new(
+    PAST::Regex.new(
+      PAST::Regex.new('foo', :pasttype('literal')),
+      :pasttype('quant'),
+      :backtrack('f'),
+      :min(5),
+      :max(9)
+    ),
+    PAST::Regex.new(:pasttype('pass')),
+  );
+say(PAST::Compiler.compile($past, :target('pir')));
+
+


More information about the parrot-commits mailing list