line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#Copyright 2007-10 Arthur S Goldstein |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Parse::Stallion::Talon; |
4
|
32
|
|
|
32
|
|
833999
|
use Carp; |
|
32
|
|
|
|
|
83
|
|
|
32
|
|
|
|
|
4867
|
|
5
|
32
|
|
|
32
|
|
202
|
use strict; |
|
32
|
|
|
|
|
68
|
|
|
32
|
|
|
|
|
1065
|
|
6
|
32
|
|
|
32
|
|
262
|
use warnings; |
|
32
|
|
|
|
|
69
|
|
|
32
|
|
|
|
|
1017
|
|
7
|
32
|
|
|
32
|
|
935
|
use 5.006; |
|
32
|
|
|
|
|
111
|
|
|
32
|
|
|
|
|
12061
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub stringify { |
10
|
1423
|
|
|
1423
|
|
4093
|
my $self = shift; |
11
|
1423
|
|
|
|
|
1660
|
my $parameters = shift; |
12
|
1423
|
|
100
|
|
|
6209
|
my $values = $parameters->{values} || ['steps','name','parse_match']; |
13
|
1423
|
|
100
|
|
|
3441
|
my $spaces = $parameters->{spaces} || ''; |
14
|
1423
|
|
|
|
|
1586
|
my $value_separator = '|'; |
15
|
1423
|
50
|
|
|
|
2977
|
if (defined $parameters->{value_separator}) { |
16
|
0
|
|
|
|
|
0
|
$value_separator = $parameters->{value_separator}; |
17
|
|
|
|
|
|
|
} |
18
|
1423
|
|
|
|
|
1829
|
my $line = $spaces; |
19
|
|
|
|
|
|
|
|
20
|
1423
|
|
|
|
|
2003
|
foreach my $value (@$values) { |
21
|
4239
|
100
|
|
|
|
7160
|
if (defined $self->{$value}) { |
22
|
3123
|
|
|
|
|
6306
|
$line .= $self->{$value}.$value_separator; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
else { |
25
|
1116
|
|
|
|
|
2398
|
$line .= $value_separator; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
1423
|
|
|
|
|
1931
|
$line .= "\n"; |
30
|
1423
|
|
|
|
|
1761
|
foreach my $child (@{$self->{children}}) { |
|
1423
|
|
|
|
|
3209
|
|
31
|
1298
|
|
|
|
|
2118
|
$parameters->{spaces} = $spaces.' '; |
32
|
1298
|
|
|
|
|
2360
|
$line .= stringify($child,$parameters); |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
1423
|
|
|
|
|
5518
|
return $line; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
package Parse::Stallion::Parser; |
39
|
32
|
|
|
32
|
|
188
|
use Carp; |
|
32
|
|
|
|
|
61
|
|
|
32
|
|
|
|
|
2819
|
|
40
|
32
|
|
|
32
|
|
188
|
use strict; |
|
32
|
|
|
|
|
52
|
|
|
32
|
|
|
|
|
1135
|
|
41
|
32
|
|
|
32
|
|
362
|
use warnings; |
|
32
|
|
|
|
|
51
|
|
|
32
|
|
|
|
|
120944
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub new { |
44
|
424
|
|
|
424
|
|
628
|
my $type = shift; |
45
|
424
|
|
33
|
|
|
1879
|
my $class = ref($type) || $type; |
46
|
424
|
|
|
|
|
711
|
my $parameters = shift; |
47
|
424
|
|
|
|
|
2416
|
my $parsing_info = {parse_stallion => $parameters}; |
48
|
424
|
|
|
|
|
1835
|
return bless $parsing_info, $class; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub parse_leaf { |
53
|
25
|
|
|
25
|
|
32
|
my $parsing_info = shift; |
54
|
25
|
|
|
|
|
30
|
my $parameters = shift; |
55
|
25
|
|
|
|
|
29
|
my $start_rule_name = shift; |
56
|
25
|
|
|
|
|
34
|
my $parse_stallion = $parsing_info->{parse_stallion}; |
57
|
25
|
|
|
|
|
32
|
my $parse_hash = $parameters->{parse_hash}; |
58
|
25
|
|
|
|
|
54
|
my $parse_this_ref = $parse_hash->{parse_this_ref} = |
59
|
|
|
|
|
|
|
$parameters->{parse_this_ref}; |
60
|
25
|
|
|
|
|
75
|
my $parse_this_length = $parse_hash->{__parse_this_length}; |
61
|
25
|
|
|
|
|
30
|
my $must_parse_length = $parse_hash->{__match_length}; |
62
|
25
|
|
|
|
|
29
|
my $do_evaluation_in_parsing = $parse_stallion->{do_evaluation_in_parsing}; |
63
|
25
|
|
|
|
|
45
|
my $start_node = $parse_stallion->{rule}->{$start_rule_name}; |
64
|
25
|
|
|
|
|
34
|
my $initial_position = $parse_hash->{__initial_position}; |
65
|
|
|
|
|
|
|
|
66
|
25
|
|
|
|
|
27
|
my $tree; |
67
|
|
|
|
|
|
|
my @bottom_up_left_to_right; |
68
|
0
|
|
|
|
|
0
|
my $current_position; |
69
|
0
|
|
|
|
|
0
|
my $continue_forward; |
70
|
0
|
|
|
|
|
0
|
my $match; |
71
|
0
|
|
|
|
|
0
|
my $delta_position; |
72
|
|
|
|
|
|
|
|
73
|
25
|
50
|
|
|
|
77
|
if (my $pf = $start_node->{parse_forward}) { |
|
|
50
|
|
|
|
|
|
74
|
0
|
|
|
|
|
0
|
$current_position = $parse_hash->{current_position} = $initial_position; |
75
|
0
|
|
|
|
|
0
|
$parse_hash->{rule_name} = $start_rule_name; |
76
|
0
|
|
|
|
|
0
|
($continue_forward, $match, $delta_position) = &{$pf}($parse_hash); |
|
0
|
|
|
|
|
0
|
|
77
|
0
|
0
|
|
|
|
0
|
if (defined $delta_position) { |
78
|
0
|
0
|
|
|
|
0
|
if ($delta_position < 0) { |
79
|
0
|
|
|
|
|
0
|
croak ("Parse forward on $start_rule_name resulted in |
80
|
|
|
|
|
|
|
backward progress ($initial_position, $delta_position)"); |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
else { |
83
|
0
|
|
|
|
|
0
|
$current_position += $delta_position; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
elsif (my $x = $start_node->{regex_match}) { |
88
|
25
|
|
|
|
|
64
|
pos $$parse_this_ref = $initial_position; |
89
|
25
|
100
|
|
|
|
160
|
if ($$parse_this_ref =~ m/$x/cg) { |
90
|
22
|
100
|
|
|
|
57
|
if (defined $2) {$match = $2;} |
|
18
|
|
|
|
|
35
|
|
|
4
|
|
|
|
|
12
|
|
91
|
|
|
|
|
|
|
else {$match = $1;} |
92
|
22
|
|
|
|
|
21
|
$continue_forward = 1; |
93
|
22
|
|
|
|
|
30
|
$current_position = pos $$parse_this_ref; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
else { |
96
|
3
|
|
|
|
|
6
|
$continue_forward = 0; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
else { |
100
|
0
|
|
|
|
|
0
|
croak ("Cannot handle leaf $start_rule_name"); |
101
|
|
|
|
|
|
|
} |
102
|
25
|
100
|
|
|
|
58
|
if ($continue_forward) { |
103
|
22
|
|
|
|
|
158
|
$tree = { |
104
|
|
|
|
|
|
|
name => $start_rule_name, |
105
|
|
|
|
|
|
|
alias => $start_node->{alias}, |
106
|
|
|
|
|
|
|
steps => 1, |
107
|
|
|
|
|
|
|
parent => undef, |
108
|
|
|
|
|
|
|
position_when_entered => $initial_position, |
109
|
|
|
|
|
|
|
__nodes_when_entered => 0, |
110
|
|
|
|
|
|
|
position_when_completed => $current_position, |
111
|
|
|
|
|
|
|
parse_match => $match, |
112
|
|
|
|
|
|
|
child_count => 0 |
113
|
|
|
|
|
|
|
}; |
114
|
22
|
50
|
|
|
|
60
|
if ($do_evaluation_in_parsing) { |
115
|
0
|
|
|
|
|
0
|
$parameters->{nodes} = [$tree]; |
116
|
0
|
|
|
|
|
0
|
$parse_hash->{current_position} = $current_position; |
117
|
0
|
0
|
|
|
|
0
|
if ($parse_stallion->new_evaluate_tree_node($parameters)) { |
118
|
0
|
|
|
|
|
0
|
$continue_forward = 0; #rejection |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
} |
121
|
22
|
100
|
100
|
|
|
105
|
if (($parse_this_length != $current_position) && $must_parse_length) { |
122
|
1
|
|
|
|
|
3
|
$continue_forward = 0; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
} |
125
|
25
|
|
|
|
|
54
|
my $tree_size; |
126
|
25
|
100
|
|
|
|
46
|
if ($continue_forward) { |
127
|
21
|
|
|
|
|
34
|
push @bottom_up_left_to_right, $tree; |
128
|
21
|
|
|
|
|
25
|
$tree_size = 1; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
else { |
131
|
4
|
|
|
|
|
8
|
$tree = undef; |
132
|
4
|
|
|
|
|
9
|
$tree_size = 0; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
25
|
|
|
|
|
32
|
my $results = $parameters->{parse_info}; |
136
|
25
|
|
|
|
|
38
|
$results->{start_rule} = $start_rule_name; |
137
|
25
|
|
|
|
|
37
|
$results->{number_of_steps} = 1; |
138
|
25
|
|
|
|
|
34
|
$results->{final_position} = $current_position; |
139
|
25
|
|
|
|
|
30
|
$results->{final_position_rule} = $start_rule_name; |
140
|
25
|
|
|
|
|
29
|
$results->{parse_backtrack_value} = undef; |
141
|
25
|
|
|
|
|
31
|
$results->{maximum_position} = $current_position; |
142
|
25
|
|
|
|
|
32
|
$results->{maximum_position_rule} = $start_rule_name; |
143
|
25
|
|
|
|
|
47
|
$results->{parse_succeeded} = $continue_forward; |
144
|
25
|
|
|
|
|
41
|
$results->{tree} = $tree; |
145
|
25
|
|
|
|
|
26
|
$results->{tree_size} = $tree_size; |
146
|
25
|
|
|
|
|
39
|
$results->{bottom_up_left_to_right} = \@bottom_up_left_to_right; |
147
|
25
|
50
|
|
|
|
60
|
if ($do_evaluation_in_parsing) { |
148
|
0
|
|
|
|
|
0
|
$results->{parsing_evaluation} = $tree->{computed_value}; |
149
|
|
|
|
|
|
|
} |
150
|
25
|
|
|
|
|
91
|
return $results; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub parse { |
154
|
704
|
|
|
704
|
|
917
|
my $parsing_info = shift; |
155
|
704
|
|
|
|
|
1336
|
my $parse_stallion = $parsing_info->{parse_stallion}; |
156
|
704
|
|
|
|
|
849
|
my $parameters = shift; |
157
|
704
|
|
|
|
|
1257
|
my $rule = $parse_stallion->{rule}; |
158
|
704
|
|
|
|
|
951
|
my $start_rule; |
159
|
704
|
50
|
|
|
|
1823
|
if (defined $parameters->{start_rule}) { |
160
|
0
|
0
|
|
|
|
0
|
if (!defined $rule->{$parameters->{start_rule}}) { |
161
|
0
|
|
|
|
|
0
|
croak ("Unknown start rule ".$parameters->{start_rule}); |
162
|
|
|
|
|
|
|
} |
163
|
0
|
|
|
|
|
0
|
$start_rule = $parameters->{start_rule}; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
else { |
166
|
704
|
|
|
|
|
1429
|
$start_rule = $parse_stallion->{start_rule}; |
167
|
|
|
|
|
|
|
} |
168
|
704
|
100
|
|
|
|
4372
|
if ($rule->{$start_rule}->{leaf_rule}) { |
169
|
25
|
|
|
|
|
87
|
return $parsing_info->parse_leaf($parameters, $start_rule); |
170
|
|
|
|
|
|
|
} |
171
|
679
|
|
66
|
|
|
3148
|
my $parse_trace_routine = $parameters->{parse_trace_routine} |
172
|
|
|
|
|
|
|
|| $parse_stallion->{parse_trace_routine}; |
173
|
679
|
|
|
|
|
1084
|
my $parse_hash = $parameters->{parse_hash}; |
174
|
679
|
|
|
|
|
1451
|
my $parse_this_ref = $parse_hash->{parse_this_ref} = |
175
|
|
|
|
|
|
|
$parameters->{parse_this_ref}; |
176
|
679
|
|
|
|
|
1135
|
my $parse_this_length = $parse_hash->{__parse_this_length}; |
177
|
679
|
|
66
|
|
|
4222
|
my $max_steps = $parameters->{max_steps} || $parse_stallion->{max_steps}; |
178
|
679
|
|
|
|
|
934
|
my $no_max_steps = 0; |
179
|
679
|
50
|
|
|
|
1755
|
if ($max_steps < 0) { |
180
|
0
|
|
|
|
|
0
|
$no_max_steps = 1; |
181
|
0
|
|
|
|
|
0
|
$max_steps = 1000000; |
182
|
|
|
|
|
|
|
} |
183
|
679
|
|
|
|
|
833
|
my $bottom_up_left_to_right; |
184
|
679
|
|
|
|
|
781
|
my $move_back_mode = 0; |
185
|
679
|
|
|
|
|
832
|
my $not_move_back_mode = 1; |
186
|
|
|
|
|
|
|
|
187
|
679
|
|
|
|
|
1678
|
my $first_alias = |
188
|
|
|
|
|
|
|
'b'.$parse_stallion->{separator}.$parse_stallion->{separator}; |
189
|
|
|
|
|
|
|
|
190
|
679
|
|
|
|
|
1066
|
my $current_position = $parse_hash->{__initial_position}; |
191
|
679
|
|
|
|
|
947
|
my $results = $parameters->{parse_info}; |
192
|
679
|
|
|
|
|
914
|
my $maximum_position = $current_position; |
193
|
679
|
|
|
|
|
1068
|
my $maximum_position_rule = $start_rule; |
194
|
|
|
|
|
|
|
|
195
|
679
|
|
|
|
|
1602
|
my $must_parse_length = $parse_hash->{__match_length}; |
196
|
679
|
|
|
|
|
1178
|
my $any_minimize_children = $parse_stallion->{any_minimize_children}; |
197
|
679
|
|
|
|
|
1080
|
my $not_any_minimize_children = !$any_minimize_children; |
198
|
679
|
|
|
|
|
1452
|
my $any_maximum_child = $parse_stallion->{any_maximum_child}; |
199
|
679
|
|
|
|
|
1924
|
my $not_any_maximum_child = !$any_maximum_child; |
200
|
679
|
|
|
|
|
1149
|
my $any_minimum_child = $parse_stallion->{any_minimum_child}; |
201
|
679
|
|
|
|
|
1143
|
my $not_any_minimum_child = !$any_minimum_child; |
202
|
679
|
|
|
|
|
954
|
my $any_match_once = $parse_stallion->{any_match_once}; |
203
|
679
|
|
|
|
|
871
|
my $any_parse_forward = $parse_stallion->{any_parse_forward}; |
204
|
679
|
|
|
|
|
865
|
my $any_parse_backtrack = $parse_stallion->{any_parse_backtrack}; |
205
|
679
|
|
|
|
|
969
|
my $fast_move_back = $parse_stallion->{fast_move_back}; |
206
|
679
|
|
|
|
|
1091
|
my $delta_tree_size = $parse_stallion->{max_nodes_before_size_must_change}; |
207
|
679
|
|
|
|
|
863
|
my $do_evaluation_in_parsing = $parse_stallion->{do_evaluation_in_parsing}; |
208
|
679
|
|
|
|
|
701
|
my $bottom_up; |
209
|
679
|
100
|
66
|
|
|
4380
|
if ($do_evaluation_in_parsing || $parse_stallion->{no_evaluation}) { |
210
|
75
|
|
|
|
|
116
|
$bottom_up = 0; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
else { |
213
|
604
|
|
|
|
|
856
|
$bottom_up = 1; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
|
217
|
679
|
|
|
|
|
852
|
my ($tree, |
218
|
|
|
|
|
|
|
$current_node, |
219
|
|
|
|
|
|
|
$moving_forward, |
220
|
|
|
|
|
|
|
$moving_down, |
221
|
|
|
|
|
|
|
$steps, |
222
|
|
|
|
|
|
|
$message, |
223
|
|
|
|
|
|
|
$new_rule_name, |
224
|
|
|
|
|
|
|
$new_alias, |
225
|
|
|
|
|
|
|
$position_tree_size, |
226
|
|
|
|
|
|
|
$node_completed, |
227
|
|
|
|
|
|
|
$create_child, |
228
|
|
|
|
|
|
|
$move_back_to_child, |
229
|
|
|
|
|
|
|
$remove_node, |
230
|
|
|
|
|
|
|
$new_rule, |
231
|
|
|
|
|
|
|
$new_sub_rule, |
232
|
|
|
|
|
|
|
$continue_forward, |
233
|
|
|
|
|
|
|
$match, |
234
|
|
|
|
|
|
|
$previous_position, |
235
|
|
|
|
|
|
|
$current_node_name, |
236
|
|
|
|
|
|
|
$current_rule, |
237
|
|
|
|
|
|
|
$end_parse_now, |
238
|
|
|
|
|
|
|
$tree_size); |
239
|
|
|
|
|
|
|
|
240
|
679
|
100
|
|
|
|
1442
|
if (defined $parse_hash->{__steps_ref}) { |
241
|
274
|
|
|
|
|
382
|
$steps = ${$parse_hash->{__steps_ref}}; |
|
274
|
|
|
|
|
490
|
|
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
else { |
244
|
405
|
|
|
|
|
587
|
$steps = 0; |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
679
|
|
|
|
|
3470
|
my $continue_parse = $parameters->{continue_parse}; |
248
|
679
|
100
|
|
|
|
1452
|
if ($continue_parse) { |
249
|
87
|
|
|
|
|
106
|
$tree = $parse_hash->{__tree}; |
250
|
87
|
|
|
|
|
145
|
$current_node = $parse_hash->{__current_node}; |
251
|
87
|
|
|
|
|
86
|
$moving_forward = ${$parse_hash->{__moving_forward_ref}}; |
|
87
|
|
|
|
|
130
|
|
252
|
87
|
|
|
|
|
92
|
$moving_down = ${$parse_hash->{__moving_down_ref}}; |
|
87
|
|
|
|
|
122
|
|
253
|
87
|
|
|
|
|
90
|
$current_position = ${$parse_hash->{__current_position_ref}}; |
|
87
|
|
|
|
|
123
|
|
254
|
87
|
|
|
|
|
96
|
$message = ${$parse_hash->{__message_ref}}; |
|
87
|
|
|
|
|
202
|
|
255
|
87
|
|
|
|
|
109
|
$position_tree_size = $parse_hash->{__position_tree_size}; |
256
|
87
|
|
|
|
|
87
|
$continue_forward = ${$parse_hash->{__continue_forward_ref}}; |
|
87
|
|
|
|
|
132
|
|
257
|
87
|
|
|
|
|
89
|
$tree_size = ${$parse_hash->{__tree_size_ref}}; |
|
87
|
|
|
|
|
137
|
|
258
|
87
|
|
|
|
|
229
|
$bottom_up_left_to_right = $parse_hash->{__bottom_up_left_to_right}; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
else { |
261
|
592
|
|
|
|
|
6366
|
$tree = { |
262
|
|
|
|
|
|
|
name => $start_rule, |
263
|
|
|
|
|
|
|
steps => $steps, |
264
|
|
|
|
|
|
|
alias => $first_alias, |
265
|
|
|
|
|
|
|
position_when_entered => $current_position, |
266
|
|
|
|
|
|
|
__nodes_when_entered => 0, |
267
|
|
|
|
|
|
|
parent => undef, |
268
|
|
|
|
|
|
|
children => [], |
269
|
|
|
|
|
|
|
child_count => 0 |
270
|
|
|
|
|
|
|
}; |
271
|
592
|
|
|
|
|
1825
|
bless($tree, 'Parse::Stallion::Talon'); |
272
|
592
|
|
|
|
|
1126
|
$parse_hash->{__tree} = $tree; |
273
|
|
|
|
|
|
|
|
274
|
592
|
|
|
|
|
997
|
$bottom_up_left_to_right = []; |
275
|
592
|
|
|
|
|
869
|
$current_node = $tree; |
276
|
592
|
|
|
|
|
1103
|
$moving_forward = 1; |
277
|
592
|
|
|
|
|
859
|
$moving_down = 1; |
278
|
592
|
|
|
|
|
771
|
$message = 'Start of Parse'; |
279
|
592
|
|
|
|
|
974
|
$continue_forward = 1; |
280
|
592
|
|
|
|
|
817
|
$tree_size = 1; |
281
|
592
|
|
|
|
|
2481
|
$position_tree_size = {}; |
282
|
592
|
|
|
|
|
1184
|
$parse_hash->{__position_tree_size} = $position_tree_size; |
283
|
|
|
|
|
|
|
} |
284
|
679
|
|
|
|
|
935
|
$node_completed = 0; |
285
|
679
|
|
|
|
|
750
|
$create_child = 0; |
286
|
679
|
|
|
|
|
777
|
$move_back_to_child = 0; |
287
|
679
|
|
|
|
|
794
|
$remove_node = 0; |
288
|
679
|
|
|
|
|
1355
|
$current_node_name = $current_node->{name}; |
289
|
679
|
|
|
|
|
1044
|
$current_rule = $rule->{$current_node_name}; |
290
|
|
|
|
|
|
|
|
291
|
679
|
|
|
|
|
1598
|
$parse_hash->{__current_node_ref} = \$current_node; |
292
|
679
|
|
|
|
|
1165
|
$parse_hash->{__current_node} = $current_node; |
293
|
679
|
|
|
|
|
2500
|
$parse_hash->{__current_node_name_ref} = \$current_node_name; |
294
|
679
|
|
|
|
|
1251
|
$parse_hash->{__moving_forward_ref} = \$moving_forward; |
295
|
679
|
|
|
|
|
1735
|
$parse_hash->{__moving_down_ref} = \$moving_down; |
296
|
679
|
|
|
|
|
4674
|
$parse_hash->{__current_position_ref} = \$current_position; |
297
|
679
|
|
|
|
|
1185
|
$parse_hash->{__message_ref} = \$message; |
298
|
679
|
|
|
|
|
1079
|
$parse_hash->{__steps_ref} = \$steps; |
299
|
679
|
|
|
|
|
1796
|
$parse_hash->{__continue_forward_ref} = \$continue_forward; |
300
|
679
|
|
|
|
|
1251
|
$parse_hash->{__tree_size_ref} = \$tree_size; |
301
|
679
|
|
|
|
|
1369
|
$parse_hash->{__current_rule_ref} = \$current_rule; |
302
|
679
|
|
|
|
|
1146
|
$parse_hash->{__bottom_up} = $bottom_up; |
303
|
679
|
|
|
|
|
1092
|
$parse_hash->{__bottom_up_left_to_right} = $bottom_up_left_to_right; |
304
|
679
|
|
|
|
|
1188
|
$parse_hash->{__parse_trace_routine} = $parse_trace_routine; |
305
|
|
|
|
|
|
|
|
306
|
679
|
|
100
|
|
|
3734
|
while (($steps < $max_steps) && $current_node) { |
307
|
798
|
|
100
|
|
|
4713
|
while ($current_node && (++$steps <= $max_steps)) { |
308
|
28772
|
100
|
|
|
|
58952
|
if ($parse_trace_routine) { |
309
|
202
|
|
|
|
|
1463
|
&{$parse_trace_routine}($parse_hash); |
|
202
|
|
|
|
|
2008
|
|
310
|
|
|
|
|
|
|
} |
311
|
28772
|
100
|
|
|
|
46075
|
if ($moving_forward) { |
312
|
17810
|
100
|
100
|
|
|
56391
|
if ($current_rule->{or_rule}) { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
313
|
3736
|
100
|
|
|
|
5509
|
if ($moving_down) { |
314
|
1979
|
|
|
|
|
3442
|
$new_sub_rule = $current_rule->{subrule_list}->[0]; |
315
|
1979
|
|
|
|
|
3057
|
$new_rule_name = $new_sub_rule->{name}; |
316
|
1979
|
|
|
|
|
4583
|
$new_alias = $new_sub_rule->{alias}; |
317
|
1979
|
|
|
|
|
3147
|
$current_node->{or_child_number} = 0; |
318
|
1979
|
|
|
|
|
2448
|
$create_child = 1; |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
else { |
321
|
1757
|
|
|
|
|
2270
|
$node_completed = 1; |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
elsif ($current_rule->{and_rule}) { |
325
|
12304
|
100
|
|
|
|
26122
|
if ($current_node->{child_count} == |
326
|
|
|
|
|
|
|
$current_rule->{subrule_list_count}) { |
327
|
2724
|
|
|
|
|
3775
|
$node_completed = 1; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
else { |
330
|
9580
|
|
|
|
|
29771
|
$new_sub_rule = $current_rule->{subrule_list}->[ |
331
|
|
|
|
|
|
|
$current_node->{child_count}]; |
332
|
9580
|
|
|
|
|
15415
|
$new_rule_name = $new_sub_rule->{name}; |
333
|
9580
|
|
|
|
|
14914
|
$new_alias = $new_sub_rule->{alias}; |
334
|
9580
|
|
|
|
|
12631
|
$create_child = 1; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
elsif ($any_minimize_children && $current_rule->{minimize_children} && |
338
|
|
|
|
|
|
|
($not_any_minimum_child || |
339
|
|
|
|
|
|
|
$current_rule->{minimum_child} <= $current_node->{child_count})) { |
340
|
89
|
|
|
|
|
133
|
$node_completed = 1; |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
elsif ($any_maximum_child && $current_rule->{maximum_child} && |
343
|
|
|
|
|
|
|
$current_rule->{maximum_child} == $current_node->{child_count}) { |
344
|
106
|
|
|
|
|
421
|
$node_completed = 1; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
else { |
347
|
1575
|
|
|
|
|
2680
|
$new_rule_name = $current_rule->{sub_rule_name}; |
348
|
1575
|
|
|
|
|
2500
|
$new_alias = $current_rule->{sub_alias}; |
349
|
1575
|
|
|
|
|
2266
|
$create_child = 1; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
else { # !$moving_forward |
353
|
10962
|
100
|
100
|
|
|
45005
|
if ($current_rule->{leaf_rule}) { |
|
|
100
|
66
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
354
|
972
|
|
|
|
|
2097
|
$remove_node = 1; |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
elsif ($current_rule->{or_rule}) { |
357
|
3724
|
100
|
|
|
|
5624
|
if ($moving_down) { |
358
|
379
|
|
|
|
|
485
|
$move_back_to_child = 1; |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
else { |
361
|
3345
|
100
|
66
|
|
|
14522
|
if ($not_move_back_mode && (++$current_node->{or_child_number} < |
362
|
|
|
|
|
|
|
$current_rule->{subrule_list_count})) { |
363
|
2746
|
|
|
|
|
5096
|
$new_sub_rule = $current_rule->{subrule_list}->[ |
364
|
|
|
|
|
|
|
$current_node->{or_child_number}]; |
365
|
2746
|
|
|
|
|
4415
|
$new_rule_name = $new_sub_rule->{name}; |
366
|
2746
|
|
|
|
|
4376
|
$new_alias = $new_sub_rule->{alias}; |
367
|
2746
|
|
|
|
|
4387
|
$create_child = 1; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
else { |
370
|
599
|
|
|
|
|
900
|
$remove_node = 1; |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
elsif ($current_rule->{and_rule}) { |
375
|
4802
|
100
|
|
|
|
8318
|
if ($current_node->{child_count}) { |
376
|
1449
|
|
|
|
|
1957
|
$move_back_to_child = 1; |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
else { |
379
|
3353
|
|
|
|
|
4085
|
$remove_node = 1; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
elsif |
383
|
|
|
|
|
|
|
( |
384
|
|
|
|
|
|
|
( |
385
|
|
|
|
|
|
|
( |
386
|
|
|
|
|
|
|
!$moving_down && |
387
|
|
|
|
|
|
|
($not_any_minimize_children || !$current_rule->{minimize_children}) |
388
|
|
|
|
|
|
|
) && |
389
|
|
|
|
|
|
|
($not_any_minimum_child || !$current_rule->{minimum_child} || |
390
|
|
|
|
|
|
|
($current_rule->{minimum_child} <= $current_node->{child_count})) |
391
|
|
|
|
|
|
|
) |
392
|
|
|
|
|
|
|
&& $not_move_back_mode |
393
|
|
|
|
|
|
|
) { |
394
|
948
|
|
|
|
|
1404
|
$node_completed = 1; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
elsif ($any_minimize_children && $not_move_back_mode && |
397
|
|
|
|
|
|
|
$current_rule->{minimize_children} && $moving_down && |
398
|
|
|
|
|
|
|
($not_any_maximum_child || !$current_rule->{maximum_child} || |
399
|
|
|
|
|
|
|
($current_rule->{maximum_child} > $current_node->{child_count}))) { |
400
|
49
|
|
|
|
|
89
|
$new_rule_name = $current_rule->{sub_rule_name}; |
401
|
49
|
|
|
|
|
71
|
$new_alias = $current_rule->{sub_alias}; |
402
|
49
|
|
|
|
|
202
|
$create_child = 1; |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
elsif ($current_node->{child_count}) { |
405
|
233
|
|
|
|
|
382
|
$move_back_to_child = 1; |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
else { |
408
|
234
|
|
|
|
|
334
|
$remove_node = 1; |
409
|
|
|
|
|
|
|
} |
410
|
10962
|
100
|
|
|
|
26140
|
if ($move_back_to_child) { |
411
|
2061
|
|
|
|
|
2228
|
$move_back_to_child = 0; |
412
|
2061
|
100
|
|
|
|
4449
|
$message .= " Backtracking to child" if $parse_trace_routine; |
413
|
2061
|
|
|
|
|
2273
|
$moving_down = 1; |
414
|
2061
|
|
|
|
|
2104
|
$moving_forward = 0; |
415
|
2061
|
100
|
|
|
|
3906
|
pop @$bottom_up_left_to_right if $bottom_up; |
416
|
2061
|
|
|
|
|
4113
|
$current_node = |
417
|
|
|
|
|
|
|
$current_node->{children}->[$current_node->{child_count}-1]; |
418
|
2061
|
|
|
|
|
3325
|
$current_node_name = $current_node->{name}; |
419
|
2061
|
|
|
|
|
3220
|
$current_rule = $rule->{$current_node_name}; |
420
|
2061
|
100
|
|
|
|
4315
|
if ($do_evaluation_in_parsing) { |
421
|
461
|
|
|
|
|
626
|
$parameters->{node} = $current_node; |
422
|
461
|
|
|
|
|
1687
|
$parse_stallion->new_unevaluate_tree_node($parameters); |
423
|
|
|
|
|
|
|
} |
424
|
2061
|
100
|
100
|
|
|
12372
|
if ($any_match_once && $not_move_back_mode |
|
|
|
66
|
|
|
|
|
425
|
|
|
|
|
|
|
&& $rule->{$current_node_name}->{match_once}) { |
426
|
|
|
|
|
|
|
|
427
|
14
|
100
|
|
|
|
26
|
if ($fast_move_back) { |
428
|
11
|
|
|
|
|
15
|
$remove_node = 1; |
429
|
11
|
50
|
|
|
|
28
|
$message .= ". Fast Move Back " if $parse_trace_routine; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
else { |
432
|
3
|
|
|
|
|
5
|
$move_back_mode = 1; |
433
|
3
|
|
|
|
|
4
|
$not_move_back_mode = 0; |
434
|
3
|
|
|
|
|
74
|
$current_node->{__move_back_to} = 1; |
435
|
3
|
50
|
|
|
|
10
|
$message .= ". Move Back Mode Enabled " if $parse_trace_routine; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
28772
|
100
|
|
|
|
58959
|
if ($create_child) { |
|
|
100
|
|
|
|
|
|
442
|
15929
|
|
|
|
|
18227
|
$create_child = 0; |
443
|
15929
|
|
|
|
|
25718
|
$new_rule = $rule->{$new_rule_name}; |
444
|
15929
|
|
|
|
|
20081
|
$previous_position = $current_position; |
445
|
15929
|
100
|
100
|
|
|
77094
|
if ($any_parse_forward && (my $pf = $new_rule->{parse_forward})) { |
|
|
100
|
|
|
|
|
|
446
|
1000
|
|
|
|
|
933
|
my $delta_position; |
447
|
1000
|
|
|
|
|
1482
|
$parse_hash->{current_position} = $current_position; |
448
|
1000
|
|
|
|
|
1397
|
$parse_hash->{rule_name} = $new_rule_name; |
449
|
1000
|
|
|
|
|
3549
|
($continue_forward, $match, $delta_position) = |
450
|
1000
|
|
|
|
|
1177
|
&{$pf}($parse_hash); |
451
|
1000
|
100
|
|
|
|
6270
|
if (defined $delta_position) { |
452
|
936
|
50
|
|
|
|
1539
|
if ($delta_position < 0) { |
453
|
0
|
|
|
|
|
0
|
croak ("Parse forward on $new_rule_name resulted in |
454
|
|
|
|
|
|
|
backward progress ($previous_position, $delta_position)"); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
else { |
457
|
936
|
|
|
|
|
1514
|
$current_position += $delta_position; |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
} |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
elsif (my $x = $new_rule->{regex_match}) { |
462
|
7048
|
|
|
|
|
17461
|
pos $$parse_this_ref = $current_position; |
463
|
7048
|
100
|
|
|
|
42044
|
if ($$parse_this_ref =~ m/$x/g) { |
464
|
3321
|
100
|
|
|
|
21881
|
if (defined $2) {$match = $2;} |
|
94
|
|
|
|
|
196
|
|
|
3227
|
|
|
|
|
7236
|
|
465
|
|
|
|
|
|
|
else {$match = $1;} |
466
|
3321
|
|
|
|
|
3917
|
$continue_forward = 1; |
467
|
3321
|
|
|
|
|
4641
|
$current_position = pos $$parse_this_ref; |
468
|
3321
|
100
|
|
|
|
6769
|
$message .= 'Leaf matched' if $parse_trace_routine; |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
else { |
471
|
3727
|
|
|
|
|
4179
|
$continue_forward = 0; |
472
|
3727
|
100
|
|
|
|
11085
|
$message .= 'Leaf not matched' if $parse_trace_routine; |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
else { |
476
|
7881
|
|
|
|
|
9564
|
$match = undef; |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
|
479
|
15929
|
100
|
|
|
|
31072
|
if ($continue_forward) { |
480
|
12158
|
100
|
|
|
|
23248
|
if ($current_position > $maximum_position) { |
481
|
2538
|
|
|
|
|
3249
|
$maximum_position = $current_position; |
482
|
2538
|
|
|
|
|
3365
|
$maximum_position_rule = $new_rule_name; |
483
|
|
|
|
|
|
|
} |
484
|
12158
|
100
|
|
|
|
25775
|
if ($current_position == $previous_position) { |
485
|
9226
|
100
|
|
|
|
20708
|
if (defined $position_tree_size->{$current_position}) { |
486
|
7120
|
100
|
|
|
|
17410
|
if ($position_tree_size->{$current_position} < |
487
|
|
|
|
|
|
|
$tree_size - $delta_tree_size) { |
488
|
2
|
|
|
|
|
420
|
croak |
489
|
|
|
|
|
|
|
("$new_rule_name duplicated position $current_position"); |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
} |
492
|
|
|
|
|
|
|
else { |
493
|
2106
|
|
|
|
|
5363
|
$position_tree_size->{$current_position} = $tree_size; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
} |
496
|
12156
|
|
|
|
|
94343
|
my $new_node = { |
497
|
|
|
|
|
|
|
name => $new_rule_name, |
498
|
|
|
|
|
|
|
alias => $new_alias, |
499
|
|
|
|
|
|
|
steps => $steps, |
500
|
|
|
|
|
|
|
parent => $current_node, |
501
|
|
|
|
|
|
|
position_when_entered => $previous_position, |
502
|
|
|
|
|
|
|
__nodes_when_entered => $tree_size, |
503
|
|
|
|
|
|
|
parse_match => $match, |
504
|
|
|
|
|
|
|
child_count => 0 |
505
|
|
|
|
|
|
|
}; |
506
|
12156
|
100
|
|
|
|
41087
|
if ($new_rule->{leaf_rule}) { |
507
|
4275
|
|
|
|
|
5217
|
$node_completed = 1; |
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
else { |
510
|
7881
|
|
|
|
|
8903
|
$moving_forward = 1; |
511
|
7881
|
|
|
|
|
9285
|
$moving_down = 1; |
512
|
|
|
|
|
|
|
} |
513
|
12156
|
|
|
|
|
12403
|
push @{$current_node->{children}}, $new_node; |
|
12156
|
|
|
|
|
29692
|
|
514
|
12156
|
|
|
|
|
17012
|
$current_node->{child_count}++; |
515
|
12156
|
|
|
|
|
13870
|
$current_node = $new_node; |
516
|
12156
|
|
|
|
|
12247
|
$tree_size++; |
517
|
12156
|
|
|
|
|
14597
|
$current_node_name = $new_rule_name; |
518
|
12156
|
|
|
|
|
18443
|
$current_rule = $rule->{$current_node_name}; |
519
|
12156
|
100
|
|
|
|
28562
|
$message = "Creating child $new_rule_name on step $steps for ". |
520
|
|
|
|
|
|
|
"node created on step " |
521
|
|
|
|
|
|
|
.$current_node->{steps} if $parse_trace_routine; |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
else { |
524
|
3771
|
|
|
|
|
4554
|
$continue_forward = 1; |
525
|
3771
|
|
|
|
|
5125
|
$moving_forward = 0; |
526
|
3771
|
|
|
|
|
5088
|
$moving_down = 0; |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
elsif ($remove_node) { |
530
|
5169
|
|
|
|
|
9952
|
$remove_node = 0; |
531
|
5169
|
|
|
|
|
5141
|
$moving_forward = 0; |
532
|
5169
|
|
|
|
|
10314
|
$moving_down = 0; |
533
|
5169
|
|
|
|
|
8362
|
$current_position = $current_node->{position_when_entered}; |
534
|
5169
|
100
|
|
|
|
10945
|
if ($bottom_up) { |
535
|
4564
|
|
|
|
|
16215
|
my $change_in_tree = |
536
|
|
|
|
|
|
|
$tree_size - $current_node->{__nodes_when_entered}; |
537
|
4564
|
100
|
|
|
|
9588
|
if ($change_in_tree > 1) { |
538
|
9
|
|
|
|
|
41
|
splice (@$bottom_up_left_to_right, 1 - $change_in_tree); |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
} |
541
|
5169
|
|
|
|
|
6874
|
$tree_size = $current_node->{__nodes_when_entered}; |
542
|
5169
|
100
|
100
|
|
|
23573
|
if (defined $position_tree_size->{$current_position} |
543
|
|
|
|
|
|
|
&& ($position_tree_size->{$current_position} == $tree_size)) { |
544
|
537
|
|
|
|
|
1271
|
delete $position_tree_size->{$current_position}; |
545
|
|
|
|
|
|
|
} |
546
|
5169
|
100
|
|
|
|
10049
|
$message .= " Removed node created on step ".$current_node->{steps} |
547
|
|
|
|
|
|
|
if $parse_trace_routine; |
548
|
5169
|
|
|
|
|
11031
|
$parse_hash->{parse_match} = $current_node->{parse_match}; |
549
|
5169
|
100
|
100
|
|
|
12132
|
if ($move_back_mode && $current_node->{__move_back_to}) { |
550
|
3
|
|
|
|
|
5
|
$move_back_mode = 0; |
551
|
3
|
|
|
|
|
4
|
$not_move_back_mode = 1; |
552
|
3
|
50
|
|
|
|
23
|
$message .= ". Move Back Mode Completed" |
553
|
|
|
|
|
|
|
if $parse_trace_routine; |
554
|
|
|
|
|
|
|
} |
555
|
5169
|
|
|
|
|
7665
|
$current_node = $current_node->{parent}; |
556
|
5169
|
100
|
|
|
|
10383
|
if (defined $current_node) { |
557
|
4866
|
|
|
|
|
5125
|
pop @{$current_node->{children}}; |
|
4866
|
|
|
|
|
8101
|
|
558
|
4866
|
|
|
|
|
32202
|
$current_node->{child_count}--; |
559
|
4866
|
100
|
100
|
|
|
11162
|
if ($any_parse_backtrack && $current_rule->{parse_backtrack}) { |
560
|
12
|
|
|
|
|
31
|
$parse_hash->{current_position} = $current_position; |
561
|
12
|
|
|
|
|
25
|
$parse_hash->{rule_name} = $current_node_name; |
562
|
12
|
|
|
|
|
18
|
$end_parse_now = &{$current_rule->{parse_backtrack}} |
|
12
|
|
|
|
|
78
|
|
563
|
|
|
|
|
|
|
($parse_hash); |
564
|
12
|
100
|
|
|
|
1221
|
if ($end_parse_now) { |
565
|
3
|
|
|
|
|
6
|
$current_node = undef; |
566
|
3
|
|
|
|
|
6
|
$moving_forward = 0; |
567
|
3
|
|
|
|
|
7
|
last; |
568
|
|
|
|
|
|
|
} |
569
|
|
|
|
|
|
|
} |
570
|
4863
|
|
|
|
|
7355
|
$current_node_name = $current_node->{name}; |
571
|
4863
|
|
|
|
|
13011
|
$current_rule = $rule->{$current_node_name}; |
572
|
|
|
|
|
|
|
} |
573
|
5166
|
|
|
|
|
10130
|
delete $parse_hash->{parse_match}; |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
28767
|
100
|
|
|
|
123153
|
if ($node_completed) { |
577
|
9899
|
|
|
|
|
10150
|
$node_completed = 0; |
578
|
9899
|
|
|
|
|
14058
|
my $parent = $current_node->{parent}; |
579
|
9899
|
100
|
100
|
|
|
50403
|
if ($current_position == $current_node->{position_when_entered} |
|
|
|
100
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
580
|
|
|
|
|
|
|
&& $parent && |
581
|
|
|
|
|
|
|
(defined $rule->{$parent->{name}}->{minimum_child}) |
582
|
|
|
|
|
|
|
&& ($not_any_minimum_child || ($parent->{child_count} > |
583
|
|
|
|
|
|
|
$rule->{$parent->{name}}->{minimum_child})) |
584
|
|
|
|
|
|
|
) { |
585
|
2
|
50
|
|
|
|
5
|
$message .= " Last child empty, Child of multiple cannot be empty " |
586
|
|
|
|
|
|
|
if $parse_trace_routine; |
587
|
2
|
|
|
|
|
3
|
$moving_forward = 0; |
588
|
2
|
|
|
|
|
10
|
$moving_down = 1; |
589
|
|
|
|
|
|
|
} |
590
|
|
|
|
|
|
|
else { |
591
|
9897
|
|
|
|
|
12157
|
my $reject; |
592
|
9897
|
100
|
|
|
|
23268
|
if ($do_evaluation_in_parsing) { |
593
|
1242
|
|
|
|
|
4262
|
$parameters->{nodes} = [$current_node]; |
594
|
1242
|
|
|
|
|
2658
|
$parse_hash->{current_position} = $current_position; |
595
|
1242
|
100
|
|
|
|
2899
|
if ($parse_stallion->new_evaluate_tree_node($parameters)) { |
596
|
70
|
|
|
|
|
98
|
$moving_forward = 0; |
597
|
70
|
|
|
|
|
119
|
$moving_down = 1; |
598
|
70
|
50
|
|
|
|
148
|
$message .= " Node rejected" if $parse_trace_routine; |
599
|
70
|
|
|
|
|
383
|
next; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
} |
602
|
9827
|
100
|
|
|
|
30319
|
push @$bottom_up_left_to_right, $current_node if $bottom_up; |
603
|
9827
|
100
|
|
|
|
17044
|
$message .= " Completed node created on step ". |
604
|
|
|
|
|
|
|
$current_node->{steps} if $parse_trace_routine; |
605
|
9827
|
|
|
|
|
10699
|
$moving_down = 0; |
606
|
9827
|
|
|
|
|
9388
|
$moving_forward = 1; |
607
|
9827
|
|
|
|
|
24301
|
$current_node->{position_when_completed} = $current_position; |
608
|
9827
|
100
|
|
|
|
39564
|
if ($current_node = $parent) { |
609
|
9338
|
|
|
|
|
13065
|
$current_node_name = $current_node->{name}; |
610
|
9338
|
|
|
|
|
54207
|
$current_rule = $rule->{$current_node_name}; |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
} |
615
|
796
|
100
|
100
|
|
|
6280
|
if (!$current_node && $moving_forward && $must_parse_length && |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
616
|
|
|
|
|
|
|
($parse_this_length != $current_position)) { |
617
|
120
|
|
|
|
|
149
|
$moving_forward = 0; |
618
|
120
|
|
|
|
|
144
|
$moving_down = 1; |
619
|
120
|
|
|
|
|
152
|
$current_node = $tree; |
620
|
120
|
|
|
|
|
300
|
$current_node_name = $current_node->{name}; |
621
|
120
|
100
|
|
|
|
331
|
$message .= ' . At top of tree but did not parse entire object' |
622
|
|
|
|
|
|
|
if $parse_trace_routine; |
623
|
120
|
100
|
|
|
|
350
|
pop @$bottom_up_left_to_right if $bottom_up; |
624
|
120
|
100
|
66
|
|
|
314
|
if ($any_match_once |
625
|
|
|
|
|
|
|
&& $rule->{$current_node_name}->{match_once}) { |
626
|
1
|
50
|
|
|
|
4
|
if ($fast_move_back) { |
627
|
1
|
|
|
|
|
2
|
$current_node = undef; |
628
|
1
|
50
|
|
|
|
4
|
$message .= ". Fast Move Back " if $parse_trace_routine; |
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
else { |
631
|
0
|
|
|
|
|
0
|
$move_back_mode = 1; |
632
|
0
|
|
|
|
|
0
|
$not_move_back_mode = 0; |
633
|
0
|
|
|
|
|
0
|
$current_node->{__move_back_to} = 1; |
634
|
0
|
0
|
|
|
|
0
|
$message .= ". Move Back Mode Enabled " if $parse_trace_routine; |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
} |
638
|
796
|
50
|
33
|
|
|
4937
|
if ($no_max_steps && ($steps == $max_steps)) { |
639
|
0
|
|
|
|
|
0
|
$max_steps += 1000000; |
640
|
|
|
|
|
|
|
} |
641
|
|
|
|
|
|
|
} |
642
|
677
|
|
|
|
|
1665
|
$results->{start_rule} = $start_rule; |
643
|
677
|
|
|
|
|
1182
|
$results->{number_of_steps} = $steps; |
644
|
677
|
|
|
|
|
1206
|
$results->{final_position} = $current_position; |
645
|
677
|
|
|
|
|
1259
|
$results->{final_position_rule} = $current_node_name; |
646
|
677
|
|
|
|
|
1315
|
$results->{parse_backtrack_value} = $end_parse_now; |
647
|
677
|
|
|
|
|
1295
|
$results->{maximum_position} = $maximum_position; |
648
|
677
|
|
|
|
|
1653
|
$results->{maximum_position_rule} = $maximum_position_rule; |
649
|
677
|
100
|
66
|
|
|
2684
|
if (!$moving_forward && !$current_node) { |
650
|
307
|
|
|
|
|
768
|
$results->{tree} = {}; |
651
|
|
|
|
|
|
|
} |
652
|
|
|
|
|
|
|
else { |
653
|
370
|
|
|
|
|
1213
|
$results->{tree} = $tree; |
654
|
|
|
|
|
|
|
} |
655
|
677
|
|
|
|
|
1455
|
$results->{tree_size} = $tree_size; |
656
|
677
|
|
|
|
|
1741
|
$results->{bottom_up_left_to_right} = $bottom_up_left_to_right; |
657
|
677
|
100
|
|
|
|
1824
|
if ($steps >= $max_steps) { |
658
|
1
|
|
|
|
|
219
|
croak ("Not enough steps to do parse, max set at $max_steps"); |
659
|
|
|
|
|
|
|
} |
660
|
676
|
100
|
|
|
|
1762
|
if ($moving_forward) { |
661
|
369
|
|
|
|
|
687
|
$results->{parse_succeeded} = 1; |
662
|
369
|
100
|
|
|
|
1328
|
if ($do_evaluation_in_parsing) { |
663
|
51
|
|
|
|
|
128
|
$results->{parsing_evaluation} = $tree->{computed_value}; |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
} |
666
|
|
|
|
|
|
|
else { |
667
|
307
|
|
|
|
|
507
|
$results->{parse_succeeded} = 0; |
668
|
|
|
|
|
|
|
} |
669
|
676
|
|
|
|
|
4120
|
return $results; |
670
|
|
|
|
|
|
|
} |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
package Parse::Stallion; |
673
|
|
|
|
|
|
|
require Exporter; |
674
|
|
|
|
|
|
|
our $VERSION = '2.01'; |
675
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
676
|
|
|
|
|
|
|
our @EXPORT = |
677
|
|
|
|
|
|
|
qw(A AND O OR LEAF L MATCHED_STRING |
678
|
|
|
|
|
|
|
MATCH_MIN_FIRST MATCH_ONCE M MULTIPLE OPTIONAL |
679
|
|
|
|
|
|
|
ZERO_OR_ONE Z |
680
|
|
|
|
|
|
|
E EVALUATION U UNEVALUATION PF PARSE_FORWARD PB PARSE_BACKTRACK |
681
|
|
|
|
|
|
|
RULE_INFO R TERMINAL TOKEN |
682
|
|
|
|
|
|
|
LEAF_DISPLAY USE_STRING_MATCH LOCATION SE STRING_EVALUATION |
683
|
|
|
|
|
|
|
I IN INC INCORPORATE |
684
|
|
|
|
|
|
|
); |
685
|
32
|
|
|
32
|
|
298
|
use strict; |
|
32
|
|
|
|
|
69
|
|
|
32
|
|
|
|
|
1286
|
|
686
|
32
|
|
|
32
|
|
176
|
use warnings; |
|
32
|
|
|
|
|
60
|
|
|
32
|
|
|
|
|
1159
|
|
687
|
32
|
|
|
32
|
|
616
|
use Carp; |
|
32
|
|
|
|
|
76
|
|
|
32
|
|
|
|
|
328700
|
|
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
sub new { |
690
|
159
|
|
|
159
|
0
|
28769
|
my $type = shift; |
691
|
159
|
|
33
|
|
|
1075
|
my $class = ref($type) || $type; |
692
|
159
|
|
|
|
|
350
|
my $rules_to_set_up_hash = shift; |
693
|
159
|
|
|
|
|
271
|
my $parameters = shift; |
694
|
159
|
|
|
|
|
320
|
my $self = {}; |
695
|
|
|
|
|
|
|
|
696
|
159
|
|
|
|
|
487
|
bless $self, $class; |
697
|
159
|
|
|
|
|
726
|
$self->{separator} = '__XZ__'; |
698
|
159
|
|
50
|
|
|
990
|
$self->{max_steps} = $parameters->{max_steps} || 1000000; |
699
|
159
|
|
50
|
|
|
955
|
$self->{parse_trace_routine} = $parameters->{parse_trace_routine} || undef; |
700
|
159
|
|
|
|
|
410
|
$self->{multiple_rule_mins} = 0; |
701
|
159
|
|
|
|
|
419
|
$self->{any_match_once} = 0; |
702
|
159
|
|
|
|
|
357
|
$self->{any_minimize_children} = 0; |
703
|
159
|
|
|
|
|
377
|
$self->{any_unevaluation} = 0; |
704
|
159
|
|
|
|
|
492
|
$self->{any_parse_forward} = 0; |
705
|
159
|
|
|
|
|
450
|
$self->{any_parse_backtrack} = 0; |
706
|
159
|
|
|
|
|
387
|
$self->{any_maximum_child} = 0; |
707
|
159
|
|
|
|
|
434
|
$self->{any_minimum_child} = 0; |
708
|
159
|
|
|
|
|
413
|
$self->{self} = $self; |
709
|
159
|
50
|
50
|
|
|
1040
|
if ($self->{no_evaluation} = $parameters->{no_evaluation} || 0) { |
710
|
0
|
|
|
|
|
0
|
$self->{do_evaluation_in_parsing} = 0; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
else { |
713
|
159
|
|
100
|
|
|
941
|
$self->{do_evaluation_in_parsing} = $parameters->{do_evaluation_in_parsing} |
714
|
|
|
|
|
|
|
|| 0; |
715
|
|
|
|
|
|
|
} |
716
|
159
|
|
50
|
|
|
1734
|
$self->{unreachable_rules_allowed} = $parameters->{unreachable_rules_allowed} |
717
|
|
|
|
|
|
|
|| 0; |
718
|
159
|
|
100
|
|
|
1150
|
$self->{do_not_compress_eval} = $parameters->{do_not_compress_eval} || 0; |
719
|
159
|
|
66
|
|
|
786
|
$self->{separator} = $parameters->{separator} || $self->{separator}; |
720
|
159
|
100
|
|
|
|
491
|
if (defined $parameters->{parse_forward}) { |
721
|
1
|
|
|
|
|
3
|
$self->{leaf_parse_forward} = $parameters->{parse_forward}; |
722
|
1
|
|
|
|
|
2
|
$self->{any_parse_forward} = 1; |
723
|
|
|
|
|
|
|
} |
724
|
159
|
100
|
|
|
|
622
|
if (defined $parameters->{parse_backtrack}) { |
725
|
1
|
|
|
|
|
3
|
$self->{leaf_parse_backtrack} = $parameters->{parse_backtrack}; |
726
|
1
|
|
|
|
|
2
|
$self->{any_parse_backtrack} = 1; |
727
|
|
|
|
|
|
|
} |
728
|
159
|
100
|
|
|
|
424
|
if (defined $parameters->{length_routine}) { |
729
|
1
|
|
|
|
|
3
|
$self->{length_routine} = $parameters->{length_routine}; |
730
|
|
|
|
|
|
|
} |
731
|
|
|
|
|
|
|
else { |
732
|
500
|
|
|
500
|
|
730
|
$self->{length_routine} = sub {return length(${$_[0]});} |
|
500
|
|
|
|
|
1818
|
|
733
|
158
|
|
|
|
|
987
|
} |
734
|
159
|
100
|
|
|
|
567
|
$self->incorporate_others($parameters->{incorporate}) |
735
|
|
|
|
|
|
|
if defined $parameters->{incorporate}; |
736
|
158
|
|
|
|
|
829
|
$self->set_up_full_rule_set($rules_to_set_up_hash, $parameters); |
737
|
147
|
|
|
|
|
215
|
my $number_of_rules = scalar(keys %{$self->{rule}}); |
|
147
|
|
|
|
|
706
|
|
738
|
147
|
|
|
|
|
261
|
my $min_multiplier = $number_of_rules; |
739
|
147
|
|
|
|
|
538
|
$self->{max_nodes_before_size_must_change} = $number_of_rules + |
740
|
|
|
|
|
|
|
$min_multiplier * $self->{multiple_rule_mins}; |
741
|
147
|
|
100
|
|
|
1379
|
$self->{fast_move_back} = $parameters->{fast_move_back} || |
742
|
|
|
|
|
|
|
!($self->{any_parse_backtrack} || $self->{any_unevaluation}); |
743
|
147
|
|
|
|
|
689
|
return $self; |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
sub copy_tree_node_list { |
747
|
65
|
|
|
65
|
0
|
94
|
my $list = shift; |
748
|
65
|
|
|
|
|
70
|
my @new_list; |
749
|
|
|
|
|
|
|
my %parent_hash; |
750
|
65
|
|
|
|
|
193
|
my $node_count = scalar @$list - 1; |
751
|
65
|
|
|
|
|
106
|
my $node_to_copy = $list->[$node_count]; |
752
|
65
|
|
|
|
|
472
|
$new_list[$node_count] = { |
753
|
|
|
|
|
|
|
name => $node_to_copy->{name}, |
754
|
|
|
|
|
|
|
alias => $node_to_copy->{alias}, |
755
|
|
|
|
|
|
|
parse_match => $node_to_copy->{parse_match}, |
756
|
|
|
|
|
|
|
position_when_entered => $node_to_copy->{position_when_entered}, |
757
|
|
|
|
|
|
|
position_when_completed => $node_to_copy->{position_when_completed} |
758
|
|
|
|
|
|
|
}; |
759
|
65
|
|
|
|
|
204
|
$parent_hash{$node_to_copy} = $node_count; |
760
|
65
|
|
|
|
|
371
|
for (my $i = $node_count-1; $i > -1; $i--) { |
761
|
149
|
|
|
|
|
185
|
$node_to_copy = $list->[$i]; |
762
|
149
|
|
|
|
|
318
|
$parent_hash{$node_to_copy} = $i; |
763
|
149
|
|
|
|
|
2073
|
$new_list[$i] = { |
764
|
|
|
|
|
|
|
name => $node_to_copy->{name}, |
765
|
|
|
|
|
|
|
alias => $node_to_copy->{alias}, |
766
|
|
|
|
|
|
|
parse_match => $node_to_copy->{parse_match}, |
767
|
|
|
|
|
|
|
position_when_entered => $node_to_copy->{position_when_entered}, |
768
|
|
|
|
|
|
|
position_when_completed => $node_to_copy->{position_when_completed}, |
769
|
|
|
|
|
|
|
parent => $new_list[$parent_hash{$node_to_copy->{parent}}], |
770
|
|
|
|
|
|
|
}; |
771
|
|
|
|
|
|
|
} |
772
|
65
|
|
|
|
|
243
|
return \@new_list; |
773
|
|
|
|
|
|
|
} |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
sub parse_and_evaluate { |
776
|
424
|
|
|
424
|
0
|
211075
|
my $self = shift; |
777
|
424
|
|
100
|
|
|
2840
|
my $parameters = $_[1] || {}; |
778
|
424
|
|
|
|
|
676
|
my $in_is_string = 0; |
779
|
424
|
|
100
|
|
|
3025
|
$parameters->{parse_info} = $parameters->{parse_info} || {}; |
780
|
424
|
|
50
|
|
|
3421
|
$parameters->{parse_hash} = $parameters->{parse_hash} || {}; |
781
|
424
|
|
|
|
|
718
|
my $initial_position = 0; |
782
|
424
|
50
|
|
|
|
1360
|
if (defined $_[0]) { |
783
|
424
|
|
|
|
|
946
|
$parameters->{parse_this_ref} = \$_[0]; |
784
|
424
|
50
|
|
|
|
1278
|
if (ref $_[0] eq '') { |
785
|
424
|
|
|
|
|
565
|
$in_is_string = 1; |
786
|
424
|
|
100
|
|
|
2339
|
$initial_position = pos $_[0] || 0; |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
} |
789
|
424
|
|
|
|
|
545
|
my $find_all; |
790
|
424
|
100
|
|
|
|
1827
|
if (defined $parameters->{find_all}) { |
|
|
100
|
|
|
|
|
|
791
|
4
|
|
|
|
|
10
|
$find_all = $parameters->{find_all}; |
792
|
|
|
|
|
|
|
} |
793
|
|
|
|
|
|
|
elsif ($parameters->{global}) { |
794
|
18
|
100
|
|
|
|
44
|
if (wantarray) { |
795
|
4
|
|
|
|
|
11
|
$find_all = 1; |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
else { |
798
|
14
|
|
|
|
|
22
|
$find_all = 0; |
799
|
|
|
|
|
|
|
} |
800
|
|
|
|
|
|
|
} |
801
|
424
|
100
|
|
|
|
1105
|
if (defined $parameters->{start_position}) { |
802
|
10
|
|
|
|
|
15
|
$initial_position = $parameters->{start_position}; |
803
|
|
|
|
|
|
|
} |
804
|
424
|
|
|
|
|
519
|
my $not_match_start; |
805
|
424
|
100
|
|
|
|
1170
|
if (!defined $parameters->{match_start}) { |
806
|
399
|
|
|
|
|
569
|
$not_match_start = 0; |
807
|
|
|
|
|
|
|
} |
808
|
|
|
|
|
|
|
else { |
809
|
25
|
|
|
|
|
53
|
$not_match_start = !$parameters->{match_start}; |
810
|
|
|
|
|
|
|
} |
811
|
424
|
100
|
|
|
|
1002
|
if (!defined $parameters->{match_length}) { |
812
|
377
|
|
|
|
|
1192
|
$parameters->{parse_hash}->{__match_length} = 1; |
813
|
|
|
|
|
|
|
} |
814
|
|
|
|
|
|
|
else { |
815
|
47
|
|
|
|
|
120
|
$parameters->{parse_hash}->{__match_length} = $parameters->{match_length}; |
816
|
|
|
|
|
|
|
} |
817
|
424
|
|
|
|
|
1618
|
$parameters->{parse_hash}->{__initial_position} = $initial_position; |
818
|
424
|
|
|
|
|
691
|
my $parse_this_ref = $parameters->{parse_this_ref}; |
819
|
424
|
|
|
|
|
1477
|
my $parse_this_length = $parameters->{parse_hash}->{__parse_this_length} = |
820
|
|
|
|
|
|
|
$self->{length_routine}($parse_this_ref); |
821
|
424
|
|
|
|
|
1758
|
my $parser = new Parse::Stallion::Parser($self); |
822
|
424
|
|
|
|
|
632
|
my $substitution_subroutine; |
823
|
|
|
|
|
|
|
my $substitute; |
824
|
424
|
50
|
100
|
|
|
2909
|
if (defined $parameters->{substitution}) { |
|
|
100
|
|
|
|
|
|
825
|
0
|
|
|
|
|
0
|
$substitute = 1; |
826
|
0
|
0
|
|
|
|
0
|
if (ref $parameters->{substitution} eq 'CODE') { |
827
|
0
|
|
|
|
|
0
|
$substitution_subroutine = $parameters->{substitution}; |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
else { |
830
|
0
|
|
|
0
|
|
0
|
$substitution_subroutine = sub {return $parameters->{substitution}}; |
|
0
|
|
|
|
|
0
|
|
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
} |
833
|
|
|
|
|
|
|
elsif ($substitute = $parameters->{substitute} || 0) { |
834
|
40
|
|
|
40
|
|
90
|
$substitution_subroutine = sub {return $_[0];} |
835
|
13
|
|
|
|
|
178
|
} |
836
|
424
|
|
|
|
|
1381
|
$parameters->{parse_hash}->{rule_info} = |
837
|
|
|
|
|
|
|
$self->{rule_info}; |
838
|
424
|
|
|
|
|
517
|
my $parser_results; |
839
|
424
|
100
|
|
|
|
1087
|
if ($parameters->{parse_trace}) { |
840
|
|
|
|
|
|
|
$parameters->{parse_trace_routine} = sub { |
841
|
123
|
|
|
123
|
|
161
|
my $parse_hash = shift; |
842
|
123
|
|
|
|
|
141
|
my $parent_step = 0; |
843
|
123
|
|
|
|
|
245
|
my $current_node = ${$parse_hash->{__current_node_ref}}; |
|
123
|
|
|
|
|
311
|
|
844
|
123
|
100
|
|
|
|
315
|
if ($current_node->{parent}) { |
845
|
104
|
|
|
|
|
358
|
$parent_step = $current_node->{parent}->{steps}; |
846
|
|
|
|
|
|
|
} |
847
|
123
|
|
|
|
|
211
|
push @{$parameters->{parse_trace}}, { |
|
123
|
|
|
|
|
191
|
|
848
|
123
|
|
|
|
|
315
|
rule_name => ${$parse_hash->{__current_node_name_ref}}, |
849
|
123
|
|
|
|
|
162
|
moving_forward => ${$parse_hash->{__moving_forward_ref}}, |
850
|
123
|
|
|
|
|
210
|
moving_down => ${$parse_hash->{__moving_down_ref}}, |
851
|
123
|
|
|
|
|
319
|
position => ${$parse_hash->{__current_position_ref}}, |
852
|
|
|
|
|
|
|
node_creation_step => $current_node->{steps}, |
853
|
|
|
|
|
|
|
parent_node_creation_step => $parent_step, |
854
|
123
|
|
|
|
|
131
|
message => ${$parse_hash->{__message_ref}}, |
855
|
|
|
|
|
|
|
tree => $parse_hash->{__tree}->stringify, |
856
|
|
|
|
|
|
|
}; |
857
|
5
|
|
|
|
|
40
|
}; |
858
|
|
|
|
|
|
|
} |
859
|
424
|
|
|
|
|
572
|
my $match_position; |
860
|
424
|
|
|
|
|
668
|
my $match_maximum = $parameters->{match_maximum}; |
861
|
424
|
|
|
|
|
793
|
my $match_minimum = $parameters->{match_minimum}; |
862
|
424
|
50
|
66
|
|
|
1429
|
if ($match_maximum && $match_minimum) { |
863
|
0
|
|
|
|
|
0
|
croak "Cannot match both maximum and minimum"; |
864
|
|
|
|
|
|
|
} |
865
|
424
|
100
|
100
|
|
|
2043
|
if ($match_maximum || $match_minimum) { |
866
|
23
|
|
|
|
|
42
|
$parameters->{parse_hash}->{__match_length} = 0; |
867
|
|
|
|
|
|
|
} |
868
|
424
|
|
|
|
|
617
|
my $tree_to_evaluate = undef; |
869
|
424
|
|
|
|
|
539
|
my $to_return; |
870
|
|
|
|
|
|
|
my @results_array; |
871
|
424
|
|
|
|
|
515
|
my $continue_to_parse = 1; |
872
|
424
|
|
|
|
|
498
|
my $parse_succeeded; |
873
|
424
|
|
|
|
|
927
|
while ($continue_to_parse) { |
874
|
466
|
|
|
|
|
636
|
$continue_to_parse = 0; |
875
|
466
|
100
|
|
|
|
1428
|
if ($match_maximum) { |
|
|
100
|
|
|
|
|
|
876
|
22
|
|
|
|
|
30
|
$match_position = -1; |
877
|
|
|
|
|
|
|
} |
878
|
|
|
|
|
|
|
elsif ($match_minimum) { |
879
|
23
|
|
|
|
|
27
|
$match_position = $parse_this_length; |
880
|
|
|
|
|
|
|
} |
881
|
466
|
|
|
|
|
538
|
$parse_succeeded = 0; |
882
|
466
|
|
|
|
|
541
|
my $root_node; |
883
|
466
|
|
|
|
|
611
|
my $repeat_parse_by_start = 1; |
884
|
466
|
|
|
|
|
1075
|
while ($repeat_parse_by_start) { |
885
|
617
|
|
|
|
|
700
|
$repeat_parse_by_start = 0; |
886
|
617
|
|
|
|
|
722
|
my $repeat_parse = 1; |
887
|
617
|
|
|
|
|
1438
|
while ($repeat_parse) { |
888
|
704
|
|
|
|
|
854
|
$repeat_parse = 0; |
889
|
704
|
|
|
|
|
953
|
$parser_results = eval {$parser->parse($parameters)}; |
|
704
|
|
|
|
|
1865
|
|
890
|
704
|
100
|
|
|
|
2065
|
if ($@) {croak ($@)}; |
|
3
|
|
|
|
|
418
|
|
891
|
701
|
100
|
|
|
|
2307
|
if ($parser_results->{parse_succeeded}) { |
892
|
390
|
|
|
|
|
580
|
$parse_succeeded = 1; |
893
|
390
|
100
|
100
|
|
|
2528
|
if ($match_maximum && |
|
|
100
|
66
|
|
|
|
|
|
|
100
|
|
|
|
|
|
894
|
|
|
|
|
|
|
($parser_results->{final_position} < $parse_this_length)) { |
895
|
39
|
100
|
|
|
|
94
|
if ($parser_results->{final_position} > $match_position) { |
896
|
29
|
|
|
|
|
36
|
$match_position = $parser_results->{final_position}; |
897
|
29
|
50
|
|
|
|
61
|
if ($self->{do_evaluation_in_parsing}) { |
898
|
0
|
|
|
|
|
0
|
$to_return = $parser_results->{parsing_evaluation}; |
899
|
|
|
|
|
|
|
} |
900
|
|
|
|
|
|
|
else { |
901
|
29
|
|
|
|
|
82
|
$tree_to_evaluate = copy_tree_node_list( |
902
|
|
|
|
|
|
|
$parser_results->{bottom_up_left_to_right}); |
903
|
29
|
|
|
|
|
87
|
$root_node = |
904
|
|
|
|
|
|
|
$tree_to_evaluate->[$parser_results->{tree_size}-1]; |
905
|
|
|
|
|
|
|
} |
906
|
|
|
|
|
|
|
} |
907
|
39
|
|
|
|
|
55
|
$repeat_parse = 1; |
908
|
39
|
|
|
|
|
135
|
$parameters->{continue_parse} = 1; |
909
|
39
|
|
|
|
|
46
|
${$parameters->{parse_hash}->{__moving_forward_ref}} = 0; |
|
39
|
|
|
|
|
140
|
|
910
|
39
|
|
|
|
|
50
|
${$parameters->{parse_hash}->{__moving_down_ref}} = 1; |
|
39
|
|
|
|
|
60
|
|
911
|
39
|
|
|
|
|
84
|
$parameters->{parse_hash}->{current_node} = |
912
|
|
|
|
|
|
|
$parameters->{parse_hash}->{tree}; |
913
|
39
|
50
|
|
|
|
96
|
${$parameters->{parse_hash}->{__message_ref}} .= |
|
0
|
|
|
|
|
0
|
|
914
|
|
|
|
|
|
|
' . Looking for longer match ' |
915
|
|
|
|
|
|
|
if $parameters->{parse_hash}->{__parse_trace_routine}; |
916
|
39
|
50
|
|
|
|
90
|
pop @{$parser_results->{bottom_up_left_to_right}} |
|
39
|
|
|
|
|
115
|
|
917
|
|
|
|
|
|
|
if $parameters->{parse_hash}->{__bottom_up}; |
918
|
|
|
|
|
|
|
} |
919
|
|
|
|
|
|
|
elsif ($match_minimum && |
920
|
|
|
|
|
|
|
($parser_results->{final_position} > $initial_position)) { |
921
|
48
|
100
|
|
|
|
116
|
if ($parser_results->{final_position} < $match_position) { |
922
|
36
|
|
|
|
|
48
|
$match_position = $parser_results->{final_position}; |
923
|
36
|
50
|
|
|
|
552
|
if ($self->{do_evaluation_in_parsing}) { |
924
|
0
|
|
|
|
|
0
|
$to_return = $parser_results->{parsing_evaluation}; |
925
|
|
|
|
|
|
|
} |
926
|
|
|
|
|
|
|
else { |
927
|
36
|
|
|
|
|
89
|
$tree_to_evaluate = copy_tree_node_list( |
928
|
|
|
|
|
|
|
$parser_results->{bottom_up_left_to_right}); |
929
|
36
|
|
|
|
|
132
|
$root_node = |
930
|
|
|
|
|
|
|
$tree_to_evaluate->[$parser_results->{tree_size}-1]; |
931
|
|
|
|
|
|
|
} |
932
|
|
|
|
|
|
|
} |
933
|
48
|
|
|
|
|
72
|
$repeat_parse = 1; |
934
|
48
|
|
|
|
|
137
|
$parameters->{continue_parse} = 1; |
935
|
48
|
|
|
|
|
50
|
${$parameters->{parse_hash}->{__moving_forward_ref}} = 0; |
|
48
|
|
|
|
|
85
|
|
936
|
48
|
|
|
|
|
58
|
${$parameters->{parse_hash}->{__moving_down_ref}} = 1; |
|
48
|
|
|
|
|
73
|
|
937
|
48
|
|
|
|
|
88
|
$parameters->{parse_hash}->{current_node} = |
938
|
|
|
|
|
|
|
$parameters->{parse_hash}->{tree}; |
939
|
48
|
50
|
|
|
|
111
|
${$parameters->{parse_hash}->{__message_ref}} .= |
|
0
|
|
|
|
|
0
|
|
940
|
|
|
|
|
|
|
' . Looking for shorter match ' |
941
|
|
|
|
|
|
|
if $parameters->{parse_hash}->{__parse_trace_routine}; |
942
|
48
|
50
|
|
|
|
101
|
pop @{$parser_results->{bottom_up_left_to_right}} |
|
48
|
|
|
|
|
252
|
|
943
|
|
|
|
|
|
|
if $parameters->{parse_hash}->{__bottom_up}; |
944
|
|
|
|
|
|
|
} |
945
|
|
|
|
|
|
|
elsif ($self->{do_evaluation_in_parsing}) { |
946
|
51
|
|
|
|
|
98
|
$match_position = $parser_results->{final_position}; |
947
|
51
|
|
|
|
|
180
|
$to_return = $parser_results->{parsing_evaluation}; |
948
|
|
|
|
|
|
|
} |
949
|
|
|
|
|
|
|
else { |
950
|
252
|
|
|
|
|
517
|
$match_position = $parser_results->{final_position}; |
951
|
252
|
|
|
|
|
413
|
$tree_to_evaluate = $parser_results->{bottom_up_left_to_right}; |
952
|
252
|
|
|
|
|
2596
|
$root_node = $parser_results->{tree}; |
953
|
|
|
|
|
|
|
} |
954
|
|
|
|
|
|
|
} |
955
|
|
|
|
|
|
|
} |
956
|
614
|
100
|
100
|
|
|
4163
|
if (!($parse_succeeded) && $not_match_start && |
|
|
|
100
|
|
|
|
|
957
|
|
|
|
|
|
|
($parse_this_length > $initial_position)) { |
958
|
151
|
|
|
|
|
338
|
$parameters->{parse_hash}->{__initial_position}++; |
959
|
151
|
|
|
|
|
159
|
$initial_position++; |
960
|
151
|
|
|
|
|
2367
|
$parameters->{continue_parse} = 0; |
961
|
151
|
|
|
|
|
350
|
$repeat_parse_by_start = 1; |
962
|
|
|
|
|
|
|
} |
963
|
|
|
|
|
|
|
} |
964
|
|
|
|
|
|
|
|
965
|
463
|
|
100
|
|
|
2077
|
$parser_results->{parse_succeeded} = |
966
|
|
|
|
|
|
|
$parser_results->{parse_succeeded} || $parse_succeeded; |
967
|
463
|
100
|
66
|
|
|
3255
|
if (!($parse_succeeded) || $self->{no_evaluation}) { |
|
|
100
|
|
|
|
|
|
968
|
123
|
|
|
|
|
206
|
$to_return = undef; |
969
|
|
|
|
|
|
|
} |
970
|
|
|
|
|
|
|
elsif ($self->{do_evaluation_in_parsing}) { |
971
|
51
|
50
|
|
|
|
130
|
if (!defined $to_return) {$to_return = ''}; |
|
0
|
|
|
|
|
0
|
|
972
|
|
|
|
|
|
|
} |
973
|
|
|
|
|
|
|
else { |
974
|
289
|
|
|
|
|
618
|
$parameters->{nodes} = $tree_to_evaluate; |
975
|
289
|
|
|
|
|
1296
|
$self->new_evaluate_tree_node($parameters); |
976
|
|
|
|
|
|
|
#$to_return = $parser_results->{tree}->{computed_value}; |
977
|
288
|
|
|
|
|
511
|
$to_return = $root_node->{computed_value}; |
978
|
288
|
100
|
|
|
|
3020
|
if (!defined $to_return) {$to_return = ''}; |
|
7
|
|
|
|
|
12
|
|
979
|
|
|
|
|
|
|
} |
980
|
462
|
100
|
100
|
|
|
2249
|
if ((defined $to_return) && ($substitute) ) { |
981
|
40
|
|
|
|
|
69
|
my $replaced_length = $match_position - $initial_position; |
982
|
40
|
|
|
|
|
283
|
my $to_sub = &{$substitution_subroutine}($to_return); |
|
40
|
|
|
|
|
97
|
|
983
|
40
|
|
|
|
|
56
|
substr(${$parameters->{parse_this_ref}}, $initial_position, |
|
40
|
|
|
|
|
131
|
|
984
|
|
|
|
|
|
|
$replaced_length) = $to_sub; |
985
|
40
|
|
|
|
|
225
|
$match_position += $self->{length_routine}(\$to_sub) - $replaced_length; |
986
|
40
|
|
|
|
|
90
|
$parameters->{parse_hash}->{__parse_this_length} = $parse_this_length = |
987
|
|
|
|
|
|
|
$self->{length_routine}($parse_this_ref); |
988
|
|
|
|
|
|
|
} |
989
|
462
|
100
|
100
|
|
|
2321
|
if ($find_all && $parse_succeeded) { |
990
|
43
|
|
|
|
|
85
|
push @results_array, $to_return; |
991
|
43
|
100
|
|
|
|
94
|
if ($match_position == $initial_position) { |
992
|
3
|
|
|
|
|
4
|
$match_position++; |
993
|
|
|
|
|
|
|
} |
994
|
43
|
|
|
|
|
84
|
$initial_position = $parameters->{parse_hash}->{__initial_position} |
995
|
|
|
|
|
|
|
= $match_position; |
996
|
43
|
100
|
|
|
|
97
|
if ($match_position <= $parse_this_length) { |
997
|
42
|
|
|
|
|
53
|
$continue_to_parse = 1; |
998
|
42
|
|
|
|
|
122
|
$parameters->{continue_parse} = 0; |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
} |
1001
|
|
|
|
|
|
|
} |
1002
|
420
|
50
|
|
|
|
1120
|
if ($in_is_string) { |
1003
|
420
|
100
|
100
|
|
|
1458
|
if ($parameters->{global} && $parse_succeeded) { |
1004
|
13
|
|
|
|
|
35
|
pos $_[0] = $match_position; |
1005
|
|
|
|
|
|
|
} |
1006
|
|
|
|
|
|
|
else { |
1007
|
407
|
|
|
|
|
1242
|
pos $_[0] = undef; |
1008
|
|
|
|
|
|
|
} |
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
|
1011
|
420
|
100
|
|
|
|
1160
|
if ($find_all) { |
1012
|
8
|
|
|
|
|
82
|
return @results_array; |
1013
|
|
|
|
|
|
|
} |
1014
|
412
|
|
|
|
|
7362
|
return $to_return; |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
sub search { |
1018
|
12
|
|
|
12
|
0
|
2590
|
my $self = shift; |
1019
|
12
|
|
100
|
|
|
61
|
my $parameters = $_[1] || {}; |
1020
|
12
|
50
|
|
|
|
47
|
if (!defined $parameters->{match_start}) { |
1021
|
12
|
|
|
|
|
34
|
$parameters->{match_start} = 0; |
1022
|
|
|
|
|
|
|
} |
1023
|
12
|
100
|
|
|
|
41
|
if (!defined $parameters->{match_length}) { |
1024
|
10
|
|
|
|
|
21
|
$parameters->{match_length} = 0; |
1025
|
|
|
|
|
|
|
} |
1026
|
12
|
|
100
|
|
|
84
|
$parameters->{parse_info} = $parameters->{parse_info} || {}; |
1027
|
12
|
100
|
100
|
|
|
60
|
if ($parameters->{global} && wantarray) { |
1028
|
2
|
|
|
|
|
10
|
return $self->parse_and_evaluate($_[0], $parameters); |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
else { |
1031
|
10
|
|
|
|
|
37
|
$self->parse_and_evaluate($_[0], $parameters); |
1032
|
10
|
100
|
|
|
|
44
|
if ($parameters->{parse_info}->{parse_succeeded}) { |
1033
|
7
|
|
|
|
|
176
|
return 1; |
1034
|
|
|
|
|
|
|
} |
1035
|
|
|
|
|
|
|
else { |
1036
|
3
|
|
|
|
|
29
|
return ''; |
1037
|
|
|
|
|
|
|
} |
1038
|
|
|
|
|
|
|
} |
1039
|
|
|
|
|
|
|
} |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
sub search_and_substitute { |
1042
|
7
|
|
|
7
|
0
|
4884
|
my $self = shift; |
1043
|
7
|
|
100
|
|
|
44
|
my $parameters = $_[1] || {}; |
1044
|
7
|
|
|
|
|
20
|
$parameters->{substitute} = 1; |
1045
|
7
|
100
|
|
|
|
26
|
if ($parameters->{global}) { |
1046
|
2
|
|
|
|
|
10
|
my @substitutions = $self->search($_[0], $parameters); |
1047
|
2
|
|
|
|
|
12
|
return scalar(@substitutions); |
1048
|
|
|
|
|
|
|
} |
1049
|
|
|
|
|
|
|
else { |
1050
|
5
|
|
|
|
|
23
|
return $self->search($_[0], $parameters); |
1051
|
|
|
|
|
|
|
} |
1052
|
|
|
|
|
|
|
} |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
#package rules |
1055
|
|
|
|
|
|
|
sub ri_sub { |
1056
|
0
|
|
|
0
|
0
|
0
|
return ['RULE_INFO', @_]; |
1057
|
|
|
|
|
|
|
} |
1058
|
|
|
|
|
|
|
|
1059
|
0
|
|
|
0
|
0
|
0
|
sub R {ri_sub(@_)} |
1060
|
0
|
|
|
0
|
0
|
0
|
sub RULE_INFO {ri_sub(@_)} |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
sub eval_sub { |
1063
|
364
|
|
|
364
|
0
|
1705
|
return ['EVAL', @_]; |
1064
|
|
|
|
|
|
|
} |
1065
|
|
|
|
|
|
|
|
1066
|
342
|
|
|
342
|
0
|
79036
|
sub E {eval_sub(@_)} |
1067
|
22
|
|
|
22
|
1
|
101
|
sub EVALUATION {eval_sub(@_)} |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
sub string_eval_sub { |
1070
|
43
|
|
|
43
|
0
|
240
|
return ['SEVAL', @_]; |
1071
|
|
|
|
|
|
|
} |
1072
|
|
|
|
|
|
|
|
1073
|
43
|
|
|
43
|
0
|
159
|
sub SE {string_eval_sub(@_)} |
1074
|
0
|
|
|
0
|
1
|
0
|
sub STRING_EVALUATION {string_eval_sub(@_)} |
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
sub uneval_sub { |
1077
|
3
|
|
|
3
|
0
|
16
|
return ['UNEVAL', @_]; |
1078
|
|
|
|
|
|
|
} |
1079
|
|
|
|
|
|
|
|
1080
|
3
|
|
|
3
|
0
|
8
|
sub U {uneval_sub(@_)} |
1081
|
0
|
|
|
0
|
0
|
0
|
sub UNEVALUATION {uneval_sub(@_)} |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
sub parse_forward_sub { |
1084
|
57
|
|
|
57
|
0
|
302
|
return ['PARSE_FORWARD', @_]; |
1085
|
|
|
|
|
|
|
} |
1086
|
|
|
|
|
|
|
|
1087
|
53
|
|
|
53
|
0
|
4596
|
sub PF {parse_forward_sub(@_)} |
1088
|
4
|
|
|
4
|
1
|
14
|
sub PARSE_FORWARD {parse_forward_sub(@_)} |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
sub parse_backtrack_sub { |
1091
|
15
|
|
|
15
|
0
|
103
|
return ['PARSE_BACKTRACK', @_]; |
1092
|
|
|
|
|
|
|
} |
1093
|
|
|
|
|
|
|
|
1094
|
15
|
|
|
15
|
0
|
46
|
sub PB {parse_backtrack_sub(@_)} |
1095
|
0
|
|
|
0
|
0
|
0
|
sub PARSE_BACKTRACK {parse_backtrack_sub(@_)} |
1096
|
|
|
|
|
|
|
|
1097
|
7
|
|
|
7
|
0
|
34
|
sub USE_STRING_MATCH {return ['USE_STRING_MATCH']} |
1098
|
|
|
|
|
|
|
|
1099
|
18
|
|
|
18
|
1
|
4341
|
sub MATCH_ONCE {return ['MATCH_ONCE', @_]} |
1100
|
|
|
|
|
|
|
|
1101
|
13
|
|
|
13
|
1
|
6220
|
sub MATCH_MIN_FIRST {return ['MATCH_MIN_FIRST']} |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
sub and_sub { |
1104
|
492
|
|
|
492
|
0
|
3450
|
return ['AND', @_]; |
1105
|
|
|
|
|
|
|
} |
1106
|
|
|
|
|
|
|
|
1107
|
63
|
|
|
63
|
1
|
3108
|
sub AND {and_sub(@_)} |
1108
|
429
|
|
|
429
|
0
|
18049
|
sub A {and_sub(@_)} |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
sub or_sub { |
1111
|
117
|
|
|
117
|
0
|
890
|
return ['OR', @_]; |
1112
|
|
|
|
|
|
|
} |
1113
|
|
|
|
|
|
|
|
1114
|
24
|
|
|
24
|
1
|
89
|
sub OR {or_sub(@_)} |
1115
|
93
|
|
|
93
|
0
|
5144
|
sub O {or_sub(@_)} |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
sub LEAF_DISPLAY { |
1118
|
711
|
|
|
711
|
1
|
6156
|
return ['LEAF_DISPLAY', $_[0]]; |
1119
|
|
|
|
|
|
|
} |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
sub leaf { |
1122
|
768
|
|
|
768
|
0
|
904
|
my @p; |
1123
|
|
|
|
|
|
|
my @q; |
1124
|
768
|
|
|
|
|
1306
|
foreach my $parm (@_) { |
1125
|
902
|
100
|
|
|
|
1990
|
if (ref $parm eq 'ARRAY') { |
1126
|
187
|
|
|
|
|
441
|
push @q, $parm; |
1127
|
|
|
|
|
|
|
} |
1128
|
|
|
|
|
|
|
else { |
1129
|
715
|
|
|
|
|
1775
|
push @p, $parm; |
1130
|
|
|
|
|
|
|
} |
1131
|
|
|
|
|
|
|
} |
1132
|
768
|
100
|
|
|
|
2103
|
if (ref $p[0] eq 'Regexp') { |
1133
|
703
|
|
|
|
|
24696
|
return ['LEAF', qr/\G($p[0])/, LEAF_DISPLAY($p[0]), @q]; |
1134
|
|
|
|
|
|
|
} |
1135
|
|
|
|
|
|
|
else { |
1136
|
65
|
|
|
|
|
681
|
return ['LEAF', @p, @q]; |
1137
|
|
|
|
|
|
|
} |
1138
|
|
|
|
|
|
|
} |
1139
|
|
|
|
|
|
|
|
1140
|
506
|
|
|
506
|
1
|
1123
|
sub LEAF {leaf(@_)} |
1141
|
0
|
|
|
0
|
0
|
0
|
sub TOKEN {leaf(@_)} |
1142
|
0
|
|
|
0
|
0
|
0
|
sub TERMINAL {leaf(@_)} |
1143
|
262
|
|
|
262
|
0
|
3349
|
sub L {leaf(@_)} |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
sub multiple { |
1146
|
139
|
|
|
139
|
0
|
218
|
my @p; |
1147
|
|
|
|
|
|
|
my @q; |
1148
|
139
|
|
|
|
|
289
|
foreach my $parm (@_) { |
1149
|
264
|
100
|
100
|
|
|
3218
|
if ((ref $parm eq 'ARRAY') && |
|
|
|
66
|
|
|
|
|
1150
|
|
|
|
|
|
|
($parm->[0] eq 'EVAL' || $parm->[0] eq 'UNEVAL' || $parm->[0] eq 'SEVAL' |
1151
|
|
|
|
|
|
|
|| $parm->[0] eq 'RULE_INFO' || $parm->[0] eq 'MATCH_ONCE' |
1152
|
|
|
|
|
|
|
|| $parm->[0] eq 'MATCH_MIN_FIRST' |
1153
|
|
|
|
|
|
|
|| $parm->[0] eq 'USE_STRING_MATCH')) { |
1154
|
37
|
|
|
|
|
111
|
push @q, $parm; |
1155
|
|
|
|
|
|
|
} |
1156
|
|
|
|
|
|
|
else { |
1157
|
227
|
|
|
|
|
521
|
push @p, $parm; |
1158
|
|
|
|
|
|
|
} |
1159
|
|
|
|
|
|
|
} |
1160
|
139
|
100
|
|
|
|
584
|
if ($#p == 0) { |
|
|
50
|
|
|
|
|
|
1161
|
95
|
|
|
|
|
864
|
return ['MULTIPLE', 0, 0, $p[0], @q]; |
1162
|
|
|
|
|
|
|
} |
1163
|
|
|
|
|
|
|
elsif ($#p == 2) { |
1164
|
44
|
|
|
|
|
450
|
return ['MULTIPLE', $p[1], $p[2], $p[0], @q]; |
1165
|
|
|
|
|
|
|
} |
1166
|
0
|
|
|
|
|
0
|
croak "Malformed MULTIPLE; arguments: ".join(", ", @_); |
1167
|
|
|
|
|
|
|
} |
1168
|
|
|
|
|
|
|
|
1169
|
14
|
|
|
14
|
1
|
43
|
sub MULTIPLE {multiple(@_)} |
1170
|
125
|
|
|
125
|
0
|
9744
|
sub M {multiple(@_)} |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
sub optional { |
1173
|
57
|
|
|
57
|
0
|
405
|
return ['MULTIPLE', 0, 1, @_]; |
1174
|
|
|
|
|
|
|
} |
1175
|
1
|
|
|
1
|
0
|
3
|
sub OPTIONAL {optional(@_)} |
1176
|
0
|
|
|
0
|
0
|
0
|
sub ZERO_OR_ONE {optional(@_)} |
1177
|
56
|
|
|
56
|
0
|
657
|
sub Z {optional(@_)} |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
sub update_count { |
1180
|
2168
|
|
|
2168
|
0
|
2940
|
my $rule_type = shift; |
1181
|
2168
|
|
|
|
|
2466
|
my $rule_hash = shift; |
1182
|
2168
|
|
|
|
|
2549
|
my $subrule_alias = shift; |
1183
|
2168
|
|
50
|
|
|
6780
|
my $subrule_count = shift || 0; |
1184
|
2168
|
100
|
66
|
|
|
9358
|
if ($subrule_count > 1) { |
|
|
100
|
66
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
33
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1185
|
263
|
|
|
|
|
1175
|
$rule_hash->{rule_count}->{$subrule_alias} = 2; |
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
elsif ($rule_type eq 'AND') { |
1188
|
1201
|
|
|
|
|
4251
|
$rule_hash->{rule_count}->{$subrule_alias} += $subrule_count; |
1189
|
|
|
|
|
|
|
} |
1190
|
|
|
|
|
|
|
elsif ($rule_type eq 'MULTIPLE' && ($rule_hash->{maximum_child} != 1 || |
1191
|
|
|
|
|
|
|
$subrule_count > 1)) { |
1192
|
234
|
|
|
|
|
998
|
$rule_hash->{rule_count}->{$subrule_alias} = 2; |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
elsif ($rule_type eq 'MULTIPLE') { |
1195
|
81
|
|
50
|
|
|
595
|
$rule_hash->{rule_count}->{$subrule_alias} = |
1196
|
|
|
|
|
|
|
$rule_hash->{rule_count}->{$subrule_alias} || 1; |
1197
|
|
|
|
|
|
|
} |
1198
|
|
|
|
|
|
|
elsif ($rule_type eq 'OR' && |
1199
|
|
|
|
|
|
|
(!defined $rule_hash->{rule_count}->{$subrule_alias} || |
1200
|
|
|
|
|
|
|
($subrule_count > $rule_hash->{rule_count}->{$subrule_alias}))) { |
1201
|
341
|
|
|
|
|
1297
|
$rule_hash->{rule_count}->{$subrule_alias} = $subrule_count; |
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
} |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
sub incorporate_others { |
1206
|
7
|
|
|
7
|
0
|
16
|
my $self = shift; |
1207
|
7
|
|
|
|
|
18
|
my $incorporate_list = shift; |
1208
|
7
|
50
|
|
|
|
31
|
if (ref $incorporate_list ne 'ARRAY') { |
1209
|
0
|
|
|
|
|
0
|
croak "Must pass array to incorporate"; |
1210
|
|
|
|
|
|
|
} |
1211
|
7
|
|
|
|
|
20
|
foreach my $to_incorporate (@$incorporate_list) { |
1212
|
10
|
|
|
|
|
32
|
$self->copy_rules_from_grammar($to_incorporate); |
1213
|
|
|
|
|
|
|
} |
1214
|
|
|
|
|
|
|
} |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
sub copy_rules_from_grammar { |
1217
|
10
|
|
|
10
|
0
|
15
|
my $self = shift; |
1218
|
10
|
|
|
|
|
17
|
my $parameters = shift; |
1219
|
10
|
|
|
|
|
16
|
my $parser_to_incorporate = $parameters->{grammar_source}; |
1220
|
10
|
50
|
|
|
|
30
|
if (!defined $parser_to_incorporate) { |
1221
|
0
|
|
|
|
|
0
|
croak "Need to define grammar_source to incorporate"; |
1222
|
|
|
|
|
|
|
} |
1223
|
10
|
|
|
|
|
21
|
my $rules_to_copy = $parser_to_incorporate->{rule}; |
1224
|
10
|
|
|
|
|
15
|
my $prefix; |
1225
|
10
|
100
|
|
|
|
26
|
if (defined $parameters->{prefix}) { |
1226
|
4
|
|
|
|
|
11
|
$prefix = $parameters->{prefix}; |
1227
|
|
|
|
|
|
|
} |
1228
|
|
|
|
|
|
|
else { |
1229
|
6
|
|
|
|
|
12
|
$prefix = ''; |
1230
|
|
|
|
|
|
|
} |
1231
|
10
|
|
|
|
|
14
|
foreach my $rule_name (keys %{$rules_to_copy}) { |
|
10
|
|
|
|
|
39
|
|
1232
|
42
|
100
|
|
|
|
141
|
if (defined $self->{rule}->{$prefix.$rule_name}) { |
1233
|
1
|
|
|
|
|
364
|
croak ("Rule $prefix$rule_name in extraction already exists"); |
1234
|
|
|
|
|
|
|
} |
1235
|
41
|
|
|
|
|
74
|
my $rule_to_copy = $rules_to_copy->{$rule_name}; |
1236
|
41
|
|
|
|
|
45
|
my %copied_rule = %{$rule_to_copy}; |
|
41
|
|
|
|
|
536
|
|
1237
|
41
|
100
|
|
|
|
176
|
$copied_rule{sub_rule_name} = $prefix.$rule_to_copy->{sub_rule_name} |
1238
|
|
|
|
|
|
|
if defined $rule_to_copy->{sub_rule_name}; |
1239
|
41
|
100
|
|
|
|
119
|
if (defined $rule_to_copy->{rule_count}) { |
1240
|
26
|
|
|
|
|
33
|
$copied_rule{rule_count} = {%{$rule_to_copy->{rule_count}}}; |
|
26
|
|
|
|
|
112
|
|
1241
|
26
|
|
|
|
|
51
|
$copied_rule{subrule_list} = []; |
1242
|
26
|
|
|
|
|
65
|
for my $i (1..$copied_rule{subrule_list_count}) { |
1243
|
41
|
|
|
|
|
97
|
$copied_rule{subrule_list}[$i-1] = {}; |
1244
|
41
|
|
|
|
|
129
|
$copied_rule{subrule_list}->[$i-1]->{'alias'} = |
1245
|
|
|
|
|
|
|
$rule_to_copy->{subrule_list}->[$i-1]->{'alias'}; |
1246
|
41
|
|
|
|
|
1166
|
$copied_rule{subrule_list}->[$i-1]->{'name'} = $prefix. |
1247
|
|
|
|
|
|
|
$rule_to_copy->{subrule_list}->[$i-1]->{'name'}; |
1248
|
|
|
|
|
|
|
} |
1249
|
|
|
|
|
|
|
} |
1250
|
41
|
|
|
|
|
3669
|
$self->{rule}->{$prefix.$rule_name} = \%copied_rule; |
1251
|
|
|
|
|
|
|
} |
1252
|
9
|
|
|
|
|
33
|
$self->{multiple_rule_mins} += $parser_to_incorporate->{multiple_rule_mins}; |
1253
|
9
|
|
100
|
|
|
62
|
$self->{do_evaluation_in_parsing} = $self->{do_evaluation_in_parsing} || |
1254
|
|
|
|
|
|
|
$parser_to_incorporate->{do_evaluation_in_parsing}; |
1255
|
9
|
|
33
|
|
|
44
|
$self->{any_unevaluation} = $self->{any_unevaluation} || |
1256
|
|
|
|
|
|
|
$parser_to_incorporate->{any_unevaluation}; |
1257
|
9
|
|
33
|
|
|
47
|
$self->{any_minimize_children} = $self->{any_minimize_children} || |
1258
|
|
|
|
|
|
|
$parser_to_incorporate->{any_minimize_children}; |
1259
|
9
|
|
33
|
|
|
46
|
$self->{any_match_once} = $self->{any_match_once} || |
1260
|
|
|
|
|
|
|
$parser_to_incorporate->{any_match_once}; |
1261
|
9
|
|
33
|
|
|
89
|
$self->{any_parse_forward} = $self->{any_parse_forward} || |
1262
|
|
|
|
|
|
|
$parser_to_incorporate->{any_parse_forward}; |
1263
|
9
|
|
33
|
|
|
46
|
$self->{any_parse_backtrack} = $self->{any_parse_backtrack} || |
1264
|
|
|
|
|
|
|
$parser_to_incorporate->{any_parse_backtrack}; |
1265
|
9
|
|
33
|
|
|
39
|
$self->{any_maximum_child} = $self->{any_maximum_child} || |
1266
|
|
|
|
|
|
|
$parser_to_incorporate->{any_maximum_child}; |
1267
|
9
|
|
33
|
|
|
57
|
$self->{any_minimum_child} = $self->{any_minimum_child} || |
1268
|
|
|
|
|
|
|
$parser_to_incorporate->{any_minimum_child}; |
1269
|
9
|
|
66
|
|
|
56
|
$self->{fast_move_back} = $self->{fast_move_back} || |
1270
|
|
|
|
|
|
|
$parser_to_incorporate->{fast_move_back}; |
1271
|
9
|
|
33
|
|
|
74
|
$self->{no_evaluation} = $self->{no_evaluation} || |
1272
|
|
|
|
|
|
|
$parser_to_incorporate->{no_evaluation}; |
1273
|
|
|
|
|
|
|
} |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
sub add_rule { |
1276
|
1626
|
|
|
1626
|
0
|
2280
|
my $self = shift; |
1277
|
1626
|
|
|
|
|
1882
|
my $parameters = shift; |
1278
|
1626
|
|
33
|
|
|
3996
|
my $rule_name = $parameters->{rule_name} || croak ("Empty rule name"); |
1279
|
1626
|
|
|
|
|
2124
|
my $rule = $parameters->{rule_definition}; |
1280
|
1626
|
100
|
|
|
|
3912
|
if ($self->{rule}->{$rule_name}) { |
1281
|
1
|
|
|
|
|
281
|
croak ("Rule $rule_name already exists"); |
1282
|
|
|
|
|
|
|
} |
1283
|
1625
|
100
|
|
|
|
5252
|
if (ref $rule eq 'Regexp') { |
|
|
50
|
|
|
|
|
|
1284
|
58
|
|
|
|
|
166
|
$rule = LEAF($rule); |
1285
|
|
|
|
|
|
|
} |
1286
|
|
|
|
|
|
|
elsif (ref $rule eq '') { |
1287
|
0
|
|
|
|
|
0
|
$rule = AND($rule); |
1288
|
|
|
|
|
|
|
} |
1289
|
|
|
|
|
|
|
|
1290
|
1625
|
50
|
|
|
|
3680
|
if (ref $rule ne 'ARRAY') { |
1291
|
0
|
|
|
|
|
0
|
croak ("Bad format of rule $rule_name, cannot create."); |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
|
1294
|
1625
|
|
|
|
|
2846
|
my $separator = $self->{separator}; |
1295
|
1625
|
|
|
|
|
1915
|
my $base_rule = $rule_name; |
1296
|
1625
|
100
|
|
|
|
4336
|
if (defined $parameters->{generated_name}) { |
|
|
100
|
|
|
|
|
|
1297
|
848
|
|
|
|
|
3199
|
$self->{rule}->{$rule_name}->{generated} = 1; |
1298
|
848
|
|
|
|
|
2354
|
$self->{rule}->{$rule_name}->{base_rule} = |
1299
|
|
|
|
|
|
|
$base_rule = $parameters->{generated_name}; |
1300
|
|
|
|
|
|
|
} |
1301
|
|
|
|
|
|
|
elsif (index($rule_name, $separator) != -1) { |
1302
|
1
|
|
|
|
|
176
|
croak ("rule name $rule_name contains separator $separator"); |
1303
|
|
|
|
|
|
|
} |
1304
|
|
|
|
|
|
|
else { |
1305
|
776
|
|
|
|
|
2450
|
$self->{rule}->{$rule_name}->{base_rule} = $rule_name; |
1306
|
|
|
|
|
|
|
} |
1307
|
1624
|
|
|
|
|
2159
|
my $default_alias = ''; |
1308
|
1624
|
|
|
|
|
1764
|
my @copy_of_rule; #to prevent changing input |
1309
|
1624
|
|
|
|
|
3985
|
my $rule_type = $self->{rule}->{$rule_name}->{rule_type} = $rule->[0]; |
1310
|
1624
|
|
|
|
|
2696
|
foreach my $sub_rule (@$rule) { |
1311
|
5892
|
100
|
100
|
|
|
103801
|
if (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'EVAL') { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
50
|
66
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1312
|
381
|
|
|
|
|
552
|
my $what_to_eval = $sub_rule->[1]; |
1313
|
381
|
50
|
|
|
|
1220
|
if ($self->{rule}->{$rule_name}->{parsing_evaluation}) { |
1314
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has more than one evaluation routine"); |
1315
|
|
|
|
|
|
|
} |
1316
|
381
|
100
|
|
|
|
1113
|
if (ref $sub_rule->[1] eq 'CODE') { |
1317
|
374
|
|
|
|
|
1473
|
$self->{rule}->{$rule_name}->{parsing_evaluation} = $what_to_eval; |
1318
|
|
|
|
|
|
|
} |
1319
|
|
|
|
|
|
|
} |
1320
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'SEVAL') { |
1321
|
34
|
|
|
|
|
101
|
$self->{rule}->{$rule_name}->{string_evaluation} = $sub_rule->[1]; |
1322
|
34
|
|
|
|
|
118
|
$self->{rule}->{$rule_name}->{matched_string} = $sub_rule->[2]; |
1323
|
|
|
|
|
|
|
} |
1324
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'UNEVAL') { |
1325
|
3
|
50
|
|
|
|
13
|
if ($self->{rule}->{$rule_name}->{parsing_unevaluation}) { |
1326
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has more than one unevaluation routine"); |
1327
|
|
|
|
|
|
|
} |
1328
|
3
|
|
66
|
|
|
30
|
$self->{rule}->{$rule_name}->{parsing_unevaluation} = $sub_rule->[1] |
1329
|
|
|
|
|
|
|
|| $self->{rule}->{$rule_name}->{parsing_unevaluation}; |
1330
|
3
|
|
|
|
|
5
|
$self->{do_evaluation_in_parsing} = 1; |
1331
|
3
|
|
|
|
|
8
|
$self->{any_unevaluation} = 1; |
1332
|
|
|
|
|
|
|
} |
1333
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'MATCH_MIN_FIRST') { |
1334
|
13
|
50
|
|
|
|
39
|
if ($rule_type ne 'MULTIPLE') { |
1335
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name: Only multiple rules can have MATCH_MIN_FIRST"); |
1336
|
|
|
|
|
|
|
} |
1337
|
13
|
|
|
|
|
47
|
$self->{rule}->{$rule_name}->{minimize_children} = 1; |
1338
|
13
|
|
|
|
|
37
|
$self->{any_minimize_children} = 1; |
1339
|
|
|
|
|
|
|
} |
1340
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'MATCH_ONCE') { |
1341
|
18
|
|
|
|
|
59
|
$self->{rule}->{$rule_name}->{match_once} = 1; |
1342
|
18
|
|
|
|
|
115
|
$self->{any_match_once} = 1; |
1343
|
|
|
|
|
|
|
} |
1344
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'RULE_INFO') { |
1345
|
0
|
0
|
|
|
|
0
|
if ($self->{rule_info}->{$rule_name}) { |
1346
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has more than one rule_info"); |
1347
|
|
|
|
|
|
|
} |
1348
|
0
|
|
|
|
|
0
|
$self->{rule_info}->{$rule_name} = $sub_rule->[1]; |
1349
|
|
|
|
|
|
|
} |
1350
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'LEAF_DISPLAY') { |
1351
|
733
|
50
|
|
|
|
2202
|
if ($self->{rule}->{$rule_name}->{leaf_display}) { |
1352
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has more than one leaf_display"); |
1353
|
|
|
|
|
|
|
} |
1354
|
733
|
50
|
|
|
|
1513
|
if ($rule_type ne 'LEAF') { |
1355
|
0
|
|
|
|
|
0
|
croak ("Only leaf rules can have LEAF_DISPLAY in rule $rule_name"); |
1356
|
|
|
|
|
|
|
} |
1357
|
733
|
|
|
|
|
3494
|
$self->{rule}->{$rule_name}->{leaf_display} = $sub_rule->[1]; |
1358
|
|
|
|
|
|
|
} |
1359
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'USE_STRING_MATCH') { |
1360
|
8
|
|
|
|
|
34
|
$self->{rule}->{$rule_name}->{use_string_match} = 1; |
1361
|
|
|
|
|
|
|
} |
1362
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'PARSE_FORWARD') { |
1363
|
49
|
100
|
|
|
|
191
|
if ($self->{rule}->{$rule_name}->{parse_forward}) { |
1364
|
1
|
|
|
|
|
262
|
croak ("Rule $rule_name has more than one parse_forward"); |
1365
|
|
|
|
|
|
|
} |
1366
|
48
|
|
33
|
|
|
194
|
$self->{rule}->{$rule_name}->{parse_forward} = $sub_rule->[1] |
1367
|
|
|
|
|
|
|
|| croak ("Rule $rule_name Illegal parse_forward routine"); |
1368
|
48
|
|
|
|
|
136
|
$self->{any_parse_forward} = 1; |
1369
|
|
|
|
|
|
|
} |
1370
|
|
|
|
|
|
|
elsif (ref $sub_rule eq 'ARRAY' && $sub_rule->[0] eq 'PARSE_BACKTRACK') { |
1371
|
11
|
50
|
|
|
|
32
|
if ($rule_type eq 'LEAF') { |
1372
|
11
|
50
|
|
|
|
42
|
if ($self->{rule}->{$rule_name}->{parse_backtrack}) { |
1373
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has more than one parse_backtrack"); |
1374
|
|
|
|
|
|
|
} |
1375
|
11
|
|
33
|
|
|
44
|
$self->{rule}->{$rule_name}->{parse_backtrack} = $sub_rule->[1] |
1376
|
|
|
|
|
|
|
|| croak ("Rule $rule_name Illegal parse_backtrack routine"); |
1377
|
11
|
|
|
|
|
35
|
$self->{any_parse_backtrack} = 1; |
1378
|
|
|
|
|
|
|
} |
1379
|
|
|
|
|
|
|
else { |
1380
|
0
|
|
|
|
|
0
|
croak ("Parse backtrack in rule $rule_name of $rule_type (not leaf)"); |
1381
|
|
|
|
|
|
|
} |
1382
|
|
|
|
|
|
|
} |
1383
|
|
|
|
|
|
|
elsif (!defined $sub_rule) { |
1384
|
0
|
|
|
|
|
0
|
croak "undefined sub_rule in rule $rule_name"; |
1385
|
|
|
|
|
|
|
} |
1386
|
|
|
|
|
|
|
else { |
1387
|
4642
|
|
|
|
|
8715
|
push @copy_of_rule, $sub_rule; |
1388
|
|
|
|
|
|
|
} |
1389
|
|
|
|
|
|
|
} |
1390
|
1623
|
|
|
|
|
2521
|
shift @copy_of_rule; #Remove rule type |
1391
|
1623
|
|
|
|
|
3931
|
$self->{rule}->{$rule_name}->{leaf_rule} = 0; |
1392
|
1623
|
|
|
|
|
3038
|
$self->{rule}->{$rule_name}->{or_rule} = 0; |
1393
|
1623
|
|
|
|
|
2919
|
$self->{rule}->{$rule_name}->{and_rule} = 0; |
1394
|
1623
|
|
|
|
|
3530
|
$self->{rule}->{$rule_name}->{multiple_rule} = 0; |
1395
|
1623
|
100
|
|
|
|
3893
|
if ($rule_type eq 'LEAF') { |
1396
|
789
|
|
|
|
|
1091
|
my $leaf_info = shift @copy_of_rule; |
1397
|
789
|
100
|
|
|
|
1789
|
if (ref $leaf_info eq 'Regexp') { |
|
|
100
|
|
|
|
|
|
1398
|
732
|
|
|
|
|
1738
|
$self->{rule}->{$rule_name}->{regex_match} = $leaf_info; |
1399
|
732
|
100
|
|
|
|
3738
|
if ('' =~ $leaf_info) { |
1400
|
79
|
|
|
|
|
242
|
$self->{rule}->{$rule_name}->{zero} = 1; |
1401
|
|
|
|
|
|
|
} |
1402
|
|
|
|
|
|
|
} |
1403
|
|
|
|
|
|
|
elsif (defined $leaf_info) { |
1404
|
10
|
50
|
|
|
|
24
|
if (defined $self->{rule_info}->{$rule_name}) { |
1405
|
0
|
|
|
|
|
0
|
croak ("Duplicate info on $rule_name, leaf info is put into rule_info"); |
1406
|
|
|
|
|
|
|
} |
1407
|
10
|
|
|
|
|
18
|
$self->{rule_info}->{$rule_name} = $leaf_info; |
1408
|
|
|
|
|
|
|
} |
1409
|
789
|
|
100
|
|
|
5125
|
$self->{rule}->{$rule_name}->{parse_forward} = |
1410
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{parse_forward} || |
1411
|
|
|
|
|
|
|
$self->{leaf_parse_forward}; |
1412
|
789
|
|
100
|
|
|
3843
|
$self->{rule}->{$rule_name}->{parse_backtrack} = |
1413
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{parse_backtrack} || |
1414
|
|
|
|
|
|
|
$self->{leaf_parse_backtrack}; |
1415
|
789
|
|
|
|
|
1518
|
$self->{rule}->{$rule_name}->{use_parse_match} = 1; |
1416
|
789
|
|
|
|
|
2981
|
$self->{rule}->{$rule_name}->{leaf_rule} = 1; |
1417
|
|
|
|
|
|
|
} |
1418
|
|
|
|
|
|
|
else { |
1419
|
834
|
100
|
|
|
|
2289
|
if ($rule_type eq 'AND') { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1420
|
514
|
|
|
|
|
1037
|
$self->{rule}->{$rule_name}->{and_rule} = 1; |
1421
|
|
|
|
|
|
|
} |
1422
|
|
|
|
|
|
|
elsif ($rule_type eq 'OR') { |
1423
|
113
|
|
|
|
|
250
|
$self->{rule}->{$rule_name}->{or_rule} = 1; |
1424
|
|
|
|
|
|
|
} |
1425
|
|
|
|
|
|
|
elsif ($rule_type eq 'MULTIPLE') { |
1426
|
207
|
|
|
|
|
414
|
$self->{rule}->{$rule_name}->{multiple_rule} = 1; |
1427
|
207
|
|
|
|
|
642
|
my $min = |
1428
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{minimum_child} = shift @copy_of_rule; |
1429
|
207
|
|
|
|
|
555
|
my $max = |
1430
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{maximum_child} = shift @copy_of_rule; |
1431
|
207
|
50
|
66
|
|
|
2504
|
if (($max && ($min > $max)) || ($min < 0) || $min != int($min) |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
1432
|
|
|
|
|
|
|
|| $max != int($max)) { |
1433
|
0
|
|
|
|
|
0
|
croak("Illegal bound(s) $min and $max on $rule_name"); |
1434
|
|
|
|
|
|
|
} |
1435
|
207
|
100
|
|
|
|
685
|
if ($self->{rule}->{$rule_name}->{maximum_child}) { |
1436
|
70
|
|
|
|
|
121
|
$self->{any_maximum_child} = 1; |
1437
|
|
|
|
|
|
|
} |
1438
|
207
|
100
|
|
|
|
599
|
if ($self->{rule}->{$rule_name}->{minimum_child}) { |
1439
|
22
|
|
|
|
|
45
|
$self->{any_minimum_child} = 1; |
1440
|
|
|
|
|
|
|
} |
1441
|
207
|
|
|
|
|
392
|
$self->{multiple_rule_mins} += $min; |
1442
|
|
|
|
|
|
|
} |
1443
|
|
|
|
|
|
|
else { |
1444
|
0
|
|
|
|
|
0
|
croak "Bad rule type $rule_type on rule $rule_name"; |
1445
|
|
|
|
|
|
|
} |
1446
|
834
|
|
|
|
|
1342
|
foreach my $current_rule (@copy_of_rule) { |
1447
|
1861
|
|
|
|
|
2156
|
my ($alias, $name); |
1448
|
1861
|
100
|
|
|
|
4051
|
if (ref $current_rule eq 'HASH') { |
1449
|
121
|
|
|
|
|
189
|
my @hash_info = keys (%{$current_rule}); |
|
121
|
|
|
|
|
465
|
|
1450
|
121
|
50
|
|
|
|
381
|
if ($#hash_info != 0) { |
1451
|
0
|
|
|
|
|
0
|
croak ("Too many keys in rule $rule_name"); |
1452
|
|
|
|
|
|
|
} |
1453
|
121
|
|
|
|
|
186
|
$alias = $hash_info[0]; |
1454
|
121
|
|
|
|
|
263
|
$current_rule = $current_rule->{$alias}; |
1455
|
|
|
|
|
|
|
} |
1456
|
1861
|
100
|
|
|
|
4758
|
if (ref $current_rule eq '') { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1457
|
1013
|
100
|
|
|
|
1938
|
if (!defined $alias) { |
1458
|
977
|
|
|
|
|
1308
|
$alias = $current_rule; |
1459
|
|
|
|
|
|
|
} |
1460
|
1013
|
|
|
|
|
1224
|
$name = $current_rule; |
1461
|
|
|
|
|
|
|
} |
1462
|
|
|
|
|
|
|
elsif (ref $current_rule eq 'Regexp') { |
1463
|
399
|
100
|
|
|
|
833
|
if (!defined $alias) { |
1464
|
339
|
|
|
|
|
550
|
$alias = $default_alias; |
1465
|
|
|
|
|
|
|
} |
1466
|
399
|
|
|
|
|
1289
|
$name = $base_rule.$separator. |
1467
|
|
|
|
|
|
|
++$self->{unique_name_counter}->{$base_rule}; |
1468
|
399
|
|
|
|
|
925
|
$self->add_rule({ |
1469
|
|
|
|
|
|
|
rule_name => $name, rule_definition => LEAF($current_rule), |
1470
|
|
|
|
|
|
|
generated_name => $base_rule}); |
1471
|
|
|
|
|
|
|
} |
1472
|
|
|
|
|
|
|
elsif (ref $current_rule eq 'ARRAY') { |
1473
|
449
|
|
|
|
|
1476
|
$name = $base_rule.$separator. |
1474
|
|
|
|
|
|
|
++$self->{unique_name_counter}->{$base_rule}; |
1475
|
449
|
|
|
|
|
3111
|
$self->add_rule({ |
1476
|
|
|
|
|
|
|
rule_name => $name, rule_definition => $current_rule, |
1477
|
|
|
|
|
|
|
generated_name => $base_rule}); |
1478
|
449
|
100
|
|
|
|
1481
|
if (!defined $alias) { |
1479
|
424
|
100
|
100
|
|
|
2610
|
if (defined $self->{rule}->{$name}->{parsing_evaluation} || |
1480
|
|
|
|
|
|
|
$self->{rule}->{$name}->{rule_type} eq 'LEAF') { |
1481
|
81
|
|
|
|
|
146
|
$alias = $default_alias; |
1482
|
|
|
|
|
|
|
} |
1483
|
|
|
|
|
|
|
} |
1484
|
|
|
|
|
|
|
} |
1485
|
1861
|
|
|
|
|
3173
|
push @{$self->{rule}->{$rule_name}->{subrule_list}}, |
|
1861
|
|
|
|
|
19704
|
|
1486
|
|
|
|
|
|
|
{alias => $alias, name => $name}; |
1487
|
|
|
|
|
|
|
} |
1488
|
834
|
|
|
|
|
2655
|
$self->{rule}->{$rule_name}->{subrule_list_count} = |
1489
|
834
|
|
|
|
|
1239
|
scalar(@{$self->{rule}->{$rule_name}->{subrule_list}}); |
1490
|
834
|
|
|
|
|
1145
|
foreach my $subrule (@{$self->{rule}->{$rule_name}->{subrule_list}}) { |
|
834
|
|
|
|
|
2009
|
|
1491
|
1861
|
100
|
|
|
|
3511
|
if (defined $subrule->{alias}) { |
1492
|
1518
|
|
|
|
|
4403
|
update_count($rule_type, |
1493
|
|
|
|
|
|
|
$self->{rule}->{$rule_name},$subrule->{alias}, 1); |
1494
|
|
|
|
|
|
|
} |
1495
|
|
|
|
|
|
|
else { |
1496
|
343
|
|
|
|
|
412
|
foreach my $sub_alias (keys |
|
343
|
|
|
|
|
1358
|
|
1497
|
|
|
|
|
|
|
%{$self->{rule}->{$subrule->{name}}->{rule_count}}) { |
1498
|
650
|
|
|
|
|
2268
|
update_count($rule_type, |
1499
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}, $sub_alias, |
1500
|
|
|
|
|
|
|
$self->{rule}->{$subrule->{name}}->{rule_count}->{$sub_alias}); |
1501
|
|
|
|
|
|
|
} |
1502
|
|
|
|
|
|
|
} |
1503
|
|
|
|
|
|
|
} |
1504
|
834
|
100
|
|
|
|
2892
|
if (defined $self->{rule}->{$rule_name}->{string_evaluation}) { |
1505
|
28
|
50
|
|
|
|
88
|
if ($self->{rule}->{$rule_name}->{parsing_evaluation}) { |
1506
|
0
|
|
|
|
|
0
|
croak ("Rule $rule_name has multiple evaluation routines"); |
1507
|
|
|
|
|
|
|
} |
1508
|
28
|
|
|
|
|
68
|
my $params = which_parameters_are_arrays($self, $rule_name); |
1509
|
28
|
|
|
|
|
106
|
my @params = keys %$params; |
1510
|
28
|
|
|
|
|
49
|
my $sub = "sub {\n"; |
1511
|
28
|
100
|
|
|
|
81
|
if ($self->{rule}->{$rule_name}->{use_string_match}) { |
1512
|
2
|
|
|
|
|
5
|
$sub .= "\$_ = \$_[0];\n"; |
1513
|
|
|
|
|
|
|
} |
1514
|
|
|
|
|
|
|
else { |
1515
|
26
|
|
|
|
|
42
|
foreach my $param (@params) { |
1516
|
52
|
100
|
66
|
|
|
371
|
if ($param =~ /\w+/ && ($param ne '_')) { |
|
|
50
|
|
|
|
|
|
1517
|
43
|
|
|
|
|
119
|
$sub .= "my \$$param = \$_[0]->{$param};\n"; |
1518
|
|
|
|
|
|
|
} |
1519
|
|
|
|
|
|
|
elsif ($param eq '') { |
1520
|
9
|
|
|
|
|
30
|
$sub .= "\$_ = \$_[0]->{''};\n"; |
1521
|
|
|
|
|
|
|
} |
1522
|
|
|
|
|
|
|
else { |
1523
|
0
|
|
|
|
|
0
|
croak "String Evaluation of rule $rule_name cannot handle ". |
1524
|
|
|
|
|
|
|
"parameter with name $param"; |
1525
|
|
|
|
|
|
|
} |
1526
|
|
|
|
|
|
|
} |
1527
|
26
|
50
|
|
|
|
104
|
if (my $ms = $self->{rule}->{$rule_name}->{matched_string}) { |
1528
|
26
|
|
|
|
|
59
|
$sub .= "my \$".$ms." = MATCHED_STRING(\$_[1]);\n"; |
1529
|
|
|
|
|
|
|
} |
1530
|
|
|
|
|
|
|
} |
1531
|
28
|
|
|
|
|
77
|
$sub .= $self->{rule}->{$rule_name}->{string_evaluation}."}"; |
1532
|
28
|
|
|
|
|
4923
|
$self->{rule}->{$rule_name}->{parsing_evaluation} = eval $sub; |
1533
|
28
|
50
|
|
|
|
144
|
if ($@) {croak "Rule $rule_name error on subroutine evaluation $@"}; |
|
0
|
|
|
|
|
0
|
|
1534
|
|
|
|
|
|
|
} |
1535
|
834
|
|
|
|
|
2617
|
$self->{rule}->{$rule_name}->{sub_rule_name} = |
1536
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{subrule_list}->[0]->{name}; |
1537
|
834
|
|
|
|
|
4648
|
$self->{rule}->{$rule_name}->{sub_alias} = |
1538
|
|
|
|
|
|
|
$self->{rule}->{$rule_name}->{subrule_list}->[0]->{alias}; |
1539
|
|
|
|
|
|
|
} |
1540
|
|
|
|
|
|
|
} |
1541
|
|
|
|
|
|
|
|
1542
|
|
|
|
|
|
|
sub make_sure_all_rules_reachable { |
1543
|
152
|
|
|
152
|
0
|
259
|
my $self = shift; |
1544
|
152
|
|
|
|
|
215
|
my $parameters = shift; |
1545
|
152
|
|
|
|
|
298
|
my $start_rule = $parameters->{start_rule}; |
1546
|
152
|
|
|
|
|
389
|
my @rules_to_check = ($start_rule); |
1547
|
152
|
|
|
|
|
225
|
my %rules_checked; |
1548
|
152
|
|
|
|
|
311
|
$rules_checked{$start_rule} = 1; |
1549
|
152
|
|
|
|
|
545
|
while (my $rule_to_check = shift @rules_to_check) { |
1550
|
1621
|
100
|
|
|
|
4612
|
if ($self->{rule}->{$rule_to_check}->{subrule_list}) { |
1551
|
1407
|
|
|
|
|
2460
|
foreach my $rule_name_alias |
|
1407
|
|
|
|
|
4291
|
|
1552
|
|
|
|
|
|
|
(@{$self->{rule}->{$rule_to_check}->{subrule_list}}) { |
1553
|
1853
|
|
|
|
|
2590
|
my $rule_name = $rule_name_alias->{name}; |
1554
|
1853
|
100
|
|
|
|
5752
|
if (!($rules_checked{$rule_name}++)) { |
1555
|
1469
|
|
|
|
|
4186
|
push @rules_to_check, $rule_name; |
1556
|
|
|
|
|
|
|
} |
1557
|
|
|
|
|
|
|
} |
1558
|
|
|
|
|
|
|
} |
1559
|
|
|
|
|
|
|
} |
1560
|
152
|
|
|
|
|
469
|
my @unreachable; |
1561
|
152
|
|
|
|
|
357
|
foreach my $rule (keys %{$self->{rule}}) { |
|
152
|
|
|
|
|
705
|
|
1562
|
1642
|
100
|
|
|
|
3765
|
if (!$rules_checked{$rule}) { |
1563
|
21
|
|
|
|
|
67
|
push @unreachable, "No path to rule $rule start rule $start_rule"; |
1564
|
|
|
|
|
|
|
} |
1565
|
|
|
|
|
|
|
} |
1566
|
152
|
|
|
|
|
909
|
return @unreachable; |
1567
|
|
|
|
|
|
|
} |
1568
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
sub make_sure_all_names_covered { |
1570
|
153
|
|
|
153
|
0
|
375
|
my $self = shift; |
1571
|
153
|
|
|
|
|
251
|
my $parameters = shift; |
1572
|
153
|
|
|
|
|
290
|
my $return_list = $parameters->{return_list}; |
1573
|
153
|
|
|
|
|
334
|
my @list; |
1574
|
153
|
|
|
|
|
266
|
foreach my $rule (keys %{$self->{rule}}) { |
|
153
|
|
|
|
|
685
|
|
1575
|
1643
|
100
|
|
|
|
4284
|
if ($self->{rule}->{$rule}->{subrule_list}) { |
1576
|
1428
|
|
|
|
|
1493
|
foreach my $rule_name_alias (@{$self->{rule}->{$rule}->{subrule_list}}) { |
|
1428
|
|
|
|
|
3215
|
|
1577
|
1876
|
|
|
|
|
2633
|
my $rule_name = $rule_name_alias->{name}; |
1578
|
1876
|
100
|
|
|
|
5957
|
if (!$self->{rule}->{$rule_name}) { |
1579
|
1
|
50
|
|
|
|
4
|
if ($return_list) { |
1580
|
1
|
|
|
|
|
7
|
push @list, "Rule $rule missing subrule: $rule_name"; |
1581
|
|
|
|
|
|
|
} |
1582
|
|
|
|
|
|
|
else { |
1583
|
0
|
|
|
|
|
0
|
croak ("Rule $rule has undefined subrule of $rule_name"); |
1584
|
|
|
|
|
|
|
} |
1585
|
|
|
|
|
|
|
} |
1586
|
|
|
|
|
|
|
} |
1587
|
|
|
|
|
|
|
} |
1588
|
|
|
|
|
|
|
} |
1589
|
153
|
|
|
|
|
613
|
return @list; |
1590
|
|
|
|
|
|
|
} |
1591
|
|
|
|
|
|
|
|
1592
|
|
|
|
|
|
|
sub which_parameters_are_arrays { |
1593
|
32
|
|
|
32
|
0
|
9642
|
my $self = shift; |
1594
|
32
|
|
|
|
|
52
|
my $rule_name = shift; |
1595
|
32
|
|
|
|
|
68
|
my $rules_details = $self->{rule}; |
1596
|
32
|
|
|
|
|
44
|
my %to_return; |
1597
|
32
|
|
|
|
|
121
|
foreach my $child_rule_name (sort keys |
|
32
|
|
|
|
|
229
|
|
1598
|
|
|
|
|
|
|
%{$rules_details->{$rule_name}->{rule_count}}) { |
1599
|
60
|
100
|
|
|
|
169
|
if ($rules_details->{$rule_name}->{rule_count}->{$child_rule_name} > 1) { |
1600
|
7
|
|
|
|
|
322
|
$to_return{$child_rule_name} = 1; |
1601
|
|
|
|
|
|
|
} |
1602
|
|
|
|
|
|
|
else { |
1603
|
53
|
|
|
|
|
125
|
$to_return{$child_rule_name} = 0; |
1604
|
|
|
|
|
|
|
} |
1605
|
|
|
|
|
|
|
} |
1606
|
32
|
|
|
|
|
107
|
return \%to_return; |
1607
|
|
|
|
|
|
|
} |
1608
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
sub set_up_full_rule_set { |
1610
|
158
|
|
|
158
|
0
|
268
|
my $self = shift; |
1611
|
158
|
|
|
|
|
319
|
my $rules_to_set_up_hash = shift; |
1612
|
158
|
|
|
|
|
239
|
my $parameters = shift; |
1613
|
158
|
|
|
|
|
372
|
my $start_rule = $parameters->{start_rule}; |
1614
|
|
|
|
|
|
|
|
1615
|
158
|
100
|
|
|
|
8961
|
if (scalar keys %$rules_to_set_up_hash) { |
1616
|
157
|
|
|
|
|
1132
|
foreach my $hash_rule_name (sort keys %$rules_to_set_up_hash) { |
1617
|
778
|
|
|
|
|
3628
|
$self->add_rule({rule_name => $hash_rule_name, |
1618
|
|
|
|
|
|
|
rule_definition => $rules_to_set_up_hash->{$hash_rule_name}}); |
1619
|
|
|
|
|
|
|
} |
1620
|
|
|
|
|
|
|
} |
1621
|
|
|
|
|
|
|
|
1622
|
155
|
100
|
|
|
|
578
|
if (!defined $start_rule) { |
1623
|
98
|
|
|
|
|
263
|
my %covered_rule; |
1624
|
98
|
|
|
|
|
177
|
foreach my $rule_name (keys %{$self->{rule}}) { |
|
98
|
|
|
|
|
1092
|
|
1625
|
1192
|
|
|
|
|
1349
|
foreach my $subrule |
|
1192
|
|
|
|
|
3444
|
|
1626
|
|
|
|
|
|
|
(@{$self->{rule}->{$rule_name}->{subrule_list}}) { |
1627
|
1367
|
100
|
|
|
|
3702
|
if ($subrule->{name} ne $self->{rule}->{$rule_name}->{base_rule}) { |
1628
|
1355
|
|
|
|
|
4556
|
$covered_rule{$subrule->{name}}++; |
1629
|
|
|
|
|
|
|
} |
1630
|
|
|
|
|
|
|
} |
1631
|
|
|
|
|
|
|
} |
1632
|
98
|
|
|
|
|
273
|
START: foreach my $rule_name (keys %{$self->{rule}}) { |
|
98
|
|
|
|
|
720
|
|
1633
|
672
|
100
|
|
|
|
1353
|
if (!$covered_rule{$rule_name}) { |
1634
|
96
|
|
|
|
|
154
|
$start_rule = $rule_name; |
1635
|
96
|
|
|
|
|
340
|
last START; |
1636
|
|
|
|
|
|
|
} |
1637
|
|
|
|
|
|
|
} |
1638
|
98
|
100
|
|
|
|
517
|
if (!defined $start_rule) {croak "No valid start rule"}; |
|
2
|
|
|
|
|
401
|
|
1639
|
|
|
|
|
|
|
} |
1640
|
|
|
|
|
|
|
|
1641
|
153
|
|
|
|
|
986
|
my @missing_rules = $self->make_sure_all_names_covered({return_list=>1}); |
1642
|
153
|
100
|
|
|
|
619
|
if ($#missing_rules > -1) { |
1643
|
1
|
|
|
|
|
232
|
croak "Missing rules: ".join("\n",@missing_rules)."\n"; |
1644
|
|
|
|
|
|
|
} |
1645
|
|
|
|
|
|
|
|
1646
|
152
|
50
|
|
|
|
540
|
if (!$self->{unreachable_rules_allowed}) { |
1647
|
152
|
|
|
|
|
777
|
my @unreachable_rules = $self->make_sure_all_rules_reachable({ |
1648
|
|
|
|
|
|
|
start_rule=>$start_rule}); |
1649
|
152
|
100
|
|
|
|
667
|
if ($#unreachable_rules > -1) { |
1650
|
2
|
|
|
|
|
498
|
croak "Unreachable rules: ".join("\n",@unreachable_rules)."\n"; |
1651
|
|
|
|
|
|
|
} |
1652
|
|
|
|
|
|
|
} |
1653
|
|
|
|
|
|
|
|
1654
|
150
|
|
|
|
|
803
|
$self->look_for_left_recursion; |
1655
|
147
|
|
|
|
|
697
|
$self->{start_rule} = $start_rule; |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
} |
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
sub look_for_left_recursion { |
1660
|
150
|
|
|
150
|
0
|
263
|
my $self = shift; |
1661
|
150
|
|
|
|
|
305
|
my %checked_rules; |
1662
|
150
|
|
|
|
|
246
|
foreach my $rule (keys %{$self->{rule}}) { |
|
150
|
|
|
|
|
616
|
|
1663
|
1616
|
50
|
|
|
|
3301
|
if ($checked_rules{$rule}) {next}; |
|
0
|
|
|
|
|
0
|
|
1664
|
1616
|
|
|
|
|
2421
|
my $current_rule = $rule; |
1665
|
1616
|
|
|
|
|
1872
|
my $moving_down = 1; |
1666
|
1616
|
|
|
|
|
1650
|
my %active_rules; |
1667
|
|
|
|
|
|
|
my @active_rules; |
1668
|
1616
|
|
|
|
|
1865
|
my $previous_allows_zero = 0; |
1669
|
1616
|
|
|
|
|
8817
|
while (defined $current_rule) { |
1670
|
10998
|
100
|
|
|
|
18254
|
if ($moving_down) { |
1671
|
4970
|
100
|
|
|
|
11703
|
if ($active_rules{$current_rule}++) { |
1672
|
3
|
|
|
|
|
546
|
croak "Left recursion in grammar: ". |
1673
|
|
|
|
|
|
|
join(" leads to ", @active_rules, $current_rule); |
1674
|
|
|
|
|
|
|
} |
1675
|
4967
|
|
|
|
|
7052
|
push @active_rules, $current_rule; |
1676
|
4967
|
100
|
66
|
|
|
24653
|
if ($checked_rules{$current_rule} |
1677
|
|
|
|
|
|
|
|| $self->{rule}->{$current_rule}->{leaf_rule}) { |
1678
|
2678
|
|
|
|
|
5742
|
$moving_down = 0; |
1679
|
|
|
|
|
|
|
} |
1680
|
|
|
|
|
|
|
else { |
1681
|
2289
|
|
|
|
|
3033
|
$active_rules{$current_rule} = 1; |
1682
|
2289
|
100
|
|
|
|
5616
|
if ($self->{rule}->{$current_rule}->{multiple_rule}) { |
1683
|
318
|
|
|
|
|
1026
|
$current_rule = $self->{rule}->{$current_rule}->{sub_rule_name}; |
1684
|
|
|
|
|
|
|
} |
1685
|
|
|
|
|
|
|
else { |
1686
|
1971
|
|
|
|
|
7069
|
$current_rule = |
1687
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list}->[0]->{name}; |
1688
|
|
|
|
|
|
|
} |
1689
|
|
|
|
|
|
|
} |
1690
|
|
|
|
|
|
|
} |
1691
|
|
|
|
|
|
|
else { |
1692
|
6028
|
100
|
|
|
|
10951
|
if ($previous_allows_zero) { |
1693
|
107
|
100
|
100
|
|
|
893
|
if ($self->{rule}->{$current_rule}->{multiple_rule} || |
|
|
100
|
100
|
|
|
|
|
1694
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{or_rule}) { |
1695
|
46
|
|
|
|
|
114
|
$self->{rule}->{$current_rule}->{zero} = 1; |
1696
|
|
|
|
|
|
|
} |
1697
|
|
|
|
|
|
|
elsif ($self->{rule}->{$current_rule}->{and_rule} && |
1698
|
|
|
|
|
|
|
($active_rules{$current_rule} == |
1699
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list_count})) { |
1700
|
10
|
|
|
|
|
31
|
$self->{rule}->{$current_rule}->{zero} = 1; |
1701
|
|
|
|
|
|
|
} |
1702
|
|
|
|
|
|
|
else { |
1703
|
51
|
|
|
|
|
78
|
$previous_allows_zero = 0; |
1704
|
|
|
|
|
|
|
} |
1705
|
|
|
|
|
|
|
} |
1706
|
6028
|
100
|
100
|
|
|
49707
|
if ($self->{rule}->{$current_rule}->{multiple_rule} || |
|
|
100
|
66
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1707
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{leaf_rule} || |
1708
|
|
|
|
|
|
|
$checked_rules{$current_rule}) { |
1709
|
2996
|
|
|
|
|
4601
|
delete $active_rules{$current_rule}; |
1710
|
2996
|
|
100
|
|
|
11515
|
$previous_allows_zero = $self->{rule}->{$current_rule}->{zero} || 0; |
1711
|
2996
|
|
|
|
|
3487
|
pop @active_rules; |
1712
|
2996
|
|
|
|
|
9319
|
$current_rule = $active_rules[-1]; |
1713
|
|
|
|
|
|
|
} |
1714
|
|
|
|
|
|
|
elsif ($active_rules{$current_rule} == |
1715
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list_count}) { |
1716
|
584
|
|
100
|
|
|
2318
|
$previous_allows_zero = $self->{rule}->{$current_rule}->{zero} || 0; |
1717
|
584
|
|
|
|
|
1915
|
delete $active_rules{$current_rule}; |
1718
|
584
|
|
|
|
|
679
|
pop @active_rules; |
1719
|
584
|
|
|
|
|
1673
|
$current_rule = $active_rules[-1]; |
1720
|
|
|
|
|
|
|
} |
1721
|
|
|
|
|
|
|
elsif ($self->{rule}->{$current_rule}->{and_rule}) { |
1722
|
1473
|
|
|
|
|
3969
|
my $previous_rule = |
1723
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list}-> |
1724
|
|
|
|
|
|
|
[$active_rules{$current_rule}-1]->{name}; |
1725
|
1473
|
100
|
66
|
|
|
10186
|
if ((defined $self->{rule}->{$previous_rule}->{zero} && |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1726
|
|
|
|
|
|
|
$self->{rule}->{$previous_rule}->{zero}) || |
1727
|
|
|
|
|
|
|
($self->{rule}->{$previous_rule}->{multiple_rule} && |
1728
|
|
|
|
|
|
|
$self->{rule}->{$previous_rule}->{minimum_child} == 0)) { |
1729
|
90
|
|
|
|
|
259
|
$current_rule = |
1730
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list}-> |
1731
|
|
|
|
|
|
|
[$active_rules{$current_rule}++]->{name}; |
1732
|
90
|
|
|
|
|
236
|
$moving_down = 1; |
1733
|
|
|
|
|
|
|
} |
1734
|
|
|
|
|
|
|
else { |
1735
|
1383
|
|
50
|
|
|
5735
|
$previous_allows_zero = $self->{rule}->{$current_rule}->{zero} || 0; |
1736
|
1383
|
|
|
|
|
2061
|
delete $active_rules{$current_rule}; |
1737
|
1383
|
|
|
|
|
2157
|
pop @active_rules; |
1738
|
1383
|
|
|
|
|
4290
|
$current_rule = $active_rules[-1]; |
1739
|
|
|
|
|
|
|
} |
1740
|
|
|
|
|
|
|
} |
1741
|
|
|
|
|
|
|
else { |
1742
|
975
|
|
|
|
|
2862
|
$current_rule = |
1743
|
|
|
|
|
|
|
$self->{rule}->{$current_rule}->{subrule_list}-> |
1744
|
|
|
|
|
|
|
[$active_rules{$current_rule}++]->{name}; |
1745
|
975
|
|
|
|
|
2185
|
$moving_down = 1; |
1746
|
|
|
|
|
|
|
} |
1747
|
|
|
|
|
|
|
} |
1748
|
|
|
|
|
|
|
} |
1749
|
|
|
|
|
|
|
} |
1750
|
|
|
|
|
|
|
} |
1751
|
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
sub new_unevaluate_tree_node { |
1753
|
461
|
|
|
461
|
0
|
531
|
my $self = shift; |
1754
|
461
|
|
|
|
|
520
|
my $parameters = shift; |
1755
|
461
|
|
|
|
|
677
|
my $node = $parameters->{node}; |
1756
|
461
|
|
|
|
|
597
|
my $rules_details = $self->{rule}; |
1757
|
461
|
|
|
|
|
561
|
my $rule_name = $node->{name}; |
1758
|
461
|
|
|
|
|
701
|
my $rule = $rules_details->{$rule_name}; |
1759
|
461
|
|
|
|
|
618
|
my $subroutine_to_run = $rule->{parsing_unevaluation}; |
1760
|
461
|
|
|
|
|
708
|
my $params_to_eval = $node->{__parameters}; |
1761
|
|
|
|
|
|
|
|
1762
|
461
|
100
|
|
|
|
1089
|
if ($rule->{use_parse_match}) { |
1763
|
187
|
|
|
|
|
325
|
$params_to_eval = $node->{parse_match}; |
1764
|
|
|
|
|
|
|
} |
1765
|
|
|
|
|
|
|
|
1766
|
461
|
100
|
|
|
|
868
|
if (defined $subroutine_to_run) { |
1767
|
3
|
|
|
|
|
4
|
my $parse_hash = $parameters->{parse_hash}; |
1768
|
3
|
|
|
|
|
6
|
delete $parse_hash->{current_position}; |
1769
|
3
|
|
|
|
|
7
|
delete $parse_hash->{rule_name}; |
1770
|
3
|
|
|
|
|
6
|
$parse_hash->{current_node} = $node; |
1771
|
3
|
|
|
|
|
8
|
&$subroutine_to_run($params_to_eval, $parse_hash); |
1772
|
3
|
|
|
|
|
11
|
delete $parse_hash->{current_node}; |
1773
|
|
|
|
|
|
|
} |
1774
|
|
|
|
|
|
|
|
1775
|
461
|
|
|
|
|
449
|
my $parent; |
1776
|
461
|
50
|
|
|
|
1131
|
if ($parent = $node->{parent}) { |
1777
|
|
|
|
|
|
|
|
1778
|
461
|
|
|
|
|
506
|
foreach my $param (keys %{$node->{passed_params}}) { |
|
461
|
|
|
|
|
1436
|
|
1779
|
484
|
100
|
|
|
|
1106
|
if (my $count = $node->{passed_params}->{$param}) { |
1780
|
246
|
50
|
|
|
|
310
|
if ($count > scalar(@{$parent->{__parameters}->{$param}})) { |
|
246
|
|
|
|
|
733
|
|
1781
|
0
|
|
|
|
|
0
|
croak("Unevaluation parameter miscount; rule $rule_name p: $param"); |
1782
|
|
|
|
|
|
|
} |
1783
|
246
|
|
|
|
|
324
|
splice(@{$parent->{__parameters}->{$param}}, - $count); |
|
246
|
|
|
|
|
865
|
|
1784
|
|
|
|
|
|
|
} |
1785
|
|
|
|
|
|
|
else { |
1786
|
238
|
|
|
|
|
784
|
delete $parent->{__parameters}->{$param}; |
1787
|
|
|
|
|
|
|
} |
1788
|
|
|
|
|
|
|
} |
1789
|
461
|
|
|
|
|
1682
|
delete $node->{passed_params}; |
1790
|
|
|
|
|
|
|
} |
1791
|
|
|
|
|
|
|
} |
1792
|
|
|
|
|
|
|
|
1793
|
|
|
|
|
|
|
sub MATCHED_STRING { |
1794
|
64
|
|
|
64
|
1
|
157
|
my $parse_hash = shift; |
1795
|
64
|
|
|
|
|
91
|
my $node = $parse_hash->{current_node}; |
1796
|
64
|
|
|
|
|
65
|
return substr(${$parse_hash->{parse_this_ref}}, |
|
64
|
|
|
|
|
1575
|
|
1797
|
|
|
|
|
|
|
$node->{position_when_entered}, |
1798
|
|
|
|
|
|
|
$node->{position_when_completed} - $node->{position_when_entered}); |
1799
|
|
|
|
|
|
|
} |
1800
|
|
|
|
|
|
|
|
1801
|
|
|
|
|
|
|
sub new_evaluate_tree_node { |
1802
|
1531
|
|
|
1531
|
0
|
2191
|
my $self = shift; |
1803
|
1531
|
|
|
|
|
1964
|
my $parameters = shift; |
1804
|
1531
|
|
|
|
|
2415
|
my $nodes = $parameters->{nodes}; |
1805
|
1531
|
|
|
|
|
2605
|
my $rules_details = $self->{rule}; |
1806
|
1531
|
|
|
|
|
1728
|
my @results; |
1807
|
|
|
|
|
|
|
|
1808
|
1531
|
|
|
|
|
2072
|
my $parse_hash = $parameters->{parse_hash}; |
1809
|
1531
|
|
|
|
|
13219
|
foreach my $node (@$nodes) { |
1810
|
8157
|
|
|
|
|
13417
|
my $rule_name = $node->{name}; |
1811
|
8157
|
|
|
|
|
11071
|
my $params_to_eval = $node->{__parameters}; |
1812
|
8157
|
|
|
|
|
11933
|
my $rule = $rules_details->{$rule_name}; |
1813
|
8157
|
|
|
|
|
10488
|
my $subroutine_to_run = $rule->{parsing_evaluation}; |
1814
|
|
|
|
|
|
|
|
1815
|
8157
|
100
|
|
|
|
20059
|
if ($rule->{use_parse_match}) { |
|
|
100
|
|
|
|
|
|
1816
|
3529
|
|
|
|
|
14512
|
$params_to_eval = $node->{parse_match}; |
1817
|
|
|
|
|
|
|
} |
1818
|
|
|
|
|
|
|
elsif ($rule->{use_string_match}) { |
1819
|
9
|
|
|
|
|
12
|
$params_to_eval = substr(${$parse_hash->{parse_this_ref}}, |
|
9
|
|
|
|
|
72
|
|
1820
|
|
|
|
|
|
|
$node->{position_when_entered}, |
1821
|
|
|
|
|
|
|
$node->{position_when_completed} - $node->{position_when_entered}); |
1822
|
|
|
|
|
|
|
} |
1823
|
8157
|
|
|
|
|
12147
|
my $alias = $node->{alias}; |
1824
|
|
|
|
|
|
|
|
1825
|
8157
|
|
|
|
|
8139
|
my $cv; |
1826
|
8157
|
100
|
|
|
|
12627
|
if ($subroutine_to_run) { |
1827
|
1556
|
|
|
|
|
3009
|
$parse_hash->{rule_name} = $rule_name; |
1828
|
1556
|
|
|
|
|
7941
|
$parse_hash->{current_node} = $node; |
1829
|
1556
|
|
|
|
|
6581
|
@results = &$subroutine_to_run($params_to_eval, $parse_hash); |
1830
|
1555
|
|
|
|
|
10828
|
$cv = $results[0]; |
1831
|
|
|
|
|
|
|
} |
1832
|
|
|
|
|
|
|
else { |
1833
|
6601
|
100
|
100
|
|
|
31941
|
if ($rule->{generated} || $self->{do_not_compress_eval}) { |
|
|
100
|
100
|
|
|
|
|
1834
|
4410
|
|
|
|
|
6188
|
$cv = $params_to_eval; |
1835
|
|
|
|
|
|
|
} |
1836
|
|
|
|
|
|
|
elsif ((ref $params_to_eval eq 'HASH') && (keys %$params_to_eval == 1)) { |
1837
|
1256
|
|
|
|
|
2755
|
($cv) = values %$params_to_eval; |
1838
|
|
|
|
|
|
|
} |
1839
|
|
|
|
|
|
|
else { |
1840
|
935
|
|
|
|
|
1338
|
$cv = $params_to_eval; |
1841
|
|
|
|
|
|
|
} |
1842
|
|
|
|
|
|
|
} |
1843
|
8156
|
|
|
|
|
17016
|
$node->{computed_value} = $cv; |
1844
|
|
|
|
|
|
|
|
1845
|
8156
|
|
|
|
|
7916
|
my $parent; |
1846
|
8156
|
100
|
|
|
|
19583
|
if ($parent = $node->{parent}) { |
1847
|
7804
|
|
|
|
|
11287
|
my $parent_name = $parent->{name}; |
1848
|
|
|
|
|
|
|
|
1849
|
7804
|
100
|
|
|
|
12472
|
if (defined $alias) { |
1850
|
5855
|
100
|
|
|
|
17171
|
if ($rules_details->{$parent_name}->{rule_count}->{$alias} > 1) { |
1851
|
2311
|
|
|
|
|
2380
|
push @{$parent->{__parameters}->{$alias}}, $cv; |
|
2311
|
|
|
|
|
9766
|
|
1852
|
2311
|
|
|
|
|
9705
|
$node->{passed_params}->{$alias} = 1; |
1853
|
|
|
|
|
|
|
} |
1854
|
|
|
|
|
|
|
else { |
1855
|
3544
|
|
|
|
|
9766
|
$parent->{__parameters}->{$alias} = $cv; |
1856
|
3544
|
|
|
|
|
30148
|
$node->{passed_params}->{$alias} = 0; |
1857
|
|
|
|
|
|
|
} |
1858
|
|
|
|
|
|
|
} |
1859
|
|
|
|
|
|
|
else { # !defined alias |
1860
|
1949
|
|
|
|
|
6254
|
foreach my $key (keys %$cv) { |
1861
|
2429
|
100
|
|
|
|
9628
|
if ($rules_details->{$rule_name}->{rule_count}->{$key} > 1) { |
|
|
100
|
|
|
|
|
|
1862
|
579
|
100
|
|
|
|
743
|
if (scalar(@{$cv->{$key}})) { |
|
579
|
|
|
|
|
1545
|
|
1863
|
553
|
|
|
|
|
671
|
push @{$parent->{__parameters}->{$key}}, @{$cv->{$key}}; |
|
553
|
|
|
|
|
1424
|
|
|
553
|
|
|
|
|
1432
|
|
1864
|
553
|
|
|
|
|
1030
|
$node->{passed_params}->{$key} = scalar(@{$cv->{$key}}); |
|
553
|
|
|
|
|
2545
|
|
1865
|
|
|
|
|
|
|
} |
1866
|
|
|
|
|
|
|
} |
1867
|
|
|
|
|
|
|
elsif ($rules_details->{$parent_name}->{rule_count}->{$key} > 1) { |
1868
|
1312
|
|
|
|
|
1284
|
push @{$parent->{__parameters}->{$key}}, $cv->{$key}; |
|
1312
|
|
|
|
|
3728
|
|
1869
|
1312
|
|
|
|
|
11265
|
$node->{passed_params}->{$key} = 1; |
1870
|
|
|
|
|
|
|
} |
1871
|
|
|
|
|
|
|
else { |
1872
|
538
|
|
|
|
|
1304
|
$parent->{__parameters}->{$key} = $cv->{$key}; |
1873
|
538
|
|
|
|
|
2069
|
$node->{passed_params}->{$key} = 0; |
1874
|
|
|
|
|
|
|
} |
1875
|
|
|
|
|
|
|
} |
1876
|
|
|
|
|
|
|
} |
1877
|
|
|
|
|
|
|
} |
1878
|
|
|
|
|
|
|
} |
1879
|
1530
|
|
|
|
|
3894
|
delete $parse_hash->{current_node}; |
1880
|
|
|
|
|
|
|
|
1881
|
1530
|
|
|
|
|
5105
|
return $results[1]; |
1882
|
|
|
|
|
|
|
} |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
sub LOCATION { |
1885
|
5
|
|
|
5
|
1
|
27
|
my ($text_ref, $value) = @_; |
1886
|
5
|
50
|
|
|
|
19
|
if (ref $text_ref ne 'SCALAR') { |
1887
|
0
|
|
|
|
|
0
|
croak "First arg to LOCATION must be string ref"; |
1888
|
|
|
|
|
|
|
} |
1889
|
5
|
|
|
|
|
16
|
my $substring = substr($$text_ref,0,$value+1); |
1890
|
5
|
|
|
|
|
17
|
my $line_number = 1 + ($substring =~ tr/\n//); |
1891
|
5
|
|
|
|
|
340
|
$substring =~ /([^\n]*)$/; |
1892
|
5
|
|
|
|
|
12
|
my $line_position = length($1); |
1893
|
5
|
|
|
|
|
24
|
return ($line_number, $line_position); |
1894
|
|
|
|
|
|
|
} |
1895
|
|
|
|
|
|
|
|
1896
|
|
|
|
|
|
|
sub parse_forward { |
1897
|
0
|
|
|
0
|
0
|
|
my $parse_hash = shift; |
1898
|
|
|
|
|
|
|
|
1899
|
|
|
|
|
|
|
} |
1900
|
|
|
|
|
|
|
|
1901
|
|
|
|
|
|
|
1; |
1902
|
|
|
|
|
|
|
|
1903
|
|
|
|
|
|
|
__END__ |