use t::lib::Emitter;
plan tests => 53;
run_tests;
__DATA__
=== TEST 1:
--- token: a
--- Layout
<global>
<constant />
</global>
--- constant
## pos: 0 1
( ( substr( $s, $pos, 1 ) eq 'a' )
? ( $pos += 1 or 1 )
: 0
)
--- global
## sigspace: 0
## ratchet: 1
do { my $rule; $rule = sub {
my $grammar = $_[0];
my $s = $_[1];
$_[3] = $_[2] unless defined $_[3]; # backwards compat
no warnings 'substr', 'uninitialized', 'syntax';
my %pad;
my $m;
my $bool;
my @pos;
# XXX :pos(X) takes the precedence over :continue ?
if (defined $_[3]{p}) {
push @pos, $_[3]{p} || 0;
} elsif ($_[3]{continue}) {
push @pos, (pos($_[1]) || 0) .. length($s);
} else {
push @pos, 0..length($s);
}
for my $pos ( @pos ) {
my %index;
my @match;
my %named;
$bool = 1;
$named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};
$m = Pugs::Runtime::Match->new( {
str => \$s, from => \(0+$pos), to => \($pos),
bool => \$bool, match => \@match, named => \%named, capture => undef,
} );
{
my $prior = $::_V6_PRIOR_;
local $::_V6_PRIOR_ = $prior;
$bool = 0 unless
## <constant />
;
}
if ( $bool ) {
my $prior = $::_V6_PRIOR_;
$::_V6_PRIOR_ = sub {
local $main::_V6_PRIOR_ = $prior;
$rule->(@_);
};
#warn "pos2 = ", $pos, "\n";
pos($_[1]) = $pos if $_[3]{continue};
last;
}
} # /for
$::_V6_MATCH_ = $m;
return $m;
} }
=== TEST 2:
--- token: 'a | b'
--- Layout
<global>
<alt>
<group>
<constant />
</group>
<group>
<constant />
</group>
</alt>
</global>
--- alt
## pos: 0 5
(
( $pad{I1170} = $pos or 1 )
&& (
## <group />
)
|| (
( ( $bool = 1 ) && ( $pos = $pad{I1170} ) or 1 )
&&
## <group />
)
)
--- constant
## pos: 0 1
( ( substr( $s, $pos, 1 ) eq 'a' )
? ( $pos += 1 or 1 )
: 0
)
=== TEST 3: concat
--- token: ab
--- Layout
<global>
<concat>
<constant />
<constant />
</concat>
</global>
--- concat
## pos: 0 2
(
## <constant />
&&
## <constant />
)
=== TEST 4: metasyntax '...'
--- token: "'a'"
--- Layout
<global>
<constant />
</global>
--- constant
## pos: 0 3
( ( substr( $s, $pos, 1 ) eq 'a' )
? ( $pos += 1 or 1 )
: 0
)
=== TEST 5: metasyntax <$...>
--- token: ' <$a> '
--- Layout
<global>
<group>
<metasyntax />
</group>
</global>
--- metasyntax
## pos: 1 5
do {
my $r = Pugs::Runtime::Regex::get_variable( '$a' );
push @match,
$r->match( $s, $grammar, {p => $pos}, undef );
$pos = $match[-1]->to;
!$match[-1] != 1;
}
=== TEST 6: metasyntax <@...>
--- token: ' <@::foo> '
--- Layout
<global>
<group>
<metasyntax />
</group>
</global>
--- metasyntax
## pos: 1 9
do {
my $match;
for my $subrule ( @::foo ) {
$match = $subrule->match( $s, $grammar, { p => ( $pos ), positionals => [ ], args => {} }, undef );
last if $match;
}
if ( $match ) { $named{'::foo'} = $match;
$pos = $match->to;
1
}
else { 0 }
}
=== TEST 7: metasyntax <%...>
--- token: ' <%hi> '
--- Layout
<global>
<group>
<metasyntax>
<variable />
</metasyntax>
</group>
</global>
--- metasyntax
## pos: 1 6
do{
my $match =
## <variable />
;
if ( $match ) { $named{'hi'} = $match;
$pos = $match->to;
1
}
else { 0 }
}
--- variable
## pos: 1 6
do {
our $I1176;
our $I1176_sizes;
unless ( $I1176 ) {
my $hash = \%hi;
my %sizes = map { length($_) => 1 } keys %$hash;
$I1176_sizes = [ sort { $b <=> $a } keys %sizes ];
$I1176 = $hash;
}
my $match = 0;
my $key;
for ( @$I1176_sizes ) {
$key = ( $pos <= length( $s )
? substr( $s, $pos, $_ )
: '' );
if ( exists $I1176->{$key} ) {
#$named{KEY} = $key;
#$::_V6_MATCH_ = $m;
#print "m: ", Dumper( $::_V6_MATCH_->data )
# if ( $key eq 'until' );
$match = Pugs::Runtime::Regex::preprocess_hash( $I1176, $key )->( $s, $grammar, { p => ( $pos + $_ ), positionals => [ ], args => { KEY => $key } }, undef );
last if $match;
}
}
if ( $match ) {
$pos = $match->to;
#print "match: $key at $pos = ", Dumper( $match->data );
$bool = 1;
}; # else { $bool = 0 }
$match;
}
=== TEST 8: metasyntax
--- token: ' <{ return $0.sqrt }> '
--- Layout
<global>
<group>
<closure />
</group>
</global>
--- closure
## pos: 1 21
do {
local $::_V6_SUCCEED = 1;
$::_V6_MATCH_ = $m;
$m->data->{capture} = \( sub { return $_[0]->[0].sqrt }->( $m ) );
$bool = $::_V6_SUCCEED;
$::_V6_MATCH_ = $m if $bool;
return $m if $bool;
}
=== TEST 9: alt
--- token: 'a|b'
--- Layout
<global>
<alt>
<constant />
<constant />
</alt>
</global>
--- alt
## pos: 0 3
(
( $pad{I1178} = $pos or 1 )
&& (
## <constant />
)
|| (
( ( $bool = 1 ) && ( $pos = $pad{I1178} ) or 1 )
&&
## <constant />
)
)
=== TEST 10: special chars
--- token: "\\d \\s"
--- Layout
<global>
<concat>
<group>
<perl5 />
</group>
<perl5 />
</concat>
</global>
--- concat
## pos: 0 5
(
## <group />
&&
## <perl5 />
)
--- perl5
( ( substr( $s, $pos ) =~ m/^(\d)/ )
? ( $pos += length( $1 ) or 1 )
: 0
)
=== TEST 11: closures
--- token: " a { say 'hi' } "
--- Layout
<global>
<concat>
<group>
<constant />
</group>
<group>
<closure />
</group>
</concat>
</global>
--- closure
## pos: 3 15
do {
local $::_V6_SUCCEED = 1;
$::_V6_MATCH_ = $m;
sub { say 'hi' }->( $m );
1;
}
=== TEST 12: closure quantifier
--- token: " a**{2} "
--- Layout
<global>
<quant>
<constant />
<constant />
</quant>
</global>
--- quant
## pos: 0 8
(
( ( $pad{I1182} = $pos or 1 ) &&
## <constant />
|| ( ( $pos = $pad{I1182} ) && 0 ) ) && ( ( $pad{I1182} = $pos or 1 ) &&
## <constant />
|| ( ( $pos = $pad{I1182} ) && 0 ) )
)
=== TEST 13: quantifier +
--- token: " a+ "
--- Layout
<global>
<quant>
<constant />
<constant />
</quant>
</global>
--- quant
## pos: 0 4
(
( ( $pad{I1183} = $pos or 1 ) &&
## <constant />
|| ( ( $pos = $pad{I1183} ) && 0 ) )
&& do { while (
( ( $pad{I1183} = $pos or 1 ) &&
## <constant />
|| ( ( $pos = $pad{I1183} ) && 0 ) )) {}; $bool = 1 }
)
=== TEST 14: quantifier ?
--- token: " b? "
--- Layout
<global>
<quant>
<constant />
</quant>
</global>
--- quant
## pos: 0 4
(
( ( $pad{I1184} = $pos or 1 ) &&
## <constant />
|| ( ( $pos = $pad{I1184} ) && 0 ) )
|| ( $bool = 1 )
)
=== TEST 15: subrule (<foo>)
--- token: " <foo> "
--- Layout
<global>
<group>
<named_capture />
</group>
</global>
--- named_capture
## pos: 1 6
do {
my $prior = $::_V6_PRIOR_;
my $match =
$grammar->foo( $s, { p => $pos, positionals => [ ], args => {}, }, undef );
$::_V6_PRIOR_ = $prior;
if ( $match ) { $named{'foo'} = $match;
$pos = $match->to;
1
}
else { 0 }
}
=== TEST 16: subrule (<.foo>)
--- token: " <.foo> "
--- Layout
<global>
<group>
<metasyntax />
</group>
</global>
--- metasyntax
## pos: 1 7
do {
my $prior = $::_V6_PRIOR_;
my $match =
$grammar->foo( $s, { p => $pos, positionals => [ ], args => {}, }, undef );
$::_V6_PRIOR_ = $prior;
my $bool = (!$match != 1);
$pos = $match->to if $bool;
$match;
}
=== TEST 17: subrule (quanlified)
--- token: " <Bar.foo> "
--- Layout
<global>
<group>
<named_capture />
</group>
</global>
--- named_capture
## pos: 1 10
do {
my $prior = $::_V6_PRIOR_;
my $match =
Bar->foo( $s, { p => $pos, positionals => [ ], args => {}, }, undef );
$::_V6_PRIOR_ = $prior;
if ( $match ) { $named{'Bar.foo'} = $match;
$pos = $match->to;
1
}
else { 0 }
}
=== TEST 18: capure (...)
--- token: " (a) "
--- Layout
<global>
<group>
<capture>
<constant />
</capture>
</group>
</global>
--- capture
do{
my $hash = do {
my $bool = 1;
my $from = $pos;
my @match;
my %named;
$bool = 0 unless
## <constant />
;
{ str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }
};
my $bool = ${$hash->{'bool'}};
$match[ 0 ] = Pugs::Runtime::Match->new( $hash );
$bool;
}
=== TEST 19: named capure ( ... )
--- token: ' $abc := (a) '
--- Layout
<global>
<group>
<named_capture>
<capture>
<constant />
</capture>
</named_capture>
</group>
</global>
--- capture
do{
my $hash = do {
my $bool = 1;
my $from = $pos;
my @match;
my %named;
$bool = 0 unless
## <constant />
;
{ str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }
};
my $bool = ${$hash->{'bool'}};
$match[ 0 ] = Pugs::Runtime::Match->new( $hash );
$bool;
}
--- named_capture
## pos: 1 12
do{
my $match = Pugs::Runtime::Match->new( do {
my $bool = 1;
my $from = $pos;
my @match;
my %named;
$bool = 0 unless
## <capture />
;
{ str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }
} );
if ( $match ) { $named{'abc'} = $match;
$pos = $match->to;
1
}
else { 0 }
}
=== TEST 20: non-capture groups
--- token: ' [ a ] '
--- Layout
<global>
<group>
<group>
<constant />
</group>
</group>
</global>
--- constant
## pos: 3 4
( ( substr( $s, $pos, 1 ) eq 'a' )
? ( $pos += 1 or 1 )
: 0
)
=== TEST 20: non-capture groups
--- token: '[ a ]'
--- Layout
<global>
<group>
<constant />
</group>
</global>
--- constant
## pos: 2 3
( ( substr( $s, $pos, 1 ) eq 'a' )
? ( $pos += 1 or 1 )
: 0
)
=== TEST 21: named capture + [ ... ]
--- token: ' $a := [a] '
--- Layout
<global>
<group>
<named_capture>
<constant />
</named_capture>
</group>
</global>
--- named_capture
## pos: 1 10
do{
my $from = $pos;
my $bool =
## <constant />
;
my $match = Pugs::Runtime::Match->new(
{ str => \$s, from => \$from, match => [], named => {}, bool => \1, to => \(0+$pos), capture => undef }
); $named{'a'} = $match;
$bool
}
=== TEST 22:
--- token: ' .*? a '
--- Layout
<global>
<concat>
<quant>
<concat>
<negate>
<before>
<concat>
<group>
<constant />
</group>
</concat>
</before>
</negate>
<group>
<dot />
</group>
</concat>
</quant>
<group>
<constant />
</group>
</concat>
</global>
--- negate
## pos: 0 5
do{
my $pos1 = $pos;
do {
my $pos = $pos1;
my $from = $pos;
my @match;
my %named;
$bool =
## <before />
? 0 : 1;
$bool;
};
}