[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