Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Code to create and capture submatches; Match objects built lazily.
  • Loading branch information
pmichaud committed Oct 11, 2009
1 parent 08a47f4 commit a8a7999
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 10 deletions.
16 changes: 14 additions & 2 deletions src/PAST/Compiler-Regex.pir
Expand Up @@ -783,7 +783,7 @@ Perform a subrule call.
(cur, pos, fail) = self.'!rxregs'('cur pos fail')
ops = self.'post_new'('Ops', 'node'=>node, 'result'=>cur)

.local pmc name, negate
.local pmc name
$P0 = node.'name'()
name = self.'as_post'($P0, 'rtype'=>'~')
ops.'push'(name)
Expand All @@ -796,13 +796,25 @@ Perform a subrule call.
.local pmc zerowidth
zerowidth = node.'zerowidth'()

.local pmc bindpast, bindpost
bindpast = node.'bindnames'()
unless bindpast goto bindpost_done
bindpost = self.'as_post'(bindpast, 'rtype'=>'*')
bindpost_done:

ops.'push_pirop'('inline', name, negate, zerowidth, 'inline'=>" # rx subrule %0 negate=%1 zerowidth=%2")

self.'!cursorop'(ops, '!cursor_pos', 0, pos)
ops.'push_pirop'('callmethod', name, cur, 'result'=>'$P10')
ops.'push_pirop'(testop, '$P10', fail)
if zerowidth goto done
unless bindpast goto bindnames_done
ops.'push'(bindpost)
self.'!cursorop'(ops, '!cursor_names', 0, bindpost)
bindnames_done:
if zerowidth goto zerowidth_done
ops.'push_pirop'('callmethod', "'pos'", '$P10', 'result'=>pos)
zerowidth_done:

done:
.return (ops)
.end
Expand Down
7 changes: 7 additions & 0 deletions src/PAST/Regex.pir
Expand Up @@ -27,6 +27,13 @@ for regular expressions.
.end
.sub 'bindnames' :method
.param pmc value :optional
.param int has_value :opt_flag
.tailcall self.'attr'('bindnames', value, has_value)
.end
.sub 'negate' :method
.param pmc value :optional
.param int has_value :opt_flag
Expand Down
48 changes: 41 additions & 7 deletions src/Regex/Cursor.pir
Expand Up @@ -19,7 +19,7 @@ grammars.
load_bytecode 'P6object.pbc'
.local pmc p6meta
p6meta = new 'P6metaclass'
$P0 = p6meta.'new_class'('Regex::Cursor', 'attr'=>'$!target $!from $!pos $!match $!action @!bstack @!cstack')
$P0 = p6meta.'new_class'('Regex::Cursor', 'attr'=>'$!target $!from $!pos $!match $!action $!names @!bstack @!cstack')
$P0 = box 0
set_global '$!generation', $P0
$P0 = new ['Boolean']
Expand All @@ -46,15 +46,37 @@ for the Cursor if one hasn't been created yet.
$I0 = isa match, ['Regex';'Match']
if $I0 goto match_done

# First, create a Match object and bind it
match_make:
match = new ['Regex';'Match']
setattribute self, '$!match', match
$P0 = getattribute self, '$!target'
setattribute match, '$!target', $P0
$P0 = getattribute self, '$!from'
setattribute match, '$!from', $P0
$P0 = getattribute self, '$!pos'
setattribute match, '$!to', $P0
.local pmc target, from, to
target = getattribute self, '$!target'
setattribute match, '$!target', target
from = getattribute self, '$!from'
setattribute match, '$!from', from
to = getattribute self, '$!pos'
setattribute match, '$!to', to

# If it's not a successful match, or if there are
# no saved subcursors, we're done.
if to < from goto match_done
.local pmc cstack, cstack_it
cstack = getattribute self, '@!cstack'
if null cstack goto cstack_done
unless cstack goto cstack_done
cstack_it = iter cstack
cstack_loop:
unless cstack_it goto cstack_done
.local pmc subcur, subnames, submatch
subcur = shift cstack_it
# If the subcursor isn't bound with a name, skip it
subnames = getattribute subcur, '$!names'
if null subnames goto cstack_loop
match = subcur.'MATCH'()
match[subnames] = submatch
goto cstack_loop
cstack_done:

match_done:
.return (match)
Expand Down Expand Up @@ -201,6 +223,18 @@ with a "real" Match object when requested.
.end


=item !cursor_names(names)

Set the Cursor's name (for binding) to names.
=cut
=sub '!cursor_names' :method
.param pmc names
setattribute self, '$!names', names
.end
=item !cursor_pos(pos)
Set the cursor's position to C<pos>.
Expand Down
3 changes: 2 additions & 1 deletion src/Regex/P6Regex/Actions.pm
Expand Up @@ -213,7 +213,8 @@ method assertion:sym<!>($/) {
}

method assertion:sym<name>($/) {
my $past := PAST::Regex.new( :name(~$<longname>) , :pasttype('subrule') );
my $past := PAST::Regex.new( :name(~$<longname>) , :pasttype('subrule'),
:bindnames(~$<longname>) );
make $past;
}

Expand Down

0 comments on commit a8a7999

Please sign in to comment.