File Coverage

blib/lib/PPIx/Regexp/Structure/Switch.pm
Criterion Covered Total %
statement 36 36 100.0
branch 16 18 88.8
condition 5 9 55.5
subroutine 6 6 100.0
pod n/a
total 63 69 91.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp::Structure::Switch - Represent a switch
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp::Dumper;
8             PPIx::Regexp::Dumper->new( 'qr{(?(1)foo|bar)}smx' )
9             ->print();
10              
11             =head1 INHERITANCE
12              
13             C<PPIx::Regexp::Structure::Switch> is a
14             L<PPIx::Regexp::Structure|PPIx::Regexp::Structure>.
15              
16             C<PPIx::Regexp::Structure::Switch> has no descendants.
17              
18             =head1 DESCRIPTION
19              
20             This class represents a switch, or conditional expression. The condition
21             will be the first child.
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::Structure::Switch;
31              
32 9     9   61 use strict;
  9         17  
  9         245  
33 9     9   31 use warnings;
  9         13  
  9         360  
34              
35 9     9   32 use base qw{ PPIx::Regexp::Structure };
  9         16  
  9         698  
36              
37 9     9   39 use PPIx::Regexp::Constant qw{ @CARP_NOT };
  9         14  
  9         3301  
38              
39             our $VERSION = '0.091';
40              
41             sub __raw_width {
42 18     18   31 my ( $self ) = @_;
43 18         21 my $cond;
44 18 100 33     45 $cond = $self->schild( 0 )
      66        
45             and $cond->isa( 'PPIx::Regexp::Token::Condition' )
46             and $cond->content() eq '(DEFINE)'
47             and return ( 0, 0, 1 );
48 12         30 my ( $node_min, $node_max, $alternatives ) = $self->SUPER::__raw_width();
49 12 100 66     38 defined $node_min
50             and $alternatives < 2
51             and $node_min = 0;
52 12         30 return ( $node_min, $node_max, $alternatives );
53             }
54              
55             sub __PPIX_LEXER__finalize {
56 26     26   57 my ( $self, $lexer ) = @_;
57              
58             # Assume no errors.
59 26         44 my $rslt = 0;
60              
61             # Number of allowed alternations not known yet.
62 26         37 my $alternations;
63              
64             # If we are a valid switch, the first child is the condition. Make
65             # sure we have a first child and that it is of the expected class.
66             # If it is, determine how many alternations are allowed.
67 26 50       105 if ( my $condition = $self->child( 0 ) ) {
68 26         49 foreach my $class ( qw{
69             PPIx::Regexp::Structure::Assertion
70             PPIx::Regexp::Structure::Code
71             PPIx::Regexp::Token::Condition
72             } ) {
73 71 100       217 $condition->isa( $class ) or next;
74 25 100       90 $alternations = $condition->content() eq '(DEFINE)' ? 0 : 1;
75 25         76 last;
76             }
77             }
78              
79 26 100       60 if ( defined $alternations ) {
80             # If we figured out how many alternations were allowed, count
81             # them, changing surplus ones to the unknown token.
82 25         69 foreach my $kid ( $self->children () ) {
83 82 100       282 $kid->isa( 'PPIx::Regexp::Token::Operator' ) or next;
84 5 50       13 $kid->content() eq '|' or next;
85 5 100       29 --$alternations >= 0 and next;
86 1         16 $kid->__error( 'Too many alternatives for switch' );
87             }
88             } else {
89             # If we could not figure out how many alternations were allowed,
90             # it means we did not understand our condition. Rebless
91             # ourselves to the unknown structure and count a parse failure.
92 1         10 $self->__error( 'Switch condition not understood' );
93 1         2 $rslt++;
94             }
95              
96             # Delegate to the superclass to finalize our children, now that we
97             # have finished messing with them.
98 26         120 $rslt += $self->SUPER::__PPIX_LEXER__finalize( $lexer );
99              
100 26         56 return $rslt;
101             }
102              
103             1;
104              
105             __END__
106              
107             =head1 SUPPORT
108              
109             Support is by the author. Please file bug reports at
110             L<https://rt.cpan.org/Public/Dist/Display.html?Name=PPIx-Regexp>,
111             L<https://github.com/trwyant/perl-PPIx-Regexp/issues>, or in
112             electronic mail to the author.
113              
114             =head1 AUTHOR
115              
116             Thomas R. Wyant, III F<wyant at cpan dot org>
117              
118             =head1 COPYRIGHT AND LICENSE
119              
120             Copyright (C) 2009-2023, 2025 by Thomas R. Wyant, III
121              
122             This program is free software; you can redistribute it and/or modify it
123             under the same terms as Perl 5.10.0. For more details, see the full text
124             of the licenses in the directory LICENSES.
125              
126             This program is distributed in the hope that it will be useful, but
127             without any warranty; without even the implied warranty of
128             merchantability or fitness for a particular purpose.
129              
130             =cut
131              
132             # ex: set textwidth=72 :