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 | CORE:regcomp (opcode) | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 12µs | 24µs | BEGIN@32 | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 10µs | 13µs | __PPIX_TOKEN__recognize | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 7µs | 12µs | BEGIN@33 | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 7µs | 29µs | BEGIN@37 | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 7µs | 35µs | BEGIN@38 | PPIx::Regexp::Token::Backreference::
1 | 1 | 1 | 7µs | 800µs | BEGIN@35 | PPIx::Regexp::Token::Backreference::
3 | 2 | 1 | 3µs | 3µs | CORE:qr (opcode) | PPIx::Regexp::Token::Backreference::
0 | 0 | 0 | 0s | 0s | __PPIX_LEXER__rebless | PPIx::Regexp::Token::Backreference::
0 | 0 | 0 | 0s | 0s | __PPIX_TOKENIZER__regexp | PPIx::Regexp::Token::Backreference::
0 | 0 | 0 | 0s | 0s | __PPIX_TOKENIZER__repl | PPIx::Regexp::Token::Backreference::
0 | 0 | 0 | 0s | 0s | __error | PPIx::Regexp::Token::Backreference::
0 | 0 | 0 | 0s | 0s | perl_version_introduced | PPIx::Regexp::Token::Backreference::
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 |