| 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__ |