File Coverage

blib/lib/PPIx/Regexp/Token/Backtrack.pm
Criterion Covered Total %
statement 25 30 83.3
branch 3 4 75.0
condition n/a
subroutine 9 10 90.0
pod 5 5 100.0
total 42 49 85.7


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp::Token::Backtrack - Represent backtrack control.
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp::Dumper;
8             PPIx::Regexp::Dumper->new( 'qr{(*ACCEPT)}smx' )
9             ->print();
10              
11             =head1 INHERITANCE
12              
13             C is a
14             L.
15              
16             C has no descendants.
17              
18             =head1 DESCRIPTION
19              
20             This class represents one of the backtrack controls.
21              
22             =head1 METHODS
23              
24             This class provides no public methods beyond those provided by its
25             superclass.
26              
27             =cut
28              
29             package PPIx::Regexp::Token::Backtrack;
30              
31 9     9   69 use strict;
  9         18  
  9         276  
32 9     9   46 use warnings;
  9         39  
  9         246  
33              
34 9     9   55 use base qw{ PPIx::Regexp::Token };
  9         20  
  9         721  
35              
36 9     9   61 use PPIx::Regexp::Constant qw{ @CARP_NOT };
  9         18  
  9         4615  
37              
38             our $VERSION = '0.088';
39              
40             # Return true if the token can be quantified, and false otherwise
41 8     8 1 26 sub can_be_quantified { return };
42              
43             {
44              
45             my %explanation = (
46             ACCEPT => 'Causes match to succeed at the point of the (*ACCEPT)',
47             COMMIT => 'Causes match failure when backtracked into on failure',
48             FAIL => 'Always fails, forcing backtrack',
49             MARK => 'Name branches of alternation, target for (*SKIP)',
50             PRUNE => 'Prevent backtracking past here on failure',
51             SKIP => 'Like (*PRUNE) but also discards match to this point',
52             THEN => 'Force next alternation on failure',
53             );
54              
55             sub explain {
56 9     9 1 16 my ( $self ) = @_;
57 9         21 my $verb = $self->verb();
58 9 50       28 defined( my $expl = $explanation{$verb} )
59             or return $self->__no_explanation();
60 9         21 return $expl;
61             }
62              
63             my %synonym = (
64             '' => 'MARK',
65             F => 'FAIL',
66             );
67              
68             =head2 arg
69              
70             This method returns the backtrack control argument specified by the
71             element. This is the text after the first colon (C<':'>), or the empty
72             string (C<''>) if none was specified.
73              
74             =cut
75              
76             sub arg {
77 0     0 1 0 my ( $self ) = @_;
78 0         0 my $content = $self->content();
79 0         0 $content =~ s/ [^:]* //smx; # (
80 0         0 $content =~ s/ \) //smx;
81 0         0 return $content;
82             }
83              
84             =head2 verb
85              
86             This method returns the backtrack control verb represented by the
87             element. This is the text up to but not including the first colon
88             (C<':'>) if any. If the element specifies C<''> or C<'F">, this method
89             will return C<'MARK'> or C<'FAIL'>, respectively.
90              
91             =cut
92              
93             sub verb {
94 9     9 1 16 my ( $self ) = @_;
95 9         30 my $content = $self->content();
96 9         37 $content =~ s/ \( \* //smx;
97 9         48 $content =~ s/ [:)] .* //smx;
98 9 100       34 defined( my $syn = $synonym{$content} )
99             or return $content;
100 2         7 return $syn;
101             }
102             }
103              
104             sub perl_version_introduced {
105 9     9 1 2655 return '5.009005';
106             }
107              
108             # This must be implemented by tokens which do not recognize themselves.
109             # The return is a list of list references. Each list reference must
110             # contain a regular expression that recognizes the token, and optionally
111             # a reference to a hash to pass to make_token as the class-specific
112             # arguments. The regular expression MUST be anchored to the beginning of
113             # the string.
114             # Note that we have to require a non-lowercase letter after the asterisk
115             # to avoid grabbing the so-caled alpha_assertions introduced with
116             # 5.27.9.
117             # Optimized code ( (*{...}) and (**{...}) ), introduced in 5.37.8, broke
118             # the non-lowercase requirement. I replaced that with requiring an
119             # uppercase or a colon (the latter because in (*MARK:foo) you can omit
120             # the 'MARK').
121             sub __PPIX_TOKEN__recognize {
122 9     9   43 return ( [ qr{ \A \( \* [[:upper:]:] [^\)]* \) }smx ] );
123             }
124              
125             # This class gets recognized by PPIx::Regexp::Token::Structure as part
126             # of its left parenthesis processing.
127              
128             =begin comment
129              
130             sub __PPIX_TOKENIZER__regexp {
131             my ( $class, $tokenizer, $character ) = @_;
132              
133             return $character eq 'x' ? 1 : 0;
134             }
135              
136             =end comment
137              
138             =cut
139              
140             1;
141              
142             __END__