Benchmark-Perl-Formance-Cargo

 view release on metacpan or  search on metacpan

share/P6STD/RE_ast.pmc  view on Meta::CPAN

        my $self = shift;
        my ($node, $prefix, $continue) = splice @$self;
        bless $self, 'NFA::Node';
        $node->construct($self, $prefix, $continue);
    }
}

{
    package NFA::Node;
    sub reify { }
}

{
    package NFA::seq;
    sub new {
        my ($left, $right) = @_;
        my $literal = $left->{literal};
        my $litlen  = $left->{litlen};
        if ($literal) {
            $literal &&= $right->{literal};
            $litlen  +=  ($right->{litlen} // 0);
        }
        bless { left => $left, right => $right, literal => $literal,
            litlen => $litlen, fates => ($left->{fates} || $right->{fates}) },
            'NFA::seq';
    }

    sub construct {
        my ($self, $node, $pre_fates, $continue) = @_;

        $self->{left}->construct($node, $pre_fates, sub {
                my $mid_fates = shift;
                NFA::Lazy->new($self->{right}, $mid_fates, $continue);
            });
    }
}

#############################################################
# longest token set generator
#############################################################

#    $::DEBUG |= -1;
sub qm { my $s = shift;
    $s = $s->[0] if ref $s eq 'ARRAY';	# only count first token of circumfix or postcircumfix
    my $r = '';
    for (split(//,$s)) {
	if ($_ eq " ") { $r .= '\x20' }
	elsif ($_ eq "\t") { $r .= '\t' }
	elsif ($_ eq "\n") { $r .= '\n' }
	elsif ($_ =~ m/^\w$/) { $r .= $_ }
	elsif ($_ eq '<' | $_ eq '>') { $r .= $_ }
	else { $r .= '\\' . $_ }
    }
    $r;
}

sub here {
    return unless $::DEBUG & DEBUG::longest_token_pattern_generation;
    my $arg = shift;
    my $lvl = 0;
    while (caller($lvl)) { $lvl++ }
    my ($package, $file, $line, $subname, $hasargs) = caller(0);

    my $name = $package;   # . '::' . substr($subname,1);
    if (defined $arg) { 
	$name .= " " . $arg;
    }
    ::deb("\t", ':' x $lvl, ' ', $name, " [", $file, ":", $line, "]") if $::DEBUG & DEBUG::longest_token_pattern_generation;
}

{ package nfa;

# Rules: Don't call $cont more than once with the same fate.  Don't instantiate
# a node more than once with the same fate.
sub node {
    my $id = @::NFANODES;
    #::deb("creating direct node $id") if $::DEBUG & DEBUG::longest_token_pattern_generation;
    push @::NFANODES, [ $id, @_ ];
    $id;
}

sub gnode {
    my $id = @::NFANODES;
    #::deb("creating node $id via " . ref($_[0])) if $::DEBUG & DEBUG::longest_token_pattern_generation;
    push @::NFANODES, [ $id ];
    $_[0]->construct($::NFANODES[$id], $_[1], $_[2]);
    $id;
}

sub rgnode { my ($ob, $n, $f, $c) = @_;
    #::deb("forwarding node " . $n->[0] . " to " . ref($ob)) if $::DEBUG & DEBUG::longest_token_pattern_generation;
    $ob->construct($n, $f, $c);
}

sub nfa::null::construct { my ($self, $node, $fate, $cont) = @_;
    push @$node, $cont ? (undef, undef, $cont->($fate)) : ($fate);
}

sub nfa::imp::construct { my ($self, $node, $fate, $cont) = @_;
    push @$node, $fate;
}

our $NULL = bless({ m => [], nr => 0, l => 1, ll => 0 }, 'nfa::null');
our $IMP  = bless({ m => [], nr => 1, l => 0, ll => 0 }, 'nfa::imp');

# When a non-LTM alternation or quantifier is applied to a subregex, it becomes
# impossible to control where subsequent tokens match, so we can't copy fates.
sub nfa::horizon::construct { my ($self, $node, $fate, $cont) = @_;
    my @fate = @$fate;
    $fate[0] = 1;
    nfa::rgnode($self->{i}, $node, \@fate, $cont);
}
sub horizon { my ($inner) = @_;
    bless({ m => $inner->{m}, nr => $inner->{nr}, l => $inner->{l},
            ll => $inner->{ll}, i => $inner }, 'nfa::horizon');
}

sub method { my ($mp, $inner) = @_;
    bless({ %$inner, m => [ @{ $inner->{m} }, $mp ] }, ref($inner));
}

sub noreturn { $_[0]{nr} }



( run in 3.357 seconds using v1.01-cache-2.11-cpan-fe3c2283af0 )