| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPIx/Regexp/Token/Backreference.pm |
| Statements | Executed 17 statements in 622µs |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 2 | 2 | 1 | 53µs | 53µs | PPIx::Regexp::Token::Backreference::CORE:regcomp (opcode) |
| 1 | 1 | 1 | 12µs | 24µs | PPIx::Regexp::Token::Backreference::BEGIN@32 |
| 1 | 1 | 1 | 10µs | 13µs | PPIx::Regexp::Token::Backreference::__PPIX_TOKEN__recognize |
| 1 | 1 | 1 | 7µs | 12µs | PPIx::Regexp::Token::Backreference::BEGIN@33 |
| 1 | 1 | 1 | 7µs | 29µs | PPIx::Regexp::Token::Backreference::BEGIN@37 |
| 1 | 1 | 1 | 7µs | 35µs | PPIx::Regexp::Token::Backreference::BEGIN@38 |
| 1 | 1 | 1 | 7µs | 800µs | PPIx::Regexp::Token::Backreference::BEGIN@35 |
| 3 | 2 | 1 | 3µs | 3µs | PPIx::Regexp::Token::Backreference::CORE:qr (opcode) |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Token::Backreference::__PPIX_LEXER__rebless |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Token::Backreference::__PPIX_TOKENIZER__regexp |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Token::Backreference::__PPIX_TOKENIZER__repl |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Token::Backreference::__error |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Token::Backreference::perl_version_introduced |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | =head1 NAME | ||||
| 2 | |||||
| 3 | PPIx::Regexp::Token::Backreference - Represent a back reference | ||||
| 4 | |||||
| 5 | =head1 SYNOPSIS | ||||
| 6 | |||||
| 7 | use PPIx::Regexp::Dumper; | ||||
| 8 | PPIx::Regexp::Dumper->new( 'qr{(foo|bar)baz\1}smx' ) | ||||
| 9 | ->print(); | ||||
| 10 | |||||
| 11 | =head1 INHERITANCE | ||||
| 12 | |||||
| 13 | C<PPIx::Regexp::Token::Backreference> is a | ||||
| 14 | L<PPIx::Regexp::Token::Reference|PPIx::Regexp::Token::Reference>. | ||||
| 15 | |||||
| 16 | C<PPIx::Regexp::Token::Backreference> has no descendants. | ||||
| 17 | |||||
| 18 | =head1 DESCRIPTION | ||||
| 19 | |||||
| 20 | This class represents back references of all sorts, both the traditional | ||||
| 21 | numbered variety and the Perl 5.010 named kind. | ||||
| 22 | |||||
| 23 | =head1 METHODS | ||||
| 24 | |||||
| 25 | This class provides no public methods beyond those provided by its | ||||
| 26 | superclass. | ||||
| 27 | |||||
| 28 | =cut | ||||
| 29 | |||||
| 30 | package PPIx::Regexp::Token::Backreference; | ||||
| 31 | |||||
| 32 | 2 | 19µs | 2 | 36µs | # spent 24µs (12+12) within PPIx::Regexp::Token::Backreference::BEGIN@32 which was called:
# once (12µs+12µs) by PPIx::Regexp::Tokenizer::BEGIN@15 at line 32 # spent 24µs making 1 call to PPIx::Regexp::Token::Backreference::BEGIN@32
# spent 12µs making 1 call to strict::import |
| 33 | 2 | 20µs | 2 | 16µs | # spent 12µs (7+4) within PPIx::Regexp::Token::Backreference::BEGIN@33 which was called:
# once (7µs+4µs) by PPIx::Regexp::Tokenizer::BEGIN@15 at line 33 # spent 12µs making 1 call to PPIx::Regexp::Token::Backreference::BEGIN@33
# spent 4µs making 1 call to warnings::import |
| 34 | |||||
| 35 | 2 | 24µs | 2 | 1.59ms | # spent 800µs (7+793) within PPIx::Regexp::Token::Backreference::BEGIN@35 which was called:
# once (7µs+793µs) by PPIx::Regexp::Tokenizer::BEGIN@15 at line 35 # spent 800µs making 1 call to PPIx::Regexp::Token::Backreference::BEGIN@35
# spent 793µs making 1 call to base::import |
| 36 | |||||
| 37 | 2 | 24µs | 2 | 51µs | # spent 29µs (7+22) within PPIx::Regexp::Token::Backreference::BEGIN@37 which was called:
# once (7µs+22µs) by PPIx::Regexp::Tokenizer::BEGIN@15 at line 37 # spent 29µs making 1 call to PPIx::Regexp::Token::Backreference::BEGIN@37
# spent 22µs making 1 call to Exporter::import |
| 38 | 1 | 200ns | # spent 35µs (7+28) within PPIx::Regexp::Token::Backreference::BEGIN@38 which was called:
# once (7µs+28µs) by PPIx::Regexp::Tokenizer::BEGIN@15 at line 41 | ||
| 39 | MINIMUM_PERL RE_CAPTURE_NAME | ||||
| 40 | TOKEN_LITERAL TOKEN_UNKNOWN | ||||
| 41 | 1 | 428µs | 2 | 62µs | }; # spent 35µs making 1 call to PPIx::Regexp::Token::Backreference::BEGIN@38
# spent 28µs making 1 call to Exporter::import |
| 42 | |||||
| 43 | 1 | 600ns | our $VERSION = '0.036'; | ||
| 44 | |||||
| 45 | # Return true if the token can be quantified, and false otherwise | ||||
| 46 | # sub can_be_quantified { return }; | ||||
| 47 | |||||
| 48 | { | ||||
| 49 | |||||
| 50 | 2 | 2µs | my %perl_version_introduced = ( | ||
| 51 | g => '5.009005', # \g1 \g-1 \g{1} \g{-1} | ||||
| 52 | k => '5.009005', # \k<name> \k'name' | ||||
| 53 | '?' => '5.009005', # (?P=name) (PCRE/Python) | ||||
| 54 | ); | ||||
| 55 | |||||
| 56 | sub perl_version_introduced { | ||||
| 57 | my ( $self ) = @_; | ||||
| 58 | return $perl_version_introduced{substr( $self->content(), 1, 1 )} || | ||||
| 59 | MINIMUM_PERL; | ||||
| 60 | } | ||||
| 61 | |||||
| 62 | } | ||||
| 63 | |||||
| 64 | my @external = ( # Recognition used externally | ||||
| 65 | 1 | 30µs | 2 | 17µs | [ qr{ \A \( \? P = ( @{[ RE_CAPTURE_NAME ]} ) \) }smxo, # spent 15µs making 1 call to PPIx::Regexp::Token::Backreference::CORE:regcomp
# spent 1µs making 1 call to PPIx::Regexp::Token::Backreference::CORE:qr |
| 66 | { is_named => 1 }, | ||||
| 67 | ], | ||||
| 68 | ); | ||||
| 69 | |||||
| 70 | my @recognize = ( # recognition used internally | ||||
| 71 | [ | ||||
| 72 | qr{ \A \\ (?: # numbered (including relative) | ||||
| 73 | ( \d+ ) | | ||||
| 74 | g (?: ( -? \d+ ) | \{ ( -? \d+ ) \} ) | ||||
| 75 | ) | ||||
| 76 | }smx, { is_named => 0 }, ], | ||||
| 77 | [ | ||||
| 78 | 1 | 51µs | 3 | 39µs | qr{ \A \\ (?: # named # spent 37µs making 1 call to PPIx::Regexp::Token::Backreference::CORE:regcomp
# spent 2µs making 2 calls to PPIx::Regexp::Token::Backreference::CORE:qr, avg 1µs/call |
| 79 | g [{] ( @{[ RE_CAPTURE_NAME ]} ) [}] | | ||||
| 80 | k (?: \< ( @{[ RE_CAPTURE_NAME ]} ) \> | # named with angles | ||||
| 81 | ' ( @{[ RE_CAPTURE_NAME ]} ) ' ) # or quotes | ||||
| 82 | ) | ||||
| 83 | }smxo, { is_named => 1 }, ], | ||||
| 84 | ); | ||||
| 85 | |||||
| 86 | # This must be implemented by tokens which do not recognize themselves. | ||||
| 87 | # The return is a list of list references. Each list reference must | ||||
| 88 | # contain a regular expression that recognizes the token, and optionally | ||||
| 89 | # a reference to a hash to pass to make_token as the class-specific | ||||
| 90 | # arguments. The regular expression MUST be anchored to the beginning of | ||||
| 91 | # the string. | ||||
| 92 | # spent 13µs (10+2) within PPIx::Regexp::Token::Backreference::__PPIX_TOKEN__recognize which was called:
# once (10µs+2µs) by base::import at line 102 of PPIx/Regexp/Token/Structure.pm | ||||
| 93 | 1 | 16µs | 1 | 2µs | return __PACKAGE__->isa( scalar caller ) ? # spent 2µs making 1 call to UNIVERSAL::isa |
| 94 | ( @external, @recognize ) : | ||||
| 95 | ( @external ); | ||||
| 96 | } | ||||
| 97 | |||||
| 98 | sub __PPIX_TOKENIZER__regexp { | ||||
| 99 | my ( $class, $tokenizer, $character ) = @_; | ||||
| 100 | |||||
| 101 | # PCRE/Python back references are handled in | ||||
| 102 | # PPIx::Regexp::Token::Structure, because they are parenthesized. | ||||
| 103 | |||||
| 104 | # All the other styles are escaped. | ||||
| 105 | $character eq '\\' | ||||
| 106 | or return; | ||||
| 107 | |||||
| 108 | foreach ( @recognize ) { | ||||
| 109 | my ( $re, $arg ) = @{ $_ }; | ||||
| 110 | my $accept = $tokenizer->find_regexp( $re ) or next; | ||||
| 111 | return $tokenizer->make_token( $accept, __PACKAGE__, $arg ); | ||||
| 112 | } | ||||
| 113 | |||||
| 114 | return; | ||||
| 115 | } | ||||
| 116 | |||||
| 117 | sub __PPIX_TOKENIZER__repl { | ||||
| 118 | my ( $class, $tokenizer, $character ) = @_; | ||||
| 119 | |||||
| 120 | $tokenizer->interpolates() and goto &__PPIX_TOKENIZER__regexp; | ||||
| 121 | |||||
| 122 | return; | ||||
| 123 | } | ||||
| 124 | |||||
| 125 | # Called by the lexer to disambiguate between captures, literals, and | ||||
| 126 | # whatever. We have to return the number of tokens reblessed to | ||||
| 127 | # TOKEN_UNKNOWN (i.e. either 0 or 1) because we get called after the | ||||
| 128 | # parse is finalized. | ||||
| 129 | sub __PPIX_LEXER__rebless { | ||||
| 130 | my ( $self, %arg ) = @_; | ||||
| 131 | |||||
| 132 | # Handle named back references | ||||
| 133 | if ( $self->is_named() ) { | ||||
| 134 | $arg{capture_name}{$self->name()} | ||||
| 135 | and return 0; | ||||
| 136 | return $self->__error(); | ||||
| 137 | } | ||||
| 138 | |||||
| 139 | # Get the absolute capture group number. | ||||
| 140 | my $absolute = $self->absolute(); | ||||
| 141 | |||||
| 142 | # If it is zero or negative, we have a relateive reference to a | ||||
| 143 | # non-existent capture group. | ||||
| 144 | $absolute <= 0 | ||||
| 145 | and return $self->__error(); | ||||
| 146 | |||||
| 147 | # If the absolute number is less than or equal to the maximum | ||||
| 148 | # capture group number, we are good. | ||||
| 149 | $absolute <= $arg{max_capture} | ||||
| 150 | and return 0; | ||||
| 151 | |||||
| 152 | # It's not a valid capture. If it's an octal literal, rebless it so. | ||||
| 153 | # Note that we can't rebless single-digit numbers, since they can't | ||||
| 154 | # be octal literals. | ||||
| 155 | my $content = $self->content(); | ||||
| 156 | if ( $content =~ m/ \A \\ \d{2,} \z /smx && $content !~ m/ [89] /smx ) { | ||||
| 157 | bless $self, TOKEN_LITERAL; | ||||
| 158 | return 0; | ||||
| 159 | } | ||||
| 160 | |||||
| 161 | # Anything else is an error. | ||||
| 162 | return $self->__error(); | ||||
| 163 | } | ||||
| 164 | |||||
| 165 | sub __error { | ||||
| 166 | my ( $self, $msg ) = @_; | ||||
| 167 | defined $msg | ||||
| 168 | or $msg = 'No corresponding capture group'; | ||||
| 169 | $self->{error} = $msg; | ||||
| 170 | bless $self, TOKEN_UNKNOWN; | ||||
| 171 | return 1; | ||||
| 172 | } | ||||
| 173 | |||||
| 174 | 1 | 7µs | 1; | ||
| 175 | |||||
| 176 | __END__ | ||||
sub PPIx::Regexp::Token::Backreference::CORE:qr; # opcode | |||||
sub PPIx::Regexp::Token::Backreference::CORE:regcomp; # opcode |