File Coverage

blib/lib/PPIx/Regexp/Token/Quantifier.pm
Criterion Covered Total %
statement 36 37 97.3
branch 9 12 75.0
condition n/a
subroutine 12 13 92.3
pod 3 3 100.0
total 60 65 92.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp::Token::Quantifier - Represent an atomic quantifier.
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp::Dumper;
8             PPIx::Regexp::Dumper->new( 'qr{\w+}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 an atomic quantifier; that is, one of the
21             characters C<*>, C<+>, or C.
22              
23             B that if they occur inside a variable-length look-behind, C<'?'>
24             implies a minimum Perl version of C<5.29.9>, and C<'+'> and C<'*'> are
25             regarded as parse errors and reblessed into the unknown token.
26              
27             =head1 METHODS
28              
29             This class provides the following public methods. Methods not documented
30             here are private, and unsupported in the sense that the author reserves
31             the right to change or remove them without notice.
32              
33             =cut
34              
35             package PPIx::Regexp::Token::Quantifier;
36              
37 9     9   82 use strict;
  9         21  
  9         258  
38 9     9   47 use warnings;
  9         28  
  9         240  
39              
40 9     9   46 use base qw{ PPIx::Regexp::Token };
  9         23  
  9         779  
41              
42 9     9   58 use Carp;
  9         58  
  9         590  
43 9         5051 use PPIx::Regexp::Constant qw{
44             INFINITY
45             LITERAL_LEFT_CURLY_ALLOWED
46             MSG_LOOK_BEHIND_TOO_LONG
47             TOKEN_UNKNOWN
48             VARIABLE_LENGTH_LOOK_BEHIND_INTRODUCED
49             @CARP_NOT
50 9     9   59 };
  9         25  
51              
52             our $VERSION = '0.087_01';
53              
54             # Return true if the token can be quantified, and false otherwise
55 33     33 1 150 sub can_be_quantified { return };
56              
57             # Return true if the token is a quantifier.
58 33     33 1 124 sub is_quantifier { return 1 };
59              
60             my %quantifier = map { $_ => 1 } qw{ * + ? };
61              
62             =head2 could_be_quantifier
63              
64             PPIx::Regexp::Token::Quantifier->could_be_quantifier( '*' );
65              
66             This method returns true if the given string could be a quantifier; that
67             is, if it is '*', '+', or '?'.
68              
69             =cut
70              
71             sub could_be_quantifier {
72 2     2 1 10 my ( undef, $string ) = @_; # Invocant unused
73 2         22 return $quantifier{$string};
74             }
75              
76             {
77              
78             my %explanation = (
79             '*' => 'match zero or more times',
80             '+' => 'match one or more times',
81             '?' => 'match zero or one time',
82             );
83              
84             sub __explanation {
85 3     3   8 return \%explanation;
86             }
87              
88             }
89              
90             sub __following_literal_left_curly_disallowed_in {
91 0     0   0 return LITERAL_LEFT_CURLY_ALLOWED;
92             }
93              
94             {
95             my $variable_look_behind_introduced = {
96             '*' => undef,
97             '+' => undef,
98             '?' => VARIABLE_LENGTH_LOOK_BEHIND_INTRODUCED,
99             };
100              
101             sub __PPIX_LEXER__finalize {
102 51     51   177 my ( $self ) = @_;
103 51 100       259 if ( $self->__in_look_behind() ) {
104             $self->{perl_version_introduced} =
105 2 100       16 $variable_look_behind_introduced->{$self->content()}
106             and return 0;
107 1         17 TOKEN_UNKNOWN->__PPIX_ELEM__rebless( $self,
108             error => MSG_LOOK_BEHIND_TOO_LONG,
109             );
110 1         4 return 1;
111             }
112 49         170 return 0;
113             }
114             }
115              
116             {
117             my %width = (
118             '*' => [ 0, INFINITY ],
119             '+' => [ 1, INFINITY ],
120             '?' => [ 0, 1 ],
121             );
122              
123             sub __quantified_width {
124 56     56   135 my ( $self, $raw_min, $raw_max ) = @_;
125 56 50       156 my $info = $width{$self->content()}
126             or croak sprintf q,
127             $self->content();
128 56         106 my ( $my_min, $my_max ) = @{ $info };
  56         121  
129 56 50       145 defined $raw_min
130             and $raw_min *= $my_min;
131 56 50       152 defined $raw_max
132             and $raw_max *= $my_max;
133 56         193 return ( $raw_min, $raw_max );
134             }
135             }
136              
137             sub __PPIX_TOKENIZER__regexp {
138 1171     1171   2896 my ( undef, $tokenizer, $character ) = @_;
139              
140 1171 100       3325 $tokenizer->prior_significant_token( 'can_be_quantified' )
141             or return;
142              
143 721         2260 return $quantifier{$character};
144             }
145              
146             1;
147              
148             __END__