File Coverage

blib/lib/Test/Count/Parser.pm
Criterion Covered Total %
statement 68 68 100.0
branch 6 6 100.0
condition n/a
subroutine 17 17 100.0
pod 3 3 100.0
total 94 94 100.0


line stmt bran cond sub pod time code
1             package Test::Count::Parser;
2             $Test::Count::Parser::VERSION = '0.1104';
3 5     5   68921 use warnings;
  5         19  
  5         165  
4 5     5   25 use strict;
  5         8  
  5         108  
5              
6 5     5   474 use parent 'Test::Count::Base';
  5         632  
  5         34  
7              
8 5     5   314 use File::Basename (qw(dirname));
  5         7  
  5         452  
9              
10 5     5   6081 use Parse::RecDescent ();
  5         206142  
  5         3034  
11              
12              
13             sub _get_grammar
14             {
15 19     19   111 return <<'EOF';
16             update_count: expression {$thisparser->{count} += $item[1] * $thisparser->{filter_mults}->[-1]}
17              
18             assignments: statement ';' assignments
19             | statement
20              
21             statement: assignment
22             | expression {$item [1]}
23             | including_file {$item [1]}
24             | start_filter
25             | end_filter
26              
27             start_filter: 'FILTER(MULT(' expression '))' {push @{$thisparser->{filter_mults}}, $thisparser->{filter_mults}->[-1] * $item[2] ; }
28              
29             end_filter: 'ENDFILTER()' {if (@{$thisparser->{filter_mults}} <= 1) { die "Too many ENDFILTER()s"; } pop @{$thisparser->{filter_mults}}; }
30              
31             including_file: 'source' string {push @{$thisparser->{includes}}, $item[2];}
32              
33             assignment: variable '=' statement {$thisparser->{vars}->{$item [1]} = $item [3]}
34             | variable '+=' statement {$thisparser->{vars}->{$item [1]} += $item [3]}
35             | variable '-=' statement {$thisparser->{vars}->{$item [1]} -= $item [3]}
36             | variable '*=' statement {$thisparser->{vars}->{$item [1]} *= $item [3]}
37              
38             expression: variable '++' {$thisparser->{vars}->{$item [1]}++}
39             | term '+' expression {$item [1] + $item [3]}
40             | term '-' expression {$item [1] - $item [3]}
41             | term
42              
43             term: factor '*' term {$item [1] * $item [3]}
44             | factor '/' term {int($item [1] / $item [3])}
45             | factor
46              
47             factor: number
48             | variable {
49             (exists($thisparser->{vars}->{$item [1]})
50             ? $thisparser->{vars}->{$item [1]}
51             : do { die "Undefined variable \"$item[1]\""; } )
52             }
53             | '+' factor {$item [2]}
54             | '-' factor {$item [2] * -1}
55             | '(' statement ')' {$item [2]}
56              
57             number: /\d+/ {$item [1]}
58              
59             variable: /\$[a-z_]\w*/i
60              
61             string: /"[^"]+"/
62              
63             EOF
64             }
65              
66             sub _calc_parser
67             {
68 19     19   42 my $self = shift;
69              
70 19         84 my $parser = Parse::RecDescent->new( $self->_get_grammar() );
71              
72 19         1530457 $parser->{vars} = {};
73 19         76 $parser->{count} = 0;
74 19         67 $parser->{includes} = [];
75 19         74 $parser->{filter_mults} = [1];
76              
77 19         122 return $parser;
78             }
79              
80             sub _parser
81             {
82 228     228   401 my $self = shift;
83 228 100       530 if (@_)
84             {
85 19         59 $self->{'_parser'} = shift;
86             }
87 228         1613 return $self->{'_parser'};
88             }
89              
90             sub _current_fns
91             {
92 46     46   113 my $self = shift;
93 46 100       156 if (@_)
94             {
95 19         59 $self->{'_current_fns'} = shift;
96             }
97 46         252 return $self->{'_current_fns'};
98             }
99              
100             sub _init
101             {
102 19     19   50 my $self = shift;
103              
104 19         83 $self->_current_fns( [] );
105 19         72 $self->_parser( $self->_calc_parser() );
106              
107 19         78 return 0;
108             }
109              
110              
111             sub _push_current_filename
112             {
113 13     13   29 my $self = shift;
114 13         63 my $filename = shift;
115              
116 13         55 push @{ $self->_current_fns() }, $filename;
  13         64  
117              
118 13         39 return;
119             }
120              
121             sub _pop_current_filenames
122             {
123 13     13   39 my $self = shift;
124 13         28 my $filename = shift;
125              
126 13         26 pop( @{ $self->_current_fns() } );
  13         48  
127              
128 13         41 return;
129             }
130              
131             sub _get_current_filename
132             {
133 1     1   2 my $self = shift;
134              
135 1         29 return $self->_current_fns->[-1];
136             }
137              
138             sub _parse_filename
139             {
140 1     1   2 my $self = shift;
141 1         2 my $filename = shift;
142              
143 1         6 $filename =~ s{\A"}{};
144 1         5 $filename =~ s{"\z}{};
145              
146 1         6 my $dirname = dirname( $self->_get_current_filename() );
147 1         7 $filename =~ s{\$\^CURRENT_DIRNAME}{$dirname}g;
148              
149 1         13 return $filename;
150             }
151              
152             sub update_assignments
153             {
154 42     42 1 9786 my ( $self, $args ) = @_;
155              
156 42         120 $self->_parser->{includes} = [];
157 42         109 my $ret = $self->_parser()->assignments( $args->{text} );
158              
159 42 100       1121390 if ( @{ $self->_parser->{includes} } )
  42         172  
160             {
161 1         3 foreach my $include_file ( @{ $self->_parser->{includes} } )
  1         3  
162             {
163 1         6 my $counter = Test::Count->new(
164             {
165             filename => $self->_parse_filename($include_file),
166             },
167             );
168 1         9 $counter->process( { parser => $self } );
169             }
170 1         5 $self->_parser->{includes} = [];
171             }
172             }
173              
174              
175             sub update_count
176             {
177 48     48 1 201 my ( $self, $args ) = @_;
178              
179 48         134 return $self->_parser()->update_count( $args->{text} );
180             }
181              
182              
183             sub get_count
184             {
185 20     20 1 48477 my $self = shift;
186              
187 20         62 return $self->_parser()->{count};
188             }
189              
190              
191             1; # End of Test::Count::Parser
192              
193             __END__