File Coverage

blib/lib/PPIx/Regexp/Tokenizer.pm
Criterion Covered Total %
statement 497 525 94.6
branch 177 238 74.3
condition 44 64 68.7
subroutine 86 90 95.5
pod 29 29 100.0
total 833 946 88.0


line stmt bran cond sub pod time code
1             package PPIx::Regexp::Tokenizer;
2              
3 9     9   46 use strict;
  9         15  
  9         254  
4 9     9   30 use warnings;
  9         13  
  9         347  
5              
6 9     9   30 use base qw{ PPIx::Regexp::Support };
  9         11  
  9         685  
7              
8 9     9   36 use Carp qw{ carp croak confess };
  9         1472  
  9         485  
9 9     9   2032 use PPI::Document;
  9         782797  
  9         373  
10 9         1229 use PPIx::Regexp::Constant qw{
11             ARRAY_REF
12             CODE_REF
13             HASH_REF
14             LOCATION_LINE
15             LOCATION_CHARACTER
16             LOCATION_COLUMN
17             LOCATION_LOGICAL_LINE
18             MINIMUM_PERL
19             REGEXP_REF
20             TOKEN_LITERAL
21             TOKEN_UNKNOWN
22             @CARP_NOT
23 9     9   50 };
  9         17  
24 9     9   3775 use PPIx::Regexp::Token::Assertion ();
  9         22  
  9         194  
25 9     9   3693 use PPIx::Regexp::Token::Backreference ();
  9         44  
  9         245  
26 9     9   3321 use PPIx::Regexp::Token::Backtrack ();
  9         25  
  9         167  
27 9     9   3400 use PPIx::Regexp::Token::CharClass::POSIX ();
  9         22  
  9         173  
28 9     9   3620 use PPIx::Regexp::Token::CharClass::POSIX::Unknown ();
  9         25  
  9         168  
29 9     9   3751 use PPIx::Regexp::Token::CharClass::Simple ();
  9         22  
  9         213  
30 9     9   3561 use PPIx::Regexp::Token::Code ();
  9         26  
  9         168  
31 9     9   3381 use PPIx::Regexp::Token::Comment ();
  9         24  
  9         150  
32 9     9   3465 use PPIx::Regexp::Token::Condition ();
  9         23  
  9         241  
33 9     9   3253 use PPIx::Regexp::Token::Control ();
  9         23  
  9         171  
34 9     9   3316 use PPIx::Regexp::Token::Delimiter ();
  9         29  
  9         189  
35 9     9   3135 use PPIx::Regexp::Token::Greediness ();
  9         24  
  9         158  
36 9     9   3547 use PPIx::Regexp::Token::GroupType::Assertion ();
  9         26  
  9         205  
37 9     9   3741 use PPIx::Regexp::Token::GroupType::Atomic_Script_Run ();
  9         28  
  9         251  
38 9     9   3455 use PPIx::Regexp::Token::GroupType::BranchReset ();
  9         23  
  9         180  
39 9     9   3554 use PPIx::Regexp::Token::GroupType::Code ();
  9         27  
  9         172  
40 9     9   3794 use PPIx::Regexp::Token::GroupType::Modifier ();
  9         24  
  9         213  
41 9     9   3338 use PPIx::Regexp::Token::GroupType::NamedCapture ();
  9         24  
  9         189  
42 9     9   3256 use PPIx::Regexp::Token::GroupType::Script_Run ();
  9         22  
  9         190  
43 9     9   3439 use PPIx::Regexp::Token::GroupType::Subexpression ();
  9         20  
  9         183  
44 9     9   3568 use PPIx::Regexp::Token::GroupType::Switch ();
  9         23  
  9         162  
45 9     9   4008 use PPIx::Regexp::Token::Interpolation ();
  9         28  
  9         208  
46 9     9   4086 use PPIx::Regexp::Token::Literal ();
  9         26  
  9         236  
47 9     9   52 use PPIx::Regexp::Token::Modifier ();
  9         13  
  9         114  
48 9     9   3823 use PPIx::Regexp::Token::Operator ();
  9         27  
  9         170  
49 9     9   3826 use PPIx::Regexp::Token::Quantifier ();
  9         23  
  9         190  
50 9     9   63 use PPIx::Regexp::Token::Recursion ();
  9         13  
  9         100  
51 9     9   29 use PPIx::Regexp::Token::Structure ();
  9         11  
  9         82  
52 9     9   5136 use PPIx::Regexp::Token::Unknown ();
  9         23  
  9         144  
53 9     9   3491 use PPIx::Regexp::Token::Whitespace ();
  9         45  
  9         219  
54 9         513 use PPIx::Regexp::Util qw{
55             is_ppi_regexp_element
56             __instance
57 9     9   48 };
  9         16  
58              
59 9     9   45 use Scalar::Util qw{ looks_like_number };
  9         12  
  9         50904  
60              
61             our $VERSION = '0.091_01';
62              
63             our $DEFAULT_POSTDEREF;
64             defined $DEFAULT_POSTDEREF
65             or $DEFAULT_POSTDEREF = 1;
66              
67             {
68             # Names of classes containing tokenization machinery. There are few
69             # known ordering requirements, since each class recognizes its own,
70             # and I have tried to prevent overlap. Absent such constraints, the
71             # order is in perceived frequency of acceptance, to keep the search
72             # as short as possible. If I were conscientious I would gather
73             # statistics on this.
74             my @classes = ( # TODO make readonly when acceptable way appears
75             'PPIx::Regexp::Token::Literal',
76             'PPIx::Regexp::Token::Interpolation',
77             'PPIx::Regexp::Token::Control', # Note 1
78             'PPIx::Regexp::Token::CharClass::Simple', # Note 2
79             'PPIx::Regexp::Token::Quantifier',
80             'PPIx::Regexp::Token::Greediness',
81             'PPIx::Regexp::Token::CharClass::POSIX', # Note 3
82             'PPIx::Regexp::Token::Structure',
83             'PPIx::Regexp::Token::Assertion',
84             'PPIx::Regexp::Token::Backreference',
85             'PPIx::Regexp::Token::Operator', # Note 4
86             );
87              
88             # Note 1: If we are in quote mode ( \Q ... \E ), Control makes a
89             # literal out of anything it sees other than \E. So it
90             # needs to come before almost all other tokenizers. Not
91             # Literal, which already makes literals, and not
92             # Interpolation, which is legal in quote mode, but
93             # everything else.
94              
95             # Note 2: CharClass::Simple must come after Literal, because it
96             # relies on Literal to recognize a Unicode named character
97             # ( \N{something} ), so any \N that comes through to it
98             # must be the \N simple character class (which represents
99             # anything but a newline, and was introduced in Perl
100             # 5.11.0.
101              
102             # Note 3: CharClass::POSIX has to come before Structure, since both
103             # look for square brackets, and CharClass::POSIX is the
104             # more particular.
105              
106             # Note 4: Operator relies on Literal making the characters literal
107             # if they appear in a context where they can not be
108             # operators, and Control making them literals if quoting,
109             # so it must come after both.
110              
111             # Return the declared tokenizer classes.
112             sub __tokenizer_classes {
113 543     543   1820 return @classes;
114             }
115              
116             }
117              
118             {
119             my $errstr;
120              
121             sub new {
122 742     742 1 429410 my ( $class, $re, %args ) = @_;
123 742 50       1773 ref $class and $class = ref $class;
124              
125 742         1114 $errstr = undef;
126              
127             exists $args{default_modifiers}
128             and ARRAY_REF ne ref $args{default_modifiers}
129 742 50 66     2334 and do {
130 0         0 $errstr = 'default_modifiers must be an array reference';
131 0         0 return;
132             };
133              
134             my $self = {
135             index_locations => $args{index_locations}, # Index locations
136             capture => undef, # Captures from find_regexp.
137             content => undef, # The string we are tokenizing.
138             cookie => {}, # Cookies
139             cursor_curr => 0, # The current position in the string.
140             cursor_limit => undef, # The end of the portion of the
141             # string being tokenized.
142             cursor_orig => undef, # Position of cursor when tokenizer
143             # called. Used by get_token to prevent
144             # recursion.
145             cursor_modifiers => undef, # Position of modifiers.
146             default_modifiers => $args{default_modifiers} || [],
147             delimiter_finish => undef, # Finishing delimiter of regexp.
148             delimiter_start => undef, # Starting delimiter of regexp.
149             encoding => $args{encoding}, # Character encoding.
150             expect => undef, # Extra classes to expect.
151             expect_next => undef, # Extra classes as of next parse cycle
152             failures => 0, # Number of parse failures.
153             find => undef, # String for find_regexp
154             known => {}, # Known tokenizers, by mode.
155             location => $args{location},
156             match => undef, # Match from find_regexp.
157             mode => 'init', # Initialize
158             modifiers => [{}], # Modifier hash.
159             pending => [], # Tokens made but not returned.
160             prior => TOKEN_UNKNOWN, # Prior significant token.
161             source => $re, # The object we were initialized with.
162             strict => $args{strict}, # like "use re 'strict';".
163             trace => __PACKAGE__->__defined_or(
164 742   100     8551 $args{trace}, $ENV{PPIX_REGEXP_TOKENIZER_TRACE}, 0 ),
165             };
166              
167 742 100       2981 if ( __instance( $re, 'PPI::Element' ) ) {
    100          
168 11 50       36 is_ppi_regexp_element( $re )
169             or return __set_errstr( ref $re, 'not supported by', $class );
170             # TODO conditionalizstion on PPI class does not really
171             # belong here, but at the moment I have no other idea of
172             # where to put it.
173 11 50       85 $self->{content} = $re->isa( 'PPI::Token::HereDoc' ) ?
174             join( '', $re->content(), "\n", $re->heredoc(),
175             $re->terminator(), "\n" ) :
176             $re->content();
177             } elsif ( ref $re ) {
178 2         6 return __set_errstr( ref $re, 'not supported' );
179             } else {
180 729         1431 $self->{content} = $re;
181             }
182              
183 740         1524 bless $self, $class;
184              
185 740         2299 $self->{content} = $self->decode( $self->{content} );
186              
187 740         1517 $self->{cursor_limit} = length $self->{content};
188              
189             $self->{trace}
190 740 50       1685 and warn "\ntokenizing '$self->{content}'\n";
191              
192 740         2340 return $self;
193             }
194              
195             sub __set_errstr {
196 2     2   5 $errstr = join ' ', @_;
197 2         13 return;
198             }
199              
200             sub errstr {
201 2     2 1 5 return $errstr;
202             }
203              
204             }
205              
206             sub capture {
207 715     715 1 1086 my ( $self ) = @_;
208 715 100       1388 $self->{capture} or return;
209 694 50       1177 defined wantarray or return;
210 694 50       1042 return wantarray ? @{ $self->{capture} } : $self->{capture};
  694         2571  
211             }
212              
213             sub content {
214 1     1 1 3 my ( $self ) = @_;
215 1         4 return $self->{content};
216             }
217              
218             sub cookie {
219 10182     10182 1 13743 my ( $self, $name, @args ) = @_;
220 10182 50       13859 defined $name
221             or confess "Programming error - undefined cookie name";
222 10182 50       13529 if ( $self->{trace} ) {
223 0         0 local $" = ', ';
224 0         0 warn "cookie( '$name', @args )\n";
225             }
226 10182 100       25993 @args or return $self->{cookie}{$name};
227 721         1015 my $cookie = shift @args;
228 721 100       1903 if ( CODE_REF eq ref $cookie ) {
    50          
229 593         2056 return ( $self->{cookie}{$name} = $cookie );
230             } elsif ( defined $cookie ) {
231 0         0 confess "Programming error - cookie must be CODE ref or undef";
232             } else {
233 128         359 return delete $self->{cookie}{$name};
234             }
235             }
236              
237             # NOTE: Currently this is called only against
238             # COOKIE_LOOKAROUND_ASSERTION, once in PPIx::Token::GroupType::Assertion
239             # to prevent the cookie from being remade if it already exists, and once
240             # in PPIx::Regexp::Token::Assertion to determine if \K is inside a
241             # lookaround assertion. If it gets used other places, or if there is
242             # call for it, I should consider removing the underscores and
243             # documenting it as public.
244             sub __cookie_exists {
245 57     57   142 my ( $self, $name ) = @_;
246 57 50       111 defined $name
247             or confess "Programming error - undefined cookie name";
248 57         217 return $self->{cookie}{$name};
249             }
250              
251             sub default_modifiers {
252 0     0 1 0 my ( $self ) = @_;
253 0         0 return [ @{ $self->{default_modifiers} } ];
  0         0  
254             }
255              
256             sub __effective_modifiers {
257 334     334   614 my ( $self ) = @_;
258             HASH_REF eq ref $self->{effective_modifiers}
259 334 100       965 or return {};
260 326         469 return { %{ $self->{effective_modifiers} } };
  326         1055  
261             }
262              
263             sub encoding {
264 0     0 1 0 my ( $self ) = @_;
265 0         0 return $self->{encoding};
266             }
267              
268             sub expect {
269 330     330 1 910 my ( $self, @args ) = @_;
270              
271             @args
272 330 50       611 or return;
273              
274             $self->{expect_next} = [
275 330 50       565 map { m/ \A PPIx::Regexp:: /smx ? $_ : 'PPIx::Regexp::' . $_ }
  2602         5220  
276             @args
277             ];
278 330         644 $self->{expect} = undef;
279 330         620 return;
280             }
281              
282             sub failures {
283 8     8 1 14 my ( $self ) = @_;
284 8         27 return $self->{failures};
285             }
286              
287             sub find_matching_delimiter {
288 589     589 1 881 my ( $self ) = @_;
289 589   100     1769 $self->{cursor_curr} ||= 0;
290             my $start = substr
291             $self->{content},
292             $self->{cursor_curr},
293 589         1056 1;
294              
295 589         902 my $inx = $self->{cursor_curr};
296 589   66     1561 my $finish = (
297             my $bracketed = $self->close_bracket( $start ) ) || $start;
298              
299             =begin comment
300              
301             $self->{trace}
302             and warn "Find matching delimiter: Start with '$start' at $self->{cursor_curr}, end with '$finish' at or before $self->{cursor_limit}\n";
303              
304             =end comment
305              
306             =cut
307              
308 589         837 my $nest = 0;
309              
310 589         1421 while ( ++$inx < $self->{cursor_limit} ) {
311 6144         7188 my $char = substr $self->{content}, $inx, 1;
312              
313             =begin comment
314              
315             $self->{trace}
316             and warn " looking at '$char' at $inx, nest level $nest\n";
317              
318             =end comment
319              
320             =cut
321              
322 6144 100 100     16174 if ( $char eq '\\' && $finish ne '\\' ) {
    100 100        
    100          
323 317         492 ++$inx;
324             } elsif ( $bracketed && $char eq $start ) {
325 1         3 ++$nest;
326             } elsif ( $char eq $finish ) {
327             --$nest < 0
328 588 100       2140 and return $inx - $self->{cursor_curr};
329             }
330             }
331              
332 2         6 return;
333             }
334              
335             sub find_regexp {
336 16627     16627 1 20710 my ( $self, $regexp ) = @_;
337              
338 16627 50 0     25287 REGEXP_REF eq ref $regexp
339             or confess
340             'Argument is a ', ( ref $regexp || 'scalar' ), ' not a Regexp';
341              
342 16627 100       26811 defined $self->{find} or $self->_remainder();
343              
344 16627 100       64995 $self->{find} =~ $regexp
345             or return;
346              
347 1848         2366 my @capture;
348 1848         5469 foreach my $inx ( 0 .. $#+ ) {
349 4267 100 66     14995 if ( defined $-[$inx] && defined $+[$inx] ) {
350             push @capture, $self->{capture} = substr
351             $self->{find},
352 3778         16153 $-[$inx],
353             $+[$inx] - $-[$inx];
354             } else {
355 489         782 push @capture, undef;
356             }
357             }
358 1848         3539 $self->{match} = shift @capture;
359 1848         2881 $self->{capture} = \@capture;
360              
361             # The following circumlocution seems to be needed under Perl 5.13.0
362             # for reasons I do not fathom -- at least in the case where
363             # wantarray is false. RT 56864 details the symptoms, which I was
364             # never able to reproduce outside Perl::Critic. But returning $+[0]
365             # directly, the value could transmogrify between here and the
366             # calling module.
367             ## my @data = ( $-[0], $+[0] );
368             ## return wantarray ? @data : $data[1];
369 1848 50       6795 return wantarray ? ( $-[0] + 0, $+[0] + 0 ) : $+[0] + 0;
370             }
371              
372             sub get_mode {
373 2598     2598 1 3357 my ( $self ) = @_;
374 2598         4835 return $self->{mode};
375             }
376              
377             sub get_start_delimiter {
378 1794     1794 1 2158 my ( $self ) = @_;
379 1794         4817 return $self->{delimiter_start};
380             }
381              
382             sub get_token {
383 4133     4133 1 5338 my ( $self ) = @_;
384              
385             caller eq __PACKAGE__ or $self->{cursor_curr} > $self->{cursor_orig}
386 4133 50 66     9990 or confess 'Programming error - get_token() called without ',
387             'first calling make_token()';
388              
389 4133         6586 my $handler = '__PPIX_TOKENIZER__' . $self->{mode};
390              
391             my $code = $self->can( $handler )
392             or confess 'Programming error - ',
393             "Getting token in mode '$self->{mode}'. ",
394             "cursor_curr = $self->{cursor_curr}; ",
395             "cursor_limit = $self->{cursor_limit}; ",
396             "length( content ) = ", length $self->{content},
397 4133 50       12296 "; content = '$self->{content}'";
398              
399             my $character = substr(
400             $self->{content},
401             $self->{cursor_curr},
402 4133         8045 1
403             );
404              
405             $self->{trace}
406 4133 50       6677 and warn "get_token() got '$character' from $self->{cursor_curr}\n";
407              
408 4133         7417 return ( $code->( $self, $character ) );
409             }
410              
411             sub interpolates {
412 141     141 1 201 my ( $self ) = @_;
413 141         435 return $self->{delimiter_start} ne q{'};
414             }
415              
416             sub make_token {
417 5243     5243 1 9007 my ( $self, $length, $class, $arg ) = @_;
418 5243 100       7889 defined $class or $class = caller;
419              
420 5243 50       10080 if ( $length + $self->{cursor_curr} > $self->{cursor_limit} ) {
421             $length = $self->{cursor_limit} - $self->{cursor_curr}
422 0 0       0 or return;
423             }
424              
425 5243 50       12137 $class =~ m/ \A PPIx::Regexp:: /smx
426             or $class = 'PPIx::Regexp::' . $class;
427             my $content = substr
428             $self->{content},
429             $self->{cursor_curr},
430 5243         9237 $length;
431              
432             $self->{trace}
433 5243 50       8440 and warn "make_token( $length, '$class' ) => '$content'\n";
434 5243 50       8884 $self->{trace} > 1
435             and warn " make_token: cursor_curr = $self->{cursor_curr}; ",
436             "cursor_limit = $self->{cursor_limit}\n";
437             my $token = $class->__new( $content,
438             tokenizer => $self,
439 5243 100       11584 %{ $arg || {} } )
  5243 50       24455  
440             or return;
441              
442             $self->{index_locations}
443 5243 100       11697 and $self->_update_location( $token );
444              
445             $token->significant()
446 5243 100       11672 and $self->{expect} = undef;
447              
448 5243 100       18521 $token->isa( TOKEN_UNKNOWN ) and $self->{failures}++;
449              
450 5243         6991 $self->{cursor_curr} += $length;
451 5243         6815 $self->{find} = undef;
452 5243         6472 $self->{match} = undef;
453 5243         6176 $self->{capture} = undef;
454              
455 5243         6113 foreach my $name ( keys %{ $self->{cookie} } ) {
  5243         10120  
456 3615         4545 my $cookie = $self->{cookie}{$name};
457             $cookie->( $self, $token )
458 3615 100       6954 or delete $self->{cookie}{$name};
459             }
460              
461             # Record this token as the prior token if it is significant. We must
462             # do this after processing cookies, so that the cookies have access
463             # to the old token if they want.
464             $token->significant()
465 5243 100       9481 and $self->{prior_significant_token} = $token;
466              
467 5243         15170 return $token;
468             }
469              
470             sub match {
471 86     86 1 129 my ( $self ) = @_;
472 86         179 return $self->{match};
473             }
474              
475             sub modifier {
476 4932     4932 1 6313 my ( $self, $modifier ) = @_;
477             return PPIx::Regexp::Token::Modifier::__asserts(
478 4932         9458 $self->{modifiers}[-1], $modifier );
479             }
480              
481             sub modifier_duplicate {
482 292     292 1 468 my ( $self ) = @_;
483 292         514 push @{ $self->{modifiers} },
484 292         329 { %{ $self->{modifiers}[-1] } };
  292         874  
485 292         442 return;
486             }
487              
488             sub modifier_modify {
489 595     595 1 1180 my ( $self, %args ) = @_;
490              
491             # Modifier code is centralized in PPIx::Regexp::Token::Modifier
492             $self->{modifiers}[-1] =
493             PPIx::Regexp::Token::Modifier::__PPIX_TOKENIZER__modifier_modify(
494 595         1646 $self->{modifiers}[-1], \%args );
495              
496 595         991 return;
497              
498             }
499              
500             sub modifier_pop {
501 288     288 1 458 my ( $self ) = @_;
502 288         777 @{ $self->{modifiers} } > 1
503 288 100       331 and pop @{ $self->{modifiers} };
  282         480  
504 288         592 return;
505             }
506              
507             sub modifier_seen {
508 8     8 1 18 my ( $self, $modifier ) = @_;
509 8         11 foreach my $mod ( reverse @{ $self->{modifiers} } ) {
  8         18  
510 10 100       31 exists $mod->{$modifier}
511             and return 1;
512             }
513 5         16 return;
514             }
515              
516             sub next_token {
517 5780     5780 1 7247 my ( $self ) = @_;
518              
519             {
520              
521 5780 100       5955 if ( @{ $self->{pending} } ) {
  9896         9836  
  9896         15580  
522 5241         5455 return shift @{ $self->{pending} };
  5241         13296  
523             }
524              
525 4655 100       8833 if ( $self->{cursor_curr} >= $self->{cursor_limit} ) {
526             $self->{cursor_limit} >= length $self->{content}
527 1099 100       2944 and return;
528 560 50       1197 $self->{mode} eq 'finish' and return;
529 560         1459 $self->_set_mode( 'finish' );
530 560         927 $self->{cursor_limit} += length $self->{delimiter_finish};
531             }
532              
533 4116 50       7218 if ( my @tokens = $self->get_token() ) {
534 4116         4437 push @{ $self->{pending} }, @tokens;
  4116         6856  
535 4116         5920 redo;
536              
537             }
538              
539             }
540              
541 0         0 return;
542              
543             }
544              
545             sub peek {
546 379     379 1 546 my ( $self, $offset ) = @_;
547 379 100       621 defined $offset or $offset = 0;
548 379 50       645 $offset < 0 and return;
549 379         519 $offset += $self->{cursor_curr};
550 379 50       608 $offset >= $self->{cursor_limit} and return;
551 379         1210 return substr $self->{content}, $offset, 1;
552             }
553              
554             sub ppi_document {
555 83     83 1 142 my ( $self ) = @_;
556              
557 83 50       151 defined $self->{find} or $self->_remainder();
558              
559 83         427 return PPI::Document->new( \"$self->{find}" );
560             }
561              
562             sub prior_significant_token {
563 2413     2413 1 3188 my ( $self, $method, @args ) = @_;
564 2413 100       3266 defined $method or return $self->{prior_significant_token};
565             $self->{prior_significant_token}->can( $method )
566             or confess 'Programming error - ',
567             ( ref $self->{prior_significant_token} ||
568 2394 50 0     6545 $self->{prior_significant_token} ),
569             ' does not support method ', $method;
570 2394         5434 return $self->{prior_significant_token}->$method( @args );
571             }
572              
573             # my $length = $token->__recognize_postderef( $tokenizer, $iterator ).
574             #
575             # This method is private to the PPIx-Regexp package, and may be changed
576             # or retracted without warning. What it does is to recognize postfix
577             # dereferences. It returns the length in characters of the first postfix
578             # dereference found, or a false value if none is found.
579             #
580             # The optional $iterator argument can be one of the following:
581             # - A code reference, which will be called to provide PPI::Element
582             # objects to be checked to see if they represent a postfix
583             # dereference.
584             # - A PPI::Element, which is checked to see if it is a postfix
585             # dereference.
586             # - Undef, or omitted, in which case ppi() is called on the invocant,
587             # and everything that follows the '->' operator is checked to see if
588             # it is a postfix dereference.
589             # - Anything else results in an exception and stack trace.
590              
591             {
592             sub __recognize_postderef {
593 149     149   251 my ( $self, $token, $iterator ) = @_;
594              
595             # Note that if ppi() gets called I have to hold a reference to
596             # the returned object until I am done with all its children.
597 149         208 my $ppi;
598 149 100       305 if ( ! defined $iterator ) {
    50          
    0          
599              
600             # This MUST be done before ppi() is called.
601             $self->{index_locations}
602 145 100       296 and $self->_update_location( $token );
603              
604 145         411 $ppi = $token->ppi();
605 29         6493 my @ops = grep { '->' eq $_->content() } @{
606 145 100       263 $ppi->find( 'PPI::Token::Operator' ) || [] };
  145         488  
607             $iterator = sub {
608 151 100   151   617 my $op = shift @ops
609             or return;
610 15         62 return $op->snext_sibling();
611 145         30750 };
612             } elsif ( $iterator->isa( 'PPI::Element' ) ) {
613 4         9 my @eles = ( $iterator );
614             $iterator = sub {
615 4     4   12 return shift @eles;
616 4         11 };
617             } elsif ( CODE_REF ne ref $iterator ) {
618 0         0 confess 'Programming error - Iterator not understood';
619             }
620              
621 149         539 my $accept = $token->__postderef_accept_cast();
622              
623 149         284 while ( my $elem = $iterator->() ) {
624              
625 19         524 my $content = $elem->content();
626              
627             # As of PPI 1.238, all postfix dereferences are parsed as
628             # casts. So if we find a cast of the correct content we have
629             # a postfix deref.
630 19 100       149 $elem->isa( 'PPI::Token::Cast' )
631             or next;
632              
633 15 100       70 if ( $content =~ m/ ( .* ) \* \z /smx ) {
    50          
634             # If we're an acceptable cast ending in a glob, accept
635             # it.
636 10 100       96 $accept->{$1}
637             and return length $content;
638             } elsif ( $accept->{$content} ) {
639             # If we're an acceptable cast followed by a subscript,
640             # we're a slice -- accept both cast and subscript.
641 5 50       23 my $next = $elem->snext_sibling()
642             or next;
643 5 50       108 $next->isa( 'PPI::Structure::Subscript' )
644             or next;
645 5         20 return length( $content ) + length( $next->content() );
646             }
647              
648             # Otherwise, we're not a postfix dereference; try the next
649             # iteration.
650             }
651              
652             # No postfix dereference found.
653 136         649 return;
654             }
655             }
656              
657             sub significant {
658 0     0 1 0 return 1;
659             }
660              
661             sub strict {
662 4     4 1 9 my ( $self ) = @_;
663 4         21 return $self->{strict};
664             }
665              
666             sub _known_tokenizers {
667 3036     3036   4003 my ( $self ) = @_;
668              
669 3036         3826 my $mode = $self->{mode};
670              
671 3036         3380 my @expect;
672 3036 100       4854 if ( $self->{expect_next} ) {
673 328         538 $self->{expect} = $self->{expect_next};
674 328         481 $self->{expect_next} = undef;
675             }
676 3036 100       4661 if ( $self->{expect} ) {
677             @expect = $self->_known_tokenizer_check(
678 334         422 @{ $self->{expect} } );
  334         707  
679             }
680              
681             exists $self->{known}{$mode} and return (
682 3036 100       5800 @expect, @{ $self->{known}{$mode} } );
  2493         7745  
683              
684 543         1158 my @found = $self->_known_tokenizer_check(
685             $self->__tokenizer_classes() );
686              
687 543         1630 $self->{known}{$mode} = \@found;
688 543         1610 return (@expect, @found);
689             }
690              
691             sub _known_tokenizer_check {
692 877     877   2251 my ( $self, @args ) = @_;
693              
694 877         1300 my $handler = '__PPIX_TOKENIZER__' . $self->{mode};
695 877         928 my @found;
696              
697 877         1258 foreach my $class ( @args ) {
698              
699 8611 100       31605 $class->can( $handler ) or next;
700 8408         10939 push @found, $class;
701              
702             }
703              
704 877         3516 return @found;
705             }
706              
707             sub tokens {
708 205     205 1 408 my ( $self ) = @_;
709              
710 205         272 my @rslt;
711 205         578 while ( my $token = $self->next_token() ) {
712 1933         3367 push @rslt, $token;
713             }
714              
715 205         1264 return @rslt;
716             }
717              
718             # $self->_deprecation_notice( $type, $name );
719             #
720             # This method centralizes deprecation. Type is 'attribute' or
721             # 'method'. Deprecation is driven of the %deprecate hash. Values
722             # are:
723             # false - no warning
724             # 1 - warn on first use
725             # 2 - warn on each use
726             # 3 - die on each use.
727             #
728             # $self->_deprecation_in_progress( $type, $name )
729             #
730             # This method returns true if the deprecation is in progress. In
731             # fact it returns the deprecation level.
732              
733             =begin comment
734              
735             {
736              
737             my %deprecate = (
738             attribute => {
739             postderef => 3,
740             },
741             );
742              
743             sub _deprecation_notice {
744             my ( undef, $type, $name, $repl ) = @_; # Invocant unused
745             $deprecate{$type} or return;
746             $deprecate{$type}{$name} or return;
747             my $msg = sprintf 'The %s %s is %s', $name, $type,
748             $deprecate{$type}{$name} > 2 ? 'removed' : 'deprecated';
749             defined $repl
750             and $msg .= "; use $repl instead";
751             $deprecate{$type}{$name} >= 3
752             and croak $msg;
753             warnings::enabled( 'deprecated' )
754             and carp $msg;
755             $deprecate{$type}{$name} == 1
756             and $deprecate{$type}{$name} = 0;
757             return;
758             }
759              
760             sub _deprecation_in_progress {
761             my ( $self, $type, $name ) = @_;
762             $deprecate{$type} or return;
763             return $deprecate{$type}{$name};
764             }
765              
766             }
767              
768             =end comment
769              
770             =cut
771              
772             sub _remainder {
773 3623     3623   4624 my ( $self ) = @_;
774              
775             $self->{cursor_curr} > $self->{cursor_limit}
776 3623 50       6578 and confess "Programming error - Trying to find past end of string";
777             $self->{find} = substr(
778             $self->{content},
779             $self->{cursor_curr},
780             $self->{cursor_limit} - $self->{cursor_curr}
781 3623         7985 );
782              
783 3623         4503 return;
784             }
785              
786             sub _make_final_token {
787 10     10   31 my ( $self, $len, $class, $arg ) = @_;
788 10         28 my $token = $self->make_token( $len, $class, $arg );
789 10         27 $self->_set_mode( 'kaput' );
790 10         47 return $token;
791             }
792              
793             sub _set_mode {
794 1657     1657   2350 my ( $self, $mode ) = @_;
795             $self->{trace}
796 1657 50       2821 and warn "Tokenizer going from mode $self->{mode} to $mode\n";
797 1657         2168 $self->{mode} = $mode;
798 1657 100       2947 if ( 'kaput' eq $mode ) {
799             $self->{cursor_curr} = $self->{cursor_limit} =
800 537         949 length $self->{content};
801             }
802 1657         2115 return;
803             }
804              
805             sub __init_error {
806 10     10   18 my ( $self , $err ) = @_;
807 10 100       22 defined $err
808             or $err = 'Tokenizer found illegal first characters';
809             return $self->_make_final_token(
810 10         47 length $self->{content}, TOKEN_UNKNOWN, {
811             error => $err,
812             },
813             );
814             }
815              
816             sub _update_location {
817 107     107   161 my ( $self, $token ) = @_;
818             $token->{location} # Idempotent
819 107 100       184 and return;
820 105   66     213 my $loc = $self->{_location} ||= do {
821             my %loc = (
822             location => $self->{location},
823 12         35 );
824 12 100       37 if ( __instance( $self->{source}, 'PPI::Element' ) ) {
825 11   33     80 $loc{location} ||= $self->{source}->location();
826 11 50       1584 if ( my $doc = $self->{source}->document() ) {
827 11         297 $loc{tab_width} = $doc->tab_width();
828             }
829             }
830 12   100     90 $loc{tab_width} ||= 1;
831 12         44 \%loc;
832             };
833             $loc->{location}
834 105 50       184 or return;
835 105         121 $token->{location} = [ @{ $loc->{location} } ];
  105         279  
836 105 50       243 if ( defined( my $content = $token->content() ) ) {
837              
838 105         119 my $lines;
839 105         237 pos( $content ) = 0;
840 105         257 $lines++ while $content =~ m/ \n /smxgc;
841 105 100       176 if ( pos $content ) {
842 2         4 $loc->{location}[LOCATION_LINE] += $lines;
843 2         5 $loc->{location}[LOCATION_LOGICAL_LINE] += $lines;
844             $loc->{location}[LOCATION_CHARACTER] =
845 2         4 $loc->{location}[LOCATION_COLUMN] = 1;
846             }
847              
848 105 100       225 if ( my $chars = length( $content ) - pos( $content ) ) {
849 102         145 $loc->{location}[LOCATION_CHARACTER] += $chars;
850 102 100 100     271 if ( $loc->{tab_width} > 1 && $content =~ m/ \t /smx ) {
851 5         8 my $pos = $loc->{location}[LOCATION_COLUMN];
852 5         6 my $tab_width = $loc->{tab_width};
853             # Stolen shamelessly from PPI::Document::_visual_length
854 5         6 my ( $vis_inc );
855 5         14 foreach my $part ( split /(\t)/, $content ) {
856 10 100       14 if ($part eq "\t") {
857 5         9 $vis_inc = $tab_width - ($pos-1) % $tab_width;
858             } else {
859 5         6 $vis_inc = length $part;
860             }
861 10         12 $pos += $vis_inc;
862             }
863 5         9 $loc->{location}[LOCATION_COLUMN] = $pos;
864             } else {
865 97         139 $loc->{location}[LOCATION_COLUMN] += $chars;
866             }
867             }
868              
869             }
870 105         191 return;
871             }
872              
873             sub __PPIX_TOKENIZER__init {
874 537     537   970 my ( $self ) = @_;
875              
876 537 50       2572 $self->find_regexp(
877             qr{ \A ( \s* ) ( qr | m | s )? ( \s* ) ( . ) }smx )
878             or return $self->__init_error();
879              
880 537         1878 my ( $leading_white, $type, $next_white, $delim_start ) = $self->capture();
881              
882 537 100       1344 defined $type
883             or $type = '';
884              
885 537 100 100     2239 $type
886             or $delim_start =~ m< \A [/?] \z >smx
887             or return $self->__init_error();
888 531 100 100     1968 $type
      100        
889             and not $next_white
890             and $delim_start =~ m< \A \w \z >smx
891             and return $self->__init_error();
892              
893 529         1297 $self->{type} = $type;
894              
895 529         700 my @tokens;
896              
897 529 100       1242 '' ne $leading_white
898             and push @tokens, $self->make_token( length $leading_white,
899             'PPIx::Regexp::Token::Whitespace' );
900 529         1535 push @tokens, $self->make_token( length $type,
901             'PPIx::Regexp::Token::Structure' );
902 529 100       1244 '' ne $next_white
903             and push @tokens, $self->make_token( length $next_white,
904             'PPIx::Regexp::Token::Whitespace' );
905              
906 529         933 $self->{delimiter_start} = $delim_start;
907              
908             $self->{trace}
909 529 50       1177 and warn "Tokenizer found regexp start delimiter '$delim_start' at $self->{cursor_curr}\n";
910              
911 529 50       1155 if ( my $offset = $self->find_matching_delimiter() ) {
912 529         891 my $cursor_limit = $self->{cursor_curr} + $offset;
913             $self->{trace}
914 529 50       964 and warn "Tokenizer found regexp end delimiter at $cursor_limit\n";
915 529 100       1404 if ( $self->__number_of_extra_parts() ) {
916             ### my $found_embedded_comments;
917 46 100       113 if ( $self->close_bracket(
918             $self->{delimiter_start} ) ) {
919             pos $self->{content} = $self->{cursor_curr} +
920 7         28 $offset + 1;
921             # If we're bracketed, there may be Perl comments between
922             # the regex and the replacement. PPI gets the parse
923             # wrong as of 1.220, but if we get the handling of the
924             # underlying string right, we will Just Work when PPI
925             # gets it right.
926 7         43 while ( $self->{content} =~
927             m/ \G \s* \n \s* \# [^\n]* /smxgc ) {
928             ## $found_embedded_comments = 1;
929             }
930 7         23 $self->{content} =~ m/ \s* /smxgc;
931             } else {
932             pos $self->{content} = $self->{cursor_curr} +
933 39         145 $offset;
934             }
935             # Localizing cursor_curr and delimiter_start would be
936             # cleaner, but I don't want the old values restored if a
937             # parse error occurs.
938 46         96 my $cursor_curr = $self->{cursor_curr};
939 46         96 my $delimiter_start = $self->{delimiter_start};
940 46         88 $self->{cursor_curr} = pos $self->{content};
941             $self->{delimiter_start} = substr
942             $self->{content},
943             $self->{cursor_curr},
944 46         121 1;
945             $self->{trace}
946 46 50       98 and warn "Tokenizer found replacement start delimiter '$self->{delimiter_start}' at $self->{cursor_curr}\n";
947 46 100       87 if ( my $s_off = $self->find_matching_delimiter() ) {
948             $self->{cursor_modifiers} =
949 44         95 $self->{cursor_curr} + $s_off + 1;
950             $self->{trace}
951 44 50       95 and warn "Tokenizer found replacement end delimiter at @{[
952 0         0 $self->{cursor_curr} + $s_off ]}\n";
953 44         103 $self->{cursor_curr} = $cursor_curr;
954 44         85 $self->{delimiter_start} = $delimiter_start;
955             } else {
956             $self->{trace}
957 2 50       7 and warn 'Tokenizer failed to find replacement',
958             "end delimiter starting at $self->{cursor_curr}\n";
959 2         3 $self->{cursor_curr} = 0;
960             # TODO If I were smart enough here I could check for
961             # PPI mis-parses like s{foo}
962             # #{bar}
963             # {baz}
964             # here, doing so if $found_embedded_comments (commented
965             # out above) is true. The problem is that there seem to
966             # as many mis-parses as there are possible delimiters.
967 2         6 return $self->__init_error(
968             'Tokenizer found mismatched replacement delimiters',
969             );
970             }
971             } else {
972 483         974 $self->{cursor_modifiers} = $cursor_limit + 1;
973             }
974 527         960 $self->{cursor_limit} = $cursor_limit;
975             } else {
976 0         0 $self->{cursor_curr} = 0;
977             return $self->_make_final_token(
978 0         0 length( $self->{content} ), TOKEN_UNKNOWN, {
979             error => 'Tokenizer found mismatched regexp delimiters',
980             },
981             );
982             }
983              
984             {
985             # We have to instantiate the trailing tokens now so we can
986             # figure out what modifiers are in effect. But we can't
987             # index their locations (if desired) because they are being
988             # instantiated out of order
989              
990 527         683 local $self->{index_locations} = 0;
  527         1070  
991              
992 527         710 my @mods = @{ $self->{default_modifiers} };
  527         988  
993 527         1576 pos $self->{content} = $self->{cursor_modifiers};
994 527         1100 local $self->{cursor_curr} = $self->{cursor_modifiers};
995 527         938 local $self->{cursor_limit} = length $self->{content};
996 527         593 my @trailing;
997             {
998 527         586 my $len = $self->find_regexp( qr{ \A [[:lower:]]* }smx );
  527         1741  
999 527         1349 push @trailing, $self->make_token( $len,
1000             'PPIx::Regexp::Token::Modifier' );
1001             }
1002 527 100       1422 if ( my $len = $self->find_regexp( qr{ \A \s+ }smx ) ) {
1003 1         3 push @trailing, $self->make_token( $len,
1004             'PPIx::Regexp::Token::Whitespace' );
1005             }
1006 527 100       1359 if ( my $len = $self->find_regexp( qr{ \A .+ }smx ) ) {
1007 1         6 push @trailing, $self->make_token( $len, TOKEN_UNKNOWN, {
1008             error => 'Trailing characters after expression',
1009             } );
1010             }
1011 527         1292 $self->{trailing_tokens} = \@trailing;
1012 527         1183 push @mods, $trailing[0]->content();
1013             $self->{effective_modifiers} =
1014 527         966 PPIx::Regexp::Token::Modifier::__aggregate_modifiers (
1015             @mods );
1016             $self->{modifiers} = [
1017 527         821 { %{ $self->{effective_modifiers} } },
  527         2403  
1018             ];
1019             }
1020              
1021             $self->{delimiter_finish} = substr
1022             $self->{content},
1023             $self->{cursor_limit},
1024 527         1221 1;
1025              
1026 527         1107 push @tokens, $self->make_token( 1,
1027             'PPIx::Regexp::Token::Delimiter' );
1028              
1029 527         1520 $self->_set_mode( 'regexp' );
1030              
1031 527         727 $self->{find} = undef;
1032              
1033 527         1800 return @tokens;
1034             }
1035              
1036             # Match the initial part of the regexp including any leading white
1037             # space. The initial delimiter is the first thing not consumed, though
1038             # we check it for sanity.
1039             sub __initial_match {
1040 0     0   0 my ( $self ) = @_;
1041              
1042 0 0       0 $self->find_regexp(
1043             qr{ \A ( \s* ) ( qr | m | s )? ( \s* ) (?: [^\w\s] ) }smx )
1044             or return;
1045              
1046 0         0 my ( $leading_white, $type, $next_white ) = $self->capture();
1047              
1048 0 0       0 defined $type
1049             or $type = '';
1050              
1051 0         0 $self->{type} = $type;
1052              
1053 0         0 my @tokens;
1054              
1055 0 0       0 '' ne $leading_white
1056             and push @tokens, $self->make_token( length $leading_white,
1057             'PPIx::Regexp::Token::Whitespace' );
1058 0         0 push @tokens, $self->make_token( length $type,
1059             'PPIx::Regexp::Token::Structure' );
1060 0 0       0 '' ne $next_white
1061             and push @tokens, $self->make_token( length $next_white,
1062             'PPIx::Regexp::Token::Whitespace' );
1063              
1064 0         0 return @tokens;
1065             }
1066              
1067             {
1068             my %extra_parts = (
1069             s => 1,
1070             );
1071              
1072             # Return the number of extra delimited parts. This will be 0 except
1073             # for s///, which will be 1.
1074             sub __number_of_extra_parts {
1075 855     855   1272 my ( $self ) = @_;
1076 855   100     2901 return $extra_parts{$self->{type}} || 0;
1077             }
1078             }
1079              
1080             {
1081             my @part_class = qw{
1082             PPIx::Regexp::Structure::Regexp
1083             PPIx::Regexp::Structure::Replacement
1084             };
1085              
1086             # Return the classes for the parts of the expression.
1087             sub __part_classes {
1088 326     326   574 my ( $self ) = @_;
1089 326         745 my $max = $self->__number_of_extra_parts();
1090 326         1261 return @part_class[ 0 .. $max ];
1091             }
1092             }
1093              
1094             sub __PPIX_TOKENIZER__regexp {
1095 3036     3036   4584 my ( $self, $character ) = @_;
1096              
1097 3036         3895 my $mode = $self->{mode};
1098 3036         3618 my $handler = '__PPIX_TOKENIZER__' . $mode;
1099              
1100 3036         4149 $self->{cursor_orig} = $self->{cursor_curr};
1101 3036         5401 foreach my $class ( $self->_known_tokenizers() ) {
1102 13478         38914 my @tokens = grep { $_ } $class->$handler( $self, $character );
  3867         7101  
1103             $self->{trace}
1104 13478 50       19348 and warn $class, "->$handler( \$self, '$character' )",
1105             " => (@tokens)\n";
1106             @tokens
1107             and return ( map {
1108 13478 100       20181 ref $_ ? $_ : $self->make_token( $_,
  3033 100       8705  
1109             $class ) } @tokens );
1110             }
1111              
1112             # Find a fallback processor for the character.
1113 27   33     187 my $fallback = __PACKAGE__->can( '__PPIX_TOKEN_FALLBACK__' . $mode )
1114             || __PACKAGE__->can( '__PPIX_TOKEN_FALLBACK__regexp' )
1115             || confess "Programming error - unable to find fallback for $mode";
1116 27         68 return $fallback->( $self, $character );
1117             }
1118              
1119             *__PPIX_TOKENIZER__repl = \&__PPIX_TOKENIZER__regexp;
1120              
1121             sub __PPIX_TOKEN_FALLBACK__regexp {
1122 18     18   50 my ( $self, $character ) = @_;
1123              
1124             # As a fallback in regexp mode, any escaped character is a literal.
1125 18 100 66     100 if ( $character eq '\\'
1126             && $self->{cursor_limit} - $self->{cursor_curr} > 1
1127             ) {
1128 2         7 return $self->make_token( 2, TOKEN_LITERAL );
1129             }
1130              
1131             # Any normal character is unknown.
1132 16         64 return $self->make_token( 1, TOKEN_UNKNOWN, {
1133             error => 'Tokenizer found unexpected literal',
1134             },
1135             );
1136             }
1137              
1138             sub __PPIX_TOKEN_FALLBACK__repl {
1139 9     9   16 my ( $self, $character ) = @_;
1140              
1141             # As a fallback in replacement mode, any escaped character is a literal.
1142 9 100 66     33 if ( $character eq '\\'
1143             && defined ( my $next = $self->peek( 1 ) ) ) {
1144              
1145 5 0 33     11 if ( $self->interpolates() || $next eq q<'> || $next eq '\\' ) {
      33        
1146 5         15 return $self->make_token( 2, TOKEN_LITERAL );
1147             }
1148 0         0 return $self->make_token( 1, TOKEN_LITERAL );
1149             }
1150              
1151             # So is any normal character.
1152 4         9 return $self->make_token( 1, TOKEN_LITERAL );
1153             }
1154              
1155             sub __PPIX_TOKENIZER__finish {
1156 560     560   937 my ( $self ) = @_; # $character unused
1157              
1158             $self->{cursor_limit} > length $self->{content}
1159 560 50       1337 and confess "Programming error - ran off string";
1160              
1161             my @tokens = $self->make_token( length $self->{delimiter_finish},
1162 560         1326 'PPIx::Regexp::Token::Delimiter' );
1163              
1164 560 100       1290 if ( $self->{cursor_curr} == $self->{cursor_modifiers} ) {
1165              
1166             # We are out of string. Add the trailing tokens (created when we
1167             # did the initial bracket scan) and close up shop.
1168            
1169 516         1263 push @tokens, $self->_get_trailing_tokens();
1170              
1171 516         1004 $self->_set_mode( 'kaput' );
1172              
1173             } else {
1174              
1175             # Clear the cookies, because we are going around again.
1176 44         182 $self->{cookie} = {};
1177              
1178             # Move the cursor limit to just before the modifiers.
1179 44         104 $self->{cursor_limit} = $self->{cursor_modifiers} - 1;
1180              
1181             # If the preceding regular expression was bracketed, we need to
1182             # consume possible whitespace and find another delimiter.
1183              
1184 44 100       138 if ( $self->close_bracket( $self->{delimiter_start} ) ) {
1185 7         15 my $accept;
1186             # If we are bracketed, there can be honest-to-God Perl
1187             # comments between the regexp and the replacement, not just
1188             # regexp comments. As of version 1.220, PPI does not get
1189             # this parse right, but if we can handle this is a string,
1190             # then we will Just Work when PPI gets itself straight.
1191 7         31 while ( $self->find_regexp(
1192             qr{ \A ( \s* \n \s* ) ( \# [^\n]* \n ) }smx ) ) {
1193 2         8 my ( $white_space, $comment ) = $self->capture();
1194 2         5 push @tokens, $self->make_token(
1195             length $white_space,
1196             'PPIx::Regexp::Token::Whitespace',
1197             ), $self->make_token(
1198             length $comment,
1199             'PPIx::Regexp::Token::Comment',
1200             );
1201             }
1202 7 100       24 $accept = $self->find_regexp( qr{ \A \s+ }smx )
1203             and push @tokens, $self->make_token(
1204             $accept, 'PPIx::Regexp::Token::Whitespace' );
1205 7         22 my $character = $self->peek();
1206 7         14 $self->{delimiter_start} = $character;
1207 7         16 push @tokens, $self->make_token(
1208             1, 'PPIx::Regexp::Token::Delimiter' );
1209             $self->{delimiter_finish} = substr
1210             $self->{content},
1211 7         24 $self->{cursor_limit} - 1,
1212             1;
1213             }
1214              
1215 44 100       93 if ( $self->modifier( 'e*' ) ) {
1216             # With /e or /ee, the replacement portion is code. We make
1217             # it all into one big PPIx::Regexp::Token::Code, slap on the
1218             # trailing delimiter and modifiers, and return it all.
1219             push @tokens, $self->make_token(
1220             $self->{cursor_limit} - $self->{cursor_curr},
1221 11         51 'PPIx::Regexp::Token::Code',
1222             { perl_version_introduced => MINIMUM_PERL },
1223             );
1224 11         35 $self->{cursor_limit} = length $self->{content};
1225 11         31 push @tokens, $self->make_token( 1,
1226             'PPIx::Regexp::Token::Delimiter' ),
1227             $self->_get_trailing_tokens();
1228 11         28 $self->_set_mode( 'kaput' );
1229             } else {
1230             # Put our mode to replacement.
1231 33         62 $self->_set_mode( 'repl' );
1232             }
1233              
1234             }
1235              
1236 560         1418 return @tokens;
1237              
1238             }
1239              
1240             # To common processing on trailing tokens.
1241             sub _get_trailing_tokens {
1242 527     527   909 my ( $self ) = @_;
1243 527 100       1048 if ( $self->{index_locations} ) {
1244             # We turned off index_locations when these were created, because
1245             # they were done out of order. Fix that now.
1246 11         32 foreach my $token ( @{ $self->{trailing_tokens} } ) {
  11         20  
1247 11         39 $self->_update_location( $token );
1248             }
1249             }
1250 527         600 return @{ delete $self->{trailing_tokens} };
  527         1394  
1251             }
1252              
1253             1;
1254              
1255             __END__