File Coverage

grammar.yp
Criterion Covered Total %
statement 89 96 92.7
branch 18 32 56.2
condition 12 21 57.1
subroutine 30 32 93.7
pod 0 1 0.0
total 149 182 81.8


line stmt bran cond sub pod time code
1              
2             ###
3             ### Copyright 2002-2003 University of Illinois Board of Trustees
4             ### Copyright 2002-2003 Mark D. Roth
5             ### All rights reserved.
6             ###
7             ### grammar.yp - Parse::Yapp grammar for Config::Objective
8             ###
9             ### Mark D. Roth
10             ### Campus Information Technologies and Educational Services
11             ### University of Illinois at Urbana-Champaign
12             ###
13              
14              
15             ###
16             ### Header section
17             ###
18              
19             %{
20 1     1   5 use strict;
  1         2  
  1         30  
21              
22             ###
23             ### constants for conditional evaluation state
24             ###
25              
26             ### either we already found a true condition, or the parent conditional
27             ### block is not being evaluated, so:
28             ### 1. subsequent %else or %elif clauses are NOT evaluated
29             ### 2. enclosed statements are NOT evaluated
30 1     1   4 use constant CS_NO_EVAL => -1;
  1         2  
  1         52  
31              
32             ### have not yet found a true conditional in this block, which means:
33             ### 1. subsequent %else or %elif clauses are evaluated
34             ### 2. enclosed statements are NOT evaluated
35 1     1   4 use constant CS_FALSE => 0;
  1         1  
  1         33  
36              
37             ### immediately preceding condition was true, so:
38             ### 1. subsequent %else or %elif clauses are NOT evaluated
39             ### 2. enclosed statements are evaluated
40 1     1   5 use constant CS_TRUE => 1;
  1         16  
  1         2373  
41             %}
42              
43              
44 1     1 0 3 %left AND OR
45 1 50       7 %right NOT
46              
47              
48             %%
49              
50             ###
51             ### Rules section
52             ###
53              
54             config : #empty
55             | config directive
56             ;
57              
58             directive
59             : statement
60             | conditional
61             | include
62             ;
63              
64             include : INCLUDE string
65             {
66 0     0   0 my ($config) = $_[0]->YYData->{'config'};
67              
68             return undef
69 0 0 0     0 if (@{$config->{'cond_stack'}}
  0         0  
70             && $config->{'cond_stack'}->[-1] != CS_TRUE);
71              
72 0 0       0 $_[2] = $config->{'include_dir'} . '/' . $_[2]
73             if ($_[2] !~ m|^/|);
74              
75 0         0 $config->parse($_[2]);
76             }
77             ;
78              
79             conditional
80             : cond_if config cond_endif
81             | cond_elif
82             | cond_else
83             ;
84              
85             expression
86             : expr
87             | NOT expression
88             {
89 0     0   0 return (! $_[2]);
90             }
91             | expression OR expression
92             {
93 1   33 1   70 return ($_[1] || $_[3]);
94             }
95             | expression AND expression
96             {
97 1   33 1   37 return ($_[1] && $_[3]);
98             }
99             | PAREN_START expression PAREN_END
100             {
101 1     1   48 return $_[2];
102             }
103             ;
104              
105             expr :
106             {
107 10     10   267 my ($config) = $_[0]->YYData->{'config'};
108 10         62 $config->{'in_expr'} = 1;
109             }
110             method_call
111             {
112 10     10   302 my ($config) = $_[0]->YYData->{'config'};
113 10         54 $config->{'in_expr'} = 0;
114 10         28 return $_[2];
115             }
116             ;
117              
118             cond_if : IF PAREN_START expression PAREN_END
119             {
120 7     7   277 my ($config) = $_[0]->YYData->{'config'};
121              
122 7         10 push(@{$config->{'cond_stack'}},
123 7 100 66     36 ((@{$config->{'cond_stack'}}
    100          
124             && $config->{'cond_stack'}->[-1] != CS_TRUE)
125             ? CS_NO_EVAL
126             : ($_[3]
127             ? CS_TRUE
128             : CS_FALSE)));
129             }
130             ;
131              
132             cond_endif
133             : ENDIF
134             {
135 7     7   243 my ($config) = $_[0]->YYData->{'config'};
136              
137 7         33 die "%endif: not in conditional\n"
138 7 50       36 if (! @{$config->{'cond_stack'}});
139              
140 7         9 pop(@{$config->{'cond_stack'}});
  7         22  
141             }
142             ;
143              
144             cond_elif
145             : ELIF PAREN_START expression PAREN_END
146             {
147 1     1   45 my ($config) = $_[0]->YYData->{'config'};
148              
149 1         4 die "%elif: not in conditional\n"
150 1 50       6 if (! @{$config->{'cond_stack'}});
151              
152             ### all previous conditions were false, so evaluate this one
153 1 50       5 if ($config->{'cond_stack'}->[-1] == CS_FALSE)
    0          
154             {
155 1 50       18 $config->{'cond_stack'}->[-1] = ($_[3]
156             ? CS_TRUE
157             : CS_FALSE);
158             }
159              
160             ### the last condition was true, so all subsequent %else
161             ### or %elif clauses must be false
162             elsif ($config->{'cond_stack'}->[-1] == CS_TRUE)
163             {
164 0         0 $config->{'cond_stack'}->[-1] = CS_NO_EVAL;
165             }
166              
167             ### if it's CS_NO_EVAL, leave it alone
168             }
169             ;
170              
171             cond_else
172             : ELSE
173             {
174 2     2   81 my ($config) = $_[0]->YYData->{'config'};
175              
176 2         9 die '%else: not in conditional'
177 2 50       13 if (! @{$config->{'cond_stack'}});
178              
179             ### all previous conditions were false, so set to true
180 2 100       13 if ($config->{'cond_stack'}->[-1] == CS_FALSE)
    50          
181             {
182 1         4 $config->{'cond_stack'}->[-1] = CS_TRUE;
183             }
184              
185             ### the last condition was true, so set to CS_NO_EVAL
186             elsif ($config->{'cond_stack'}->[-1] == CS_TRUE)
187             {
188 1         6 $config->{'cond_stack'}->[-1] = CS_NO_EVAL;
189             }
190              
191             ### if it's CS_NO_EVAL, leave it alone
192             }
193             ;
194              
195             string : WORD
196             | QSTRING
197             ;
198              
199             value : string
200             | list
201             | hash
202             ;
203              
204             statement
205             : method_call EOS
206             ;
207              
208             method_name
209             : #empty
210             {
211 43     43   1103 my ($config) = $_[0]->YYData->{'config'};
212 43 100       310 return ($config->{'in_expr'} ? 'equals' : 'default');
213             }
214             | METHOD_ARROW WORD
215             {
216 25     25   888 return $_[2];
217             }
218             ;
219              
220             method_args
221             : #empty
222             {
223 8     8   231 my ($config) = $_[0]->YYData->{'config'};
224 8         42 push(@{$config->{arg_stack}}, []);
  8         28  
225             }
226             | value
227             {
228 56     56   3829 my ($config) = $_[0]->YYData->{'config'};
229 56         264 push(@{$config->{arg_stack}}, [ $_[1] ]);
  56         201  
230             }
231             | PAREN_START
232             {
233 4     4   161 my ($config) = $_[0]->YYData->{'config'};
234 4         22 push(@{$config->{'list_stack'}}, []);
  4         14  
235             }
236             list_values PAREN_END
237             {
238 4     4   140 my ($config) = $_[0]->YYData->{'config'};
239 4         20 push(@{$config->{arg_stack}}, pop(@{$config->{'list_stack'}}));
  4         8  
  4         11  
240             }
241             ;
242              
243             method_call
244             : WORD method_name method_args
245             {
246 68     68   1853 my ($config) = $_[0]->YYData->{'config'};
247              
248             # print "var='$_[1]' method='$_[2]' value='$_[3]'\n";
249              
250             ### for conditional expressions, don't bother evaluating
251             ### if a previous condition was true
252             return undef
253 68 50 66     444 if ($config->{'in_expr'}
254             && $config->{'cond_stack'}->[-1] == CS_NO_EVAL);
255              
256             ### for statements, don't evaluate if we're inside a
257             ### false conditional block
258             return undef
259 58         291 if (! $config->{'in_expr'}
260 68 100 100     172 && @{$config->{'cond_stack'}}
      100        
261             && $config->{'cond_stack'}->[-1] != CS_TRUE);
262              
263 63         220 return $config->_call_obj_method($_[1], $_[2],
264 63         97 @{pop(@{$config->{arg_stack}})});
  63         56  
265             }
266             ;
267              
268             list : LIST_START
269             {
270 17     17   726 my ($config) = $_[0]->YYData->{'config'};
271 17         91 push(@{$config->{'list_stack'}}, []);
  17         60  
272             }
273             list_values LIST_END
274             {
275 17     17   696 my ($config) = $_[0]->YYData->{'config'};
276 17         88 return pop(@{$config->{'list_stack'}});
  17         53  
277             }
278             ;
279              
280             list_values
281             : #empty
282             | value
283             {
284 20     20   1703 my ($config) = $_[0]->YYData->{'config'};
285 20         104 push(@{$config->{'list_stack'}->[-1]}, $_[1]);
  20         84  
286             }
287             | list_values COMMA value
288             {
289 37     37   2962 my ($config) = $_[0]->YYData->{'config'};
290 37         189 push(@{$config->{'list_stack'}->[-1]}, $_[3]);
  37         138  
291             }
292             ;
293              
294             hash : HASH_START HASH_END
295             {
296 1     1   48 return {};
297             }
298             | HASH_START
299             {
300 18     18   591 my ($config) = $_[0]->YYData->{'config'};
301              
302 18         95 push(@{$config->{'hash_stack'}}, {});
  18         67  
303             }
304             hash_values HASH_END
305             {
306 18     18   811 my ($config) = $_[0]->YYData->{'config'};
307              
308 18         108 return pop(@{$config->{'hash_stack'}});
  18         54  
309             }
310             ;
311              
312             hash_values
313             : hash_values COMMA hash_value
314             | hash_value
315             ;
316              
317             hash_value
318             : string
319             {
320 8     8   228 my ($config) = $_[0]->YYData->{'config'};
321              
322             # print "\t'$_[1]' => undef\n";
323 8         67 $config->{'hash_stack'}->[-1]->{$_[1]} = undef;
324             }
325             | string HASH_ARROW value
326             {
327 23     23   1805 my ($config) = $_[0]->YYData->{'config'};
328              
329             # print "\t'$_[1]' => '$_[3]'\n";
330 23         206 $config->{'hash_stack'}->[-1]->{$_[1]} = $_[3];
331             }
332 1         249 ;
333              
334             %%
335 1         161  
336             ###
337             ### Footer section
338             ###
339              
340