Created
February 19, 2013 09:00
-
-
Save FROGGS/4984189 to your computer and use it in GitHub Desktop.
Allow / [ a || b || @A ] / to do sequential matching instead of LTM.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/NQP/Actions.pm b/src/NQP/Actions.pm | |
index 0d3111e..6fbeccb 100644 | |
--- a/src/NQP/Actions.pm | |
+++ b/src/NQP/Actions.pm | |
@@ -1665,7 +1665,8 @@ class NQP::RegexActions is QRegex::P6Regex::Actions { | |
method metachar:sym<nqpvar>($/) { | |
make QAST::Regex.new( QAST::Node.new( | |
QAST::SVal.new( :value('!INTERPOLATE') ), | |
- $<var>.ast), | |
+ $<var>.ast, | |
+ QAST::IVal.new( :value($*SEQ ?? 1 !! 0) ) ), # sequential matching | |
:rxtype<subrule>, :subtype<method>, :node($/)); | |
} | |
diff --git a/src/QRegex/Cursor.nqp b/src/QRegex/Cursor.nqp | |
index 1a93813..0b0a605 100755 | |
--- a/src/QRegex/Cursor.nqp | |
+++ b/src/QRegex/Cursor.nqp | |
@@ -681,7 +681,7 @@ class NQPCursor does NQPCursorRole { | |
nqp::findmethod($cur, $rule)($cur).MATCH() | |
} | |
- method !INTERPOLATE($var) { | |
+ method !INTERPOLATE($var, $s = 0) { | |
if nqp::islist($var) { | |
my int $maxlen := -1; | |
my $cur := self.'!cursor_start_cur'(); | |
@@ -702,6 +702,7 @@ class NQPCursor does NQPCursorRole { | |
$maxlen := $len if $len > $maxlen && $pos + $len <= $eos | |
&& nqp::substr($tgt, $pos, $len) eq $_; | |
} | |
+ last if $s && $maxlen > -1; | |
} | |
$cur.'!cursor_pass'($pos + $maxlen, '') if $maxlen >= 0; | |
return $cur; | |
diff --git a/src/QRegex/P6Regex/Grammar.nqp b/src/QRegex/P6Regex/Grammar.nqp | |
index 9ae0b89..91d0a08 100755 | |
--- a/src/QRegex/P6Regex/Grammar.nqp | |
+++ b/src/QRegex/P6Regex/Grammar.nqp | |
@@ -81,10 +81,16 @@ grammar QRegex::P6Regex::Grammar is HLL::Grammar { | |
token nibbler { | |
:my $OLDRX := nqp::getlexdyn('%*RX'); | |
:my %*RX; | |
+ :my $*SEQ := 0; | |
{ | |
for $OLDRX { %*RX{$_.key} := $_.value; } | |
} | |
- [ <.ws> ['||'|'|'|'&&'|'&'] ]? | |
+ [ <.ws> [ | |
+ | '||' { $*SEQ := 1; } | |
+ | '|' | |
+ | '&&' | |
+ | '&' | |
+ ] ]? | |
<termaltseq> <.ws> | |
[ | |
|| <?infixstopper> | |
@@ -107,22 +113,22 @@ grammar QRegex::P6Regex::Grammar is HLL::Grammar { | |
token termaltseq { | |
<termconjseq> | |
- [ '||' [ <termconjseq> || <.throw_null_pattern> ] ]* | |
+ [ '||' [ { $*SEQ := 1; } <termconjseq> || <.throw_null_pattern> ] ]* | |
} | |
token termconjseq { | |
<termalt> | |
- [ '&&' [ <termalt> || <.throw_null_pattern> ] ]* | |
+ [ '&&' [ { $*SEQ := 0; } <termalt> || <.throw_null_pattern> ] ]* | |
} | |
token termalt { | |
<termconj> | |
- [ '|' <![|]> [ <termconj> || <.throw_null_pattern> ] ]* | |
+ [ '|' <![|]> [ { $*SEQ := 0; } <termconj> || <.throw_null_pattern> ] ]* | |
} | |
token termconj { | |
<termish> | |
- [ '&' <![&]> [ <termish> || <.throw_null_pattern> ] ]* | |
+ [ '&' <![&]> [ { $*SEQ := 0; } <termish> || <.throw_null_pattern> ] ]* | |
} | |
token termish { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/Perl6/Actions.pm b/src/Perl6/Actions.pm | |
index b31c6da..decaaae 100644 | |
--- a/src/Perl6/Actions.pm | |
+++ b/src/Perl6/Actions.pm | |
@@ -5880,7 +5880,8 @@ class Perl6::RegexActions is QRegex::P6Regex::Actions does STDActions { | |
make QAST::Regex.new( QAST::Node.new( | |
QAST::SVal.new( :value('INTERPOLATE') ), | |
$<var>.ast, | |
- QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) ) ), | |
+ QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) ), | |
+ QAST::IVal.new( :value($*SEQ ?? 1 !! 0) ) ), # sequential matching | |
:rxtype<subrule>, :subtype<method>, :node($/)); | |
} | |
diff --git a/src/core/Cursor.pm b/src/core/Cursor.pm | |
index 537b182..0f0c624 100644 | |
--- a/src/core/Cursor.pm | |
+++ b/src/core/Cursor.pm | |
@@ -45,10 +45,34 @@ my class Cursor does NQPCursorRole { | |
$match; | |
} | |
- method INTERPOLATE($var, $i = 0) { | |
- nqp::isconcrete($var) ?? | |
- ($var ~~ Callable ?? $var(self) !! self."!LITERAL"(nqp::unbox_s($var.Str), $i)) !! | |
+ method INTERPOLATE($var, $i = 0, $s = 0) { | |
+ if nqp::isconcrete($var) { | |
+ if nqp::istype($var, Positional) # for array-likes | |
+ || nqp::istype($var, Capture) { # for references to arrays, dunno if they should be treated as positionals directly | |
+ my $maxlen := -1; | |
+ my $cur := self.'!cursor_start_cur'(); | |
+ my $pos := nqp::getattr_i($cur, $?CLASS, '$!from'); | |
+ my $tgt := $cur.target; | |
+ my $eos := nqp::chars($tgt); | |
+ for $var.list { | |
+ my $topic := $_ ~~ Callable ?? $_(self) !! $_; | |
+ my $len := nqp::chars($topic); | |
+ if $len > $maxlen && $pos + $len <= $eos | |
+ && nqp::substr($tgt, $pos, $len) eq $topic { | |
+ $maxlen := $len; | |
+ last if $s; # stop here for sequential alternation | |
+ } | |
+ } | |
+ $cur.'!cursor_pass'($pos + $maxlen, '') if $maxlen >= 0; | |
+ $cur | |
+ } | |
+ else { | |
+ $var ~~ Callable ?? $var(self) !! self."!LITERAL"(nqp::unbox_s($var.Str), $i) | |
+ } | |
+ } | |
+ else { | |
self."!cursor_start_cur"() | |
+ } | |
} | |
method OTHERGRAMMAR($grammar, $name, |) { |
I'm sorry, but why use "$_SEQ ?? 1 !! 0", instead of "$_SEQ"?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tests:
NQP: Result: PASS
Rakudo:
t/spec/S05-interpolation/regex-in-variable.rakudo (Wstat: 0 Tests: 33 Failed: 0)
TODO passed: 24
t/spec/S05-metasyntax/litvar.rakudo (Wstat: 0 Tests: 33 Failed: 0)
TODO passed: 24-26, 28-29
t/spec/S05-metasyntax/sequential-alternation.rakudo (Wstat: 0 Tests: 10 Failed: 0)
TODO passed: 7-10
Files=723, Tests=26819, 717 wallclock secs ( 9.54 usr 1.42 sys + 2155.61 cusr 146.80 csys = 2313.37 CPU)
Result: PASS