line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyright 2012 Jeffrey Kegler |
2
|
|
|
|
|
|
|
# This file is part of Marpa::PP. Marpa::PP is free software: you can |
3
|
|
|
|
|
|
|
# redistribute it and/or modify it under the terms of the GNU Lesser |
4
|
|
|
|
|
|
|
# General Public License as published by the Free Software Foundation, |
5
|
|
|
|
|
|
|
# either version 3 of the License, or (at your option) any later version. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# Marpa::PP is distributed in the hope that it will be useful, |
8
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
9
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
10
|
|
|
|
|
|
|
# Lesser General Public License for more details. |
11
|
|
|
|
|
|
|
# |
12
|
|
|
|
|
|
|
# You should have received a copy of the GNU Lesser |
13
|
|
|
|
|
|
|
# General Public License along with Marpa::PP. If not, see |
14
|
|
|
|
|
|
|
# http://www.gnu.org/licenses/. |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
package Marpa::PP::Value; |
17
|
|
|
|
|
|
|
|
18
|
44
|
|
|
44
|
|
1340
|
use 5.010; |
|
44
|
|
|
|
|
162
|
|
|
44
|
|
|
|
|
2155
|
|
19
|
44
|
|
|
44
|
|
283
|
use warnings; |
|
44
|
|
|
|
|
89
|
|
|
44
|
|
|
|
|
2009
|
|
20
|
44
|
|
|
44
|
|
284
|
use strict; |
|
44
|
|
|
|
|
105
|
|
|
44
|
|
|
|
|
1847
|
|
21
|
44
|
|
|
44
|
|
282
|
use integer; |
|
44
|
|
|
|
|
118
|
|
|
44
|
|
|
|
|
434
|
|
22
|
|
|
|
|
|
|
|
23
|
44
|
|
|
44
|
|
7326
|
use vars qw($VERSION $STRING_VERSION); |
|
44
|
|
|
|
|
149
|
|
|
44
|
|
|
|
|
11092
|
|
24
|
|
|
|
|
|
|
$VERSION = '0.014000'; |
25
|
|
|
|
|
|
|
$STRING_VERSION = $VERSION; |
26
|
|
|
|
|
|
|
{ |
27
|
|
|
|
|
|
|
## no critic (BuiltinFunctions::ProhibitStringyEval) |
28
|
|
|
|
|
|
|
## no critic (ValuesAndExpressions::RequireConstantVersion) |
29
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
package Marpa::PP::Internal::Value; |
33
|
|
|
|
|
|
|
|
34
|
44
|
|
|
44
|
|
333
|
use English qw( -no_match_vars ); |
|
44
|
|
|
|
|
178
|
|
|
44
|
|
|
|
|
619
|
|
35
|
|
|
|
|
|
|
|
36
|
44
|
|
|
44
|
|
32282
|
no warnings qw(qw); ## no critic (TestingAndDebugging::ProhibitNoWarnings) |
|
44
|
|
|
|
|
99
|
|
|
44
|
|
|
|
|
5346
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
BEGIN { |
39
|
44
|
|
|
44
|
|
202
|
my $structure = <<'END_OF_STRUCTURE'; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::Or_Node |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
ID |
44
|
|
|
|
|
|
|
TAG |
45
|
|
|
|
|
|
|
ITEM |
46
|
|
|
|
|
|
|
RULE_ID |
47
|
|
|
|
|
|
|
POSITION |
48
|
|
|
|
|
|
|
AND_NODE_IDS |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
CYCLE { Can this Or node be part of a cycle? } |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
INITIAL_RANK_REF |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=LAST_FIELD |
55
|
|
|
|
|
|
|
END_OF_STRUCTURE |
56
|
44
|
|
|
|
|
278
|
Marpa::PP::offset($structure); |
57
|
|
|
|
|
|
|
} ## end BEGIN |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
BEGIN { |
60
|
44
|
|
|
44
|
|
112
|
my $structure = <<'END_OF_STRUCTURE'; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::And_Node |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
ID |
65
|
|
|
|
|
|
|
TAG |
66
|
|
|
|
|
|
|
RULE_ID |
67
|
|
|
|
|
|
|
TOKEN_NAME |
68
|
|
|
|
|
|
|
VALUE_REF |
69
|
|
|
|
|
|
|
VALUE_OPS |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
{ Fields before this (except ID) |
72
|
|
|
|
|
|
|
are used in evaluate() } |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
PREDECESSOR_ID |
75
|
|
|
|
|
|
|
CAUSE_ID |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
CAUSE_EARLEME |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
INITIAL_RANK_REF |
80
|
|
|
|
|
|
|
CONSTANT_RANK_REF |
81
|
|
|
|
|
|
|
TOKEN_RANK_REF |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
{ These earleme positions will be needed for the callbacks: } |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
START_EARLEME |
86
|
|
|
|
|
|
|
END_EARLEME |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
POSITION { This is only used for diagnostics, but |
89
|
|
|
|
|
|
|
diagnostics are important. } |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=LAST_FIELD |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
END_OF_STRUCTURE |
94
|
44
|
|
|
|
|
201
|
Marpa::PP::offset($structure); |
95
|
|
|
|
|
|
|
} ## end BEGIN |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
BEGIN { |
98
|
44
|
|
|
44
|
|
438
|
my $structure = <<'END_OF_STRUCTURE'; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::Iteration_Node |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
OR_NODE { The or-node } |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
CHOICES { |
105
|
|
|
|
|
|
|
A list of remaining choices of and-node. |
106
|
|
|
|
|
|
|
The current choice is first in the list. |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
PARENT { Offset of the parent in the iterations stack } |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
CAUSE_IX { Offset of the cause child, if any } |
112
|
|
|
|
|
|
|
PREDECESSOR_IX { Offset of the predecessor child, if any } |
113
|
|
|
|
|
|
|
{ IX value is -1 if IX needs to be recalculated } |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
CHILD_TYPE { Cause or Predecessor } |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
RANK { Current rank } |
118
|
|
|
|
|
|
|
CLEAN { Boolean -- true if rank does not need to |
119
|
|
|
|
|
|
|
be recalculated } |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
END_OF_STRUCTURE |
122
|
44
|
|
|
|
|
259
|
Marpa::PP::offset($structure); |
123
|
|
|
|
|
|
|
} ## end BEGIN |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
BEGIN { |
126
|
44
|
|
|
44
|
|
133
|
my $structure = <<'END_OF_STRUCTURE'; |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::Task |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
INITIALIZE |
131
|
|
|
|
|
|
|
POPULATE_OR_NODE |
132
|
|
|
|
|
|
|
POPULATE_DEPTH |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
RANK_ALL |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
ITERATE |
137
|
|
|
|
|
|
|
FIX_TREE |
138
|
|
|
|
|
|
|
STACK_INODE |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
END_OF_STRUCTURE |
141
|
44
|
|
|
|
|
217
|
Marpa::PP::offset($structure); |
142
|
|
|
|
|
|
|
} ## end BEGIN |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
BEGIN { |
145
|
44
|
|
|
44
|
|
126
|
my $structure = <<'END_OF_STRUCTURE'; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::Op |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
:{ These are the valuation-time ops } |
150
|
|
|
|
|
|
|
ARGC |
151
|
|
|
|
|
|
|
CALL |
152
|
|
|
|
|
|
|
CONSTANT_RESULT |
153
|
|
|
|
|
|
|
VIRTUAL_HEAD |
154
|
|
|
|
|
|
|
VIRTUAL_KERNEL |
155
|
|
|
|
|
|
|
VIRTUAL_TAIL |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
END_OF_STRUCTURE |
158
|
44
|
|
|
|
|
190
|
Marpa::PP::offset($structure); |
159
|
|
|
|
|
|
|
} ## end BEGIN |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
BEGIN { |
162
|
44
|
|
|
44
|
|
116
|
my $structure = <<'END_OF_STRUCTURE'; |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
:package=Marpa::PP::Internal::Choice |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
{ These are the valuation-time ops } |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
AND_NODE |
169
|
|
|
|
|
|
|
RANK { *NOT* a rank ref } |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
END_OF_STRUCTURE |
172
|
44
|
|
|
|
|
179
|
Marpa::PP::offset($structure); |
173
|
|
|
|
|
|
|
} ## end BEGIN |
174
|
|
|
|
|
|
|
|
175
|
44
|
|
|
44
|
|
652
|
use constant SKIP => -1; |
|
44
|
|
|
|
|
94
|
|
|
44
|
|
|
|
|
3562
|
|
176
|
|
|
|
|
|
|
|
177
|
44
|
|
|
44
|
|
300
|
use warnings; |
|
44
|
|
|
|
|
123
|
|
|
44
|
|
|
|
|
137258
|
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# The internal parameter is slightly misnamed -- between |
180
|
|
|
|
|
|
|
# calls it is the count of the *next* parse |
181
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::parse_count { |
182
|
9
|
|
|
9
|
0
|
116
|
my ($recce) = @_; |
183
|
9
|
|
|
|
|
34
|
return $recce->[Marpa::PP::Internal::Recognizer::PARSE_COUNT] - 1; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::and_node_tag { |
187
|
14066
|
|
|
14066
|
0
|
20984
|
my ( $recce, $and_node ) = @_; |
188
|
14066
|
|
|
|
|
22245
|
my $or_nodes = $recce->[Marpa::PP::Internal::Recognizer::OR_NODES]; |
189
|
14066
|
|
|
|
|
20654
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
190
|
14066
|
|
|
|
|
18430
|
my $symbol_hash = $grammar->[Marpa::PP::Internal::Grammar::SYMBOL_HASH]; |
191
|
14066
|
|
|
|
|
39491
|
my $recce_c = $recce->[Marpa::PP::Internal::Recognizer::C]; |
192
|
14066
|
|
|
|
|
22412
|
my $origin_earleme = |
193
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::START_EARLEME]; |
194
|
14066
|
|
|
|
|
34126
|
my $current_earleme = |
195
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::END_EARLEME]; |
196
|
14066
|
|
|
|
|
23093
|
my $middle_earleme = |
197
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::CAUSE_EARLEME]; |
198
|
14066
|
|
|
|
|
24281
|
my $position = $and_node->[Marpa::PP::Internal::And_Node::POSITION] + 1; |
199
|
14066
|
|
|
|
|
51419
|
my $rule = $and_node->[Marpa::PP::Internal::And_Node::RULE_ID]; |
200
|
|
|
|
|
|
|
|
201
|
14066
|
|
|
|
|
46428
|
my $tag = 'R' # perltidy, v20090616 adds trailing whitespace here |
202
|
|
|
|
|
|
|
. $rule . q{:} |
203
|
|
|
|
|
|
|
. $position . q{@} |
204
|
|
|
|
|
|
|
. $origin_earleme . q{-} |
205
|
|
|
|
|
|
|
. $current_earleme; |
206
|
14066
|
|
|
|
|
21858
|
my $cause_id = $and_node->[Marpa::PP::Internal::And_Node::CAUSE_ID]; |
207
|
|
|
|
|
|
|
|
208
|
14066
|
100
|
|
|
|
27073
|
if ( defined $cause_id ) { |
209
|
10591
|
|
|
|
|
15737
|
my $cause = $or_nodes->[$cause_id]; |
210
|
10591
|
|
|
|
|
19998
|
my $cause_rule = $cause->[Marpa::PP::Internal::Or_Node::RULE_ID]; |
211
|
10591
|
|
|
|
|
27170
|
$tag .= 'C' . $cause_rule; |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
else { |
214
|
3475
|
|
|
|
|
7269
|
my $token_name = |
215
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_NAME]; |
216
|
3475
|
|
|
|
|
7609
|
my $symbol = $symbol_hash->{$token_name}; |
217
|
3475
|
|
|
|
|
6941
|
$tag .= 'S' . $symbol; |
218
|
|
|
|
|
|
|
} ## end else [ if ( defined $cause_id ) ] |
219
|
14066
|
|
|
|
|
18309
|
$tag .= q{@} . $middle_earleme; |
220
|
14066
|
|
|
|
|
67851
|
return $tag; |
221
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::and_node_tag |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::or_node_tag { |
224
|
237
|
|
|
237
|
0
|
442
|
my ( $recce, $or_node ) = @_; |
225
|
237
|
50
|
|
|
|
827
|
die unless defined $or_node; |
226
|
237
|
|
|
|
|
599
|
my $item = $or_node->[Marpa::PP::Internal::Or_Node::ITEM]; |
227
|
237
|
|
|
|
|
450
|
my $set = $item->[Marpa::PP::Internal::Earley_Item::SET]; |
228
|
237
|
|
|
|
|
781
|
my $origin = $item->[Marpa::PP::Internal::Earley_Item::ORIGIN]; |
229
|
237
|
|
|
|
|
579
|
my $rule = $or_node->[Marpa::PP::Internal::Or_Node::RULE_ID]; |
230
|
237
|
|
|
|
|
416
|
my $position = $or_node->[Marpa::PP::Internal::Or_Node::POSITION]; |
231
|
237
|
|
|
|
|
1416
|
return 'R' . $rule . q{:} . $position . q{@} . $origin . q{-} . $set; |
232
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::or_node_tag |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::show_and_nodes { |
235
|
1
|
|
|
1
|
0
|
3
|
my ($recce) = @_; |
236
|
1
|
|
|
|
|
3
|
my $and_nodes = $recce->[Marpa::PP::Internal::Recognizer::AND_NODES]; |
237
|
1
|
|
|
|
|
2
|
my @data = (); |
238
|
1
|
|
|
|
|
4
|
for my $and_node ( @{$and_nodes} ) { |
|
1
|
|
|
|
|
3
|
|
239
|
23
|
|
|
|
|
48
|
my $desc = $recce->and_node_tag($and_node); |
240
|
23
|
|
|
|
|
153
|
my ( $rule, $position, $origin, $dot, $cause_type, $cause, $middle ) = |
241
|
|
|
|
|
|
|
( |
242
|
|
|
|
|
|
|
$desc =~ m{ |
243
|
|
|
|
|
|
|
\A R (\d+) [:] (\d+) |
244
|
|
|
|
|
|
|
[@] (\d+) [-] (\d+) ([SC]) (\d+) |
245
|
|
|
|
|
|
|
[@] (\d+) \z |
246
|
|
|
|
|
|
|
}msx |
247
|
|
|
|
|
|
|
); |
248
|
23
|
100
|
|
|
|
135
|
push @data, |
|
|
100
|
|
|
|
|
|
249
|
|
|
|
|
|
|
[ |
250
|
|
|
|
|
|
|
$origin, $dot, $rule, $position, $middle, |
251
|
|
|
|
|
|
|
( $cause_type eq 'C' ? $cause : -1 ), |
252
|
|
|
|
|
|
|
( $cause_type eq 'S' ? $cause : -1 ), $desc |
253
|
|
|
|
|
|
|
]; |
254
|
|
|
|
|
|
|
} ## end for my $and_node ( @{$and_nodes} ) |
255
|
23
|
50
|
100
|
|
|
53
|
my @tags = map { $_->[-1] } sort { |
|
81
|
|
100
|
|
|
464
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
256
|
1
|
|
|
|
|
5
|
$a->[0] <=> $b->[0] |
257
|
|
|
|
|
|
|
or $a->[1] <=> $b->[1] |
258
|
|
|
|
|
|
|
or $a->[2] <=> $b->[2] |
259
|
|
|
|
|
|
|
or $a->[3] <=> $b->[3] |
260
|
|
|
|
|
|
|
or $a->[4] <=> $b->[4] |
261
|
|
|
|
|
|
|
or $a->[5] <=> $b->[5] |
262
|
|
|
|
|
|
|
or $a->[6] <=> $b->[6] |
263
|
|
|
|
|
|
|
} @data; |
264
|
1
|
|
|
|
|
9
|
my $result = ( join "\n", @tags ) . "\n"; |
265
|
1
|
|
|
|
|
21
|
return $result; |
266
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::show_and_nodes |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::show_or_nodes { |
269
|
1
|
|
|
1
|
0
|
14
|
my ($recce) = @_; |
270
|
1
|
|
|
|
|
4
|
my $or_nodes = $recce->[Marpa::PP::Internal::Recognizer::OR_NODES]; |
271
|
1
|
|
|
|
|
24
|
my @data = (); |
272
|
1
|
|
|
|
|
2
|
for my $or_node ( @{$or_nodes} ) { |
|
1
|
|
|
|
|
4
|
|
273
|
20
|
|
|
|
|
38
|
my $desc = $recce->or_node_tag($or_node); |
274
|
20
|
|
|
|
|
88
|
my @elements = |
275
|
|
|
|
|
|
|
( $desc =~ /\A R (\d+) [:] (\d+) [@] (\d+) [-] (\d+) \z/msx ); |
276
|
20
|
|
|
|
|
87
|
push @data, [ @elements, $desc ]; |
277
|
|
|
|
|
|
|
} ## end for my $or_node ( @{$or_nodes} ) |
278
|
20
|
50
|
100
|
|
|
36
|
my @tags = map { $_->[-1] } sort { |
|
59
|
|
100
|
|
|
255
|
|
279
|
1
|
|
|
|
|
7
|
$a->[2] <=> $b->[2] |
280
|
|
|
|
|
|
|
or $a->[3] <=> $b->[3] |
281
|
|
|
|
|
|
|
or $a->[0] <=> $b->[0] |
282
|
|
|
|
|
|
|
or $a->[1] <=> $b->[1] |
283
|
|
|
|
|
|
|
} @data; |
284
|
1
|
|
|
|
|
7
|
my $result = ( join "\n", @tags ) . "\n"; |
285
|
1
|
|
|
|
|
27
|
return $result; |
286
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::show_or_nodes |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub Marpa::PP::brief_iteration_node { |
289
|
0
|
|
|
0
|
0
|
0
|
my ($iteration_node) = @_; |
290
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
0
|
my $or_node = |
292
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::OR_NODE]; |
293
|
0
|
|
|
|
|
0
|
my $or_node_id = $or_node->[Marpa::PP::Internal::Or_Node::ID]; |
294
|
0
|
|
|
|
|
0
|
my $and_node_ids = $or_node->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS]; |
295
|
0
|
|
|
|
|
0
|
my $text = "o$or_node_id"; |
296
|
|
|
|
|
|
|
DESCRIBE_CHOICES: { |
297
|
0
|
0
|
|
|
|
0
|
if ( not defined $and_node_ids ) { |
|
0
|
|
|
|
|
0
|
|
298
|
0
|
|
|
|
|
0
|
$text .= ' UNPOPULATED'; |
299
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
300
|
|
|
|
|
|
|
} |
301
|
0
|
|
|
|
|
0
|
my $choices = |
302
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
303
|
0
|
0
|
|
|
|
0
|
if ( not defined $choices ) { |
304
|
0
|
|
|
|
|
0
|
$text .= ' Choices not initialized'; |
305
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
306
|
|
|
|
|
|
|
} |
307
|
0
|
|
|
|
|
0
|
my $choice = $choices->[0]; |
308
|
0
|
0
|
|
|
|
0
|
if ( defined $choice ) { |
309
|
0
|
|
|
|
|
0
|
$text |
310
|
|
|
|
|
|
|
.= " [$choice] == a" |
311
|
|
|
|
|
|
|
. $choice->[Marpa::PP::Internal::Choice::AND_NODE] |
312
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::ID]; |
313
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
314
|
|
|
|
|
|
|
} ## end if ( defined $choice ) |
315
|
0
|
|
|
|
|
0
|
$text .= "o$or_node_id has no choices left"; |
316
|
|
|
|
|
|
|
} ## end DESCRIBE_CHOICES: |
317
|
0
|
|
0
|
|
|
0
|
my $parent_ix = |
318
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::PARENT] |
319
|
|
|
|
|
|
|
// q{-}; |
320
|
0
|
|
|
|
|
0
|
return "$text; p=$parent_ix"; |
321
|
|
|
|
|
|
|
} ## end sub Marpa::PP::brief_iteration_node |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub Marpa::PP::show_rank_ref { |
324
|
0
|
|
|
0
|
0
|
0
|
my ($rank_ref) = @_; |
325
|
0
|
0
|
|
|
|
0
|
return 'undef' if not defined $rank_ref; |
326
|
0
|
0
|
|
|
|
0
|
return 'SKIP' if $rank_ref == Marpa::PP::Internal::Value::SKIP; |
327
|
0
|
|
|
|
|
0
|
return ${$rank_ref}; |
|
0
|
|
|
|
|
0
|
|
328
|
|
|
|
|
|
|
} ## end sub Marpa::PP::show_rank_ref |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::show_iteration_node { |
331
|
0
|
|
|
0
|
0
|
0
|
my ( $recce, $iteration_node, $verbose ) = @_; |
332
|
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
0
|
my $or_node = |
334
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::OR_NODE]; |
335
|
0
|
|
|
|
|
0
|
my $or_node_id = $or_node->[Marpa::PP::Internal::Or_Node::ID]; |
336
|
0
|
|
|
|
|
0
|
my $or_node_tag = $or_node->[Marpa::PP::Internal::Or_Node::TAG]; |
337
|
0
|
|
|
|
|
0
|
my $text = "o$or_node_id $or_node_tag; "; |
338
|
0
|
|
|
|
|
0
|
given ( |
339
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CHILD_TYPE] ) |
340
|
|
|
|
|
|
|
{ |
341
|
0
|
|
|
|
|
0
|
when (Marpa::PP::Internal::And_Node::CAUSE_ID) { |
342
|
0
|
|
|
|
|
0
|
$text .= 'cause ' |
343
|
|
|
|
|
|
|
} |
344
|
0
|
|
|
|
|
0
|
when (Marpa::PP::Internal::And_Node::PREDECESSOR_ID) { |
345
|
0
|
|
|
|
|
0
|
$text .= 'predecessor ' |
346
|
|
|
|
|
|
|
} |
347
|
0
|
|
|
|
|
0
|
default { |
348
|
0
|
|
|
|
|
0
|
$text .= '- ' |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
} ## end given |
351
|
|
|
|
|
|
|
|
352
|
0
|
0
|
0
|
|
|
0
|
$text |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
353
|
|
|
|
|
|
|
.= 'pr=' |
354
|
|
|
|
|
|
|
. ( |
355
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX] |
356
|
|
|
|
|
|
|
// q{-} ) |
357
|
|
|
|
|
|
|
. q{;c=} |
358
|
|
|
|
|
|
|
. ( $iteration_node->[Marpa::PP::Internal::Iteration_Node::CAUSE_IX] |
359
|
|
|
|
|
|
|
// q{-} ) |
360
|
|
|
|
|
|
|
. q{;p=} |
361
|
|
|
|
|
|
|
. ( $iteration_node->[Marpa::PP::Internal::Iteration_Node::PARENT] |
362
|
|
|
|
|
|
|
// q{-} ) |
363
|
|
|
|
|
|
|
. q{; rank=} |
364
|
|
|
|
|
|
|
. ( $iteration_node->[Marpa::PP::Internal::Iteration_Node::RANK] |
365
|
|
|
|
|
|
|
// 'undef' ) |
366
|
|
|
|
|
|
|
. ( |
367
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CLEAN] |
368
|
|
|
|
|
|
|
? q{} |
369
|
|
|
|
|
|
|
: ' (dirty)' |
370
|
|
|
|
|
|
|
) . "\n"; |
371
|
|
|
|
|
|
|
|
372
|
0
|
|
|
|
|
0
|
DESCRIBE_CHOICES: { |
373
|
0
|
|
|
|
|
0
|
my $and_node_ids = |
374
|
|
|
|
|
|
|
$or_node->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS]; |
375
|
0
|
0
|
|
|
|
0
|
if ( not defined $and_node_ids ) { |
376
|
0
|
|
|
|
|
0
|
$text .= " UNPOPULATED\n"; |
377
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
378
|
|
|
|
|
|
|
} |
379
|
0
|
|
|
|
|
0
|
my $choices = |
380
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
381
|
0
|
0
|
|
|
|
0
|
if ( not defined $choices ) { |
382
|
0
|
|
|
|
|
0
|
$text .= " Choices not initialized\n"; |
383
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
384
|
|
|
|
|
|
|
} |
385
|
0
|
0
|
|
|
|
0
|
if ( not scalar @{$choices} ) { |
|
0
|
|
|
|
|
0
|
|
386
|
0
|
|
|
|
|
0
|
$text .= " has no choices left\n"; |
387
|
0
|
|
|
|
|
0
|
last DESCRIBE_CHOICES; |
388
|
|
|
|
|
|
|
} |
389
|
0
|
|
|
|
|
0
|
for my $choice_ix ( 0 .. $#{$choices} ) { |
|
0
|
|
|
|
|
0
|
|
390
|
0
|
|
|
|
|
0
|
my $choice = $choices->[$choice_ix]; |
391
|
0
|
|
|
|
|
0
|
$text .= " o$or_node_id" . '[' . $choice_ix . '] '; |
392
|
0
|
|
|
|
|
0
|
my $and_node = $choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
393
|
0
|
|
|
|
|
0
|
my $and_node_tag = |
394
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG]; |
395
|
0
|
|
|
|
|
0
|
my $and_node_id = $and_node->[Marpa::PP::Internal::And_Node::ID]; |
396
|
0
|
|
|
|
|
0
|
$text .= " ::= a$and_node_id $and_node_tag"; |
397
|
44
|
|
|
44
|
|
442
|
no integer; |
|
44
|
|
|
|
|
139
|
|
|
44
|
|
|
|
|
453
|
|
398
|
0
|
0
|
|
|
|
0
|
if ($verbose) { |
399
|
0
|
|
|
|
|
0
|
$text .= q{; rank=} |
400
|
|
|
|
|
|
|
. $choice->[Marpa::PP::Internal::Choice::RANK]; |
401
|
|
|
|
|
|
|
} |
402
|
0
|
|
|
|
|
0
|
$text .= "\n"; |
403
|
0
|
0
|
|
|
|
0
|
last CHOICE if not $verbose; |
404
|
|
|
|
|
|
|
} ## end for my $choice_ix ( 0 .. $#{$choices} ) |
405
|
|
|
|
|
|
|
} ## end DESCRIBE_CHOICES: |
406
|
0
|
|
|
|
|
0
|
return $text; |
407
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::show_iteration_node |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::show_iteration_stack { |
410
|
0
|
|
|
0
|
0
|
0
|
my ( $recce, $verbose ) = @_; |
411
|
0
|
|
|
|
|
0
|
my $iteration_stack = |
412
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::ITERATION_STACK]; |
413
|
0
|
|
|
|
|
0
|
my $text = q{}; |
414
|
0
|
|
|
|
|
0
|
for my $ix ( 0 .. $#{$iteration_stack} ) { |
|
0
|
|
|
|
|
0
|
|
415
|
0
|
|
|
|
|
0
|
my $iteration_node = $iteration_stack->[$ix]; |
416
|
0
|
|
|
|
|
0
|
$text .= "$ix: " |
417
|
|
|
|
|
|
|
. $recce->show_iteration_node( $iteration_node, $verbose ); |
418
|
|
|
|
|
|
|
} |
419
|
0
|
|
|
|
|
0
|
return $text; |
420
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::show_iteration_stack |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
package Marpa::PP::Internal::Recognizer; |
423
|
|
|
|
|
|
|
our $DEFAULT_ACTION_VALUE = \undef; |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
package Marpa::PP::Internal::Value; |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
sub Marpa::PP::Internal::Recognizer::set_null_values { |
428
|
185
|
|
|
185
|
|
566
|
my ($recce) = @_; |
429
|
185
|
|
|
|
|
375
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
430
|
185
|
|
|
|
|
414
|
my $trace_values = |
431
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_VALUES]; |
432
|
|
|
|
|
|
|
|
433
|
185
|
|
|
|
|
439
|
my $rules = $grammar->[Marpa::PP::Internal::Grammar::RULES]; |
434
|
185
|
|
|
|
|
453
|
my $symbols = $grammar->[Marpa::PP::Internal::Grammar::SYMBOLS]; |
435
|
185
|
|
|
|
|
362
|
my $default_null_value = |
436
|
|
|
|
|
|
|
$grammar->[Marpa::PP::Internal::Grammar::DEFAULT_NULL_VALUE]; |
437
|
|
|
|
|
|
|
|
438
|
185
|
|
|
|
|
331
|
my $null_values; |
439
|
185
|
|
|
|
|
327
|
$#{$null_values} = $#{$symbols}; |
|
185
|
|
|
|
|
1249
|
|
|
185
|
|
|
|
|
407
|
|
440
|
|
|
|
|
|
|
|
441
|
185
|
|
|
|
|
347
|
SYMBOL: for my $symbol ( @{$symbols} ) { |
|
185
|
|
|
|
|
521
|
|
442
|
4296
|
100
|
|
|
|
10931
|
next SYMBOL if not $symbol->[Marpa::PP::Internal::Symbol::NULLING]; |
443
|
|
|
|
|
|
|
|
444
|
578
|
|
|
|
|
676
|
my $null_value = undef; |
445
|
578
|
100
|
|
|
|
1337
|
if ( $symbol->[Marpa::PP::Internal::Symbol::NULL_VALUE] ) { |
446
|
18
|
|
|
|
|
38
|
$null_value = |
447
|
18
|
|
|
|
|
20
|
${ $symbol->[Marpa::PP::Internal::Symbol::NULL_VALUE] }; |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
else { |
450
|
560
|
|
|
|
|
706
|
$null_value = $default_null_value; |
451
|
|
|
|
|
|
|
} |
452
|
578
|
100
|
|
|
|
1468
|
next SYMBOL if not defined $null_value; |
453
|
|
|
|
|
|
|
|
454
|
103
|
|
|
|
|
152
|
my $symbol_id = $symbol->[Marpa::PP::Internal::Symbol::ID]; |
455
|
103
|
|
|
|
|
183
|
$null_values->[$symbol_id] = $null_value; |
456
|
|
|
|
|
|
|
|
457
|
103
|
50
|
|
|
|
320
|
if ($trace_values) { |
458
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
459
|
|
|
|
|
|
|
'Setting null value for symbol ', |
460
|
|
|
|
|
|
|
$symbol->[Marpa::PP::Internal::Symbol::NAME], |
461
|
|
|
|
|
|
|
' to ', Data::Dumper->new( [ \$null_value ] )->Terse(1)->Dump |
462
|
|
|
|
|
|
|
or Marpa::PP::exception('Could not print to trace file'); |
463
|
|
|
|
|
|
|
} ## end if ($trace_values) |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
} ## end for my $symbol ( @{$symbols} ) |
466
|
|
|
|
|
|
|
|
467
|
185
|
|
|
|
|
885
|
return $null_values; |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
} # set_null_values |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# Given the grammar and an action name, resolve it to a closure, |
472
|
|
|
|
|
|
|
# or return undef |
473
|
|
|
|
|
|
|
sub Marpa::PP::Internal::Recognizer::resolve_semantics { |
474
|
5304
|
|
|
5304
|
|
13836
|
my ( $recce, $closure_name ) = @_; |
475
|
5304
|
|
|
|
|
16382
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
476
|
5304
|
|
|
|
|
6734
|
my $closures = $recce->[Marpa::PP::Internal::Recognizer::CLOSURES]; |
477
|
5304
|
|
|
|
|
6783
|
my $trace_actions = |
478
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_ACTIONS]; |
479
|
|
|
|
|
|
|
|
480
|
5304
|
50
|
|
|
|
10508
|
Marpa::PP::exception(q{Trying to resolve 'undef' as closure name}) |
481
|
|
|
|
|
|
|
if not defined $closure_name; |
482
|
|
|
|
|
|
|
|
483
|
5304
|
100
|
|
|
|
26872
|
if ( my $closure = $closures->{$closure_name} ) { |
484
|
3220
|
50
|
|
|
|
5797
|
if ($trace_actions) { |
485
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
486
|
|
|
|
|
|
|
qq{Resolved "$closure_name" to explicit closure\n} |
487
|
|
|
|
|
|
|
or Marpa::PP::exception('Could not print to trace file'); |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
3220
|
|
|
|
|
6418
|
return $closure; |
491
|
|
|
|
|
|
|
} ## end if ( my $closure = $closures->{$closure_name} ) |
492
|
|
|
|
|
|
|
|
493
|
2084
|
|
|
|
|
2211
|
my $fully_qualified_name; |
494
|
|
|
|
|
|
|
DETERMINE_FULLY_QUALIFIED_NAME: { |
495
|
2084
|
100
|
|
|
|
2200
|
if ( $closure_name =~ /([:][:])|[']/xms ) { |
|
2084
|
|
|
|
|
8915
|
|
496
|
219
|
|
|
|
|
308
|
$fully_qualified_name = $closure_name; |
497
|
219
|
|
|
|
|
6268
|
last DETERMINE_FULLY_QUALIFIED_NAME; |
498
|
|
|
|
|
|
|
} |
499
|
1865
|
100
|
|
|
|
4287
|
if (defined( |
500
|
|
|
|
|
|
|
my $actions_package = |
501
|
|
|
|
|
|
|
$grammar->[Marpa::PP::Internal::Grammar::ACTIONS] |
502
|
|
|
|
|
|
|
) |
503
|
|
|
|
|
|
|
) |
504
|
|
|
|
|
|
|
{ |
505
|
214
|
|
|
|
|
485
|
$fully_qualified_name = $actions_package . q{::} . $closure_name; |
506
|
214
|
|
|
|
|
341
|
last DETERMINE_FULLY_QUALIFIED_NAME; |
507
|
|
|
|
|
|
|
} ## end if ( defined( my $actions_package = $grammar->[...])) |
508
|
|
|
|
|
|
|
|
509
|
1651
|
100
|
|
|
|
3828
|
if (defined( |
510
|
|
|
|
|
|
|
my $action_object_class = |
511
|
|
|
|
|
|
|
$grammar->[Marpa::PP::Internal::Grammar::ACTION_OBJECT] |
512
|
|
|
|
|
|
|
) |
513
|
|
|
|
|
|
|
) |
514
|
|
|
|
|
|
|
{ |
515
|
5
|
|
|
|
|
12
|
$fully_qualified_name = |
516
|
|
|
|
|
|
|
$action_object_class . q{::} . $closure_name; |
517
|
|
|
|
|
|
|
} ## end if ( defined( my $action_object_class = $grammar->[...])) |
518
|
|
|
|
|
|
|
} ## end DETERMINE_FULLY_QUALIFIED_NAME: |
519
|
|
|
|
|
|
|
|
520
|
2084
|
100
|
|
|
|
9544
|
return if not defined $fully_qualified_name; |
521
|
|
|
|
|
|
|
|
522
|
44
|
|
|
44
|
|
57597
|
no strict 'refs'; |
|
44
|
|
|
|
|
106
|
|
|
44
|
|
|
|
|
2865
|
|
523
|
438
|
|
|
|
|
596
|
my $closure = *{$fully_qualified_name}{'CODE'}; |
|
438
|
|
|
|
|
2073
|
|
524
|
44
|
|
|
44
|
|
272
|
use strict 'refs'; |
|
44
|
|
|
|
|
269
|
|
|
44
|
|
|
|
|
134502
|
|
525
|
|
|
|
|
|
|
|
526
|
438
|
50
|
|
|
|
1092
|
if ($trace_actions) { |
527
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
0
|
|
|
|
0
|
|
528
|
|
|
|
|
|
|
( $closure ? 'Successful' : 'Failed' ) |
529
|
|
|
|
|
|
|
. qq{ resolution of "$closure_name" }, |
530
|
|
|
|
|
|
|
'to ', $fully_qualified_name, "\n" |
531
|
|
|
|
|
|
|
or Marpa::PP::exception('Could not print to trace file'); |
532
|
|
|
|
|
|
|
} ## end if ($trace_actions) |
533
|
|
|
|
|
|
|
|
534
|
438
|
|
|
|
|
1295
|
return $closure; |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Internal::Recognizer::resolve_semantics |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
sub Marpa::PP::Internal::Recognizer::set_actions { |
539
|
235
|
|
|
235
|
|
498
|
my ($recce) = @_; |
540
|
235
|
|
|
|
|
490
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
541
|
|
|
|
|
|
|
|
542
|
235
|
|
|
|
|
3754
|
my ( $rules, $default_action, ) = @{$grammar}[ |
|
235
|
|
|
|
|
740
|
|
543
|
|
|
|
|
|
|
Marpa::PP::Internal::Grammar::RULES, |
544
|
|
|
|
|
|
|
Marpa::PP::Internal::Grammar::DEFAULT_ACTION, |
545
|
|
|
|
|
|
|
]; |
546
|
|
|
|
|
|
|
|
547
|
235
|
|
|
|
|
481
|
my $evaluator_rules = []; |
548
|
|
|
|
|
|
|
|
549
|
235
|
|
|
|
|
357
|
my $default_action_closure; |
550
|
235
|
100
|
|
|
|
760
|
if ( defined $default_action ) { |
551
|
169
|
|
|
|
|
607
|
$default_action_closure = |
552
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
553
|
|
|
|
|
|
|
$default_action ); |
554
|
169
|
50
|
|
|
|
583
|
Marpa::PP::exception( |
555
|
|
|
|
|
|
|
"Could not resolve default action named '$default_action'") |
556
|
|
|
|
|
|
|
if not $default_action_closure; |
557
|
|
|
|
|
|
|
} ## end if ( defined $default_action ) |
558
|
|
|
|
|
|
|
|
559
|
235
|
|
|
|
|
392
|
RULE: for my $rule ( @{$rules} ) { |
|
235
|
|
|
|
|
650
|
|
560
|
|
|
|
|
|
|
|
561
|
7666
|
100
|
|
|
|
19478
|
next RULE if not $rule->[Marpa::PP::Internal::Rule::USED]; |
562
|
|
|
|
|
|
|
|
563
|
6335
|
|
|
|
|
11861
|
my $rule_id = $rule->[Marpa::PP::Internal::Rule::ID]; |
564
|
6335
|
|
|
|
|
14148
|
my $ops = $evaluator_rules->[$rule_id] = []; |
565
|
|
|
|
|
|
|
|
566
|
6335
|
|
|
|
|
22800
|
my $virtual_rhs = $rule->[Marpa::PP::Internal::Rule::VIRTUAL_RHS]; |
567
|
6335
|
|
|
|
|
8413
|
my $virtual_lhs = $rule->[Marpa::PP::Internal::Rule::VIRTUAL_LHS]; |
568
|
|
|
|
|
|
|
|
569
|
6335
|
100
|
|
|
|
24044
|
if ($virtual_lhs) { |
570
|
1237
|
100
|
|
|
|
1423
|
push @{$ops}, |
|
1237
|
|
|
|
|
4051
|
|
571
|
|
|
|
|
|
|
( |
572
|
|
|
|
|
|
|
$virtual_rhs |
573
|
|
|
|
|
|
|
? Marpa::PP::Internal::Op::VIRTUAL_KERNEL |
574
|
|
|
|
|
|
|
: Marpa::PP::Internal::Op::VIRTUAL_TAIL |
575
|
|
|
|
|
|
|
), |
576
|
|
|
|
|
|
|
$rule->[Marpa::PP::Internal::Rule::REAL_SYMBOL_COUNT]; |
577
|
1237
|
|
|
|
|
4277
|
next RULE; |
578
|
|
|
|
|
|
|
} ## end if ($virtual_lhs) |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
# If we are here the LHS is real, not virtual |
581
|
|
|
|
|
|
|
|
582
|
5098
|
100
|
|
|
|
8513
|
if ($virtual_rhs) { |
|
4654
|
50
|
|
|
|
11983
|
|
583
|
444
|
|
|
|
|
601
|
push @{$ops}, |
|
444
|
|
|
|
|
1362
|
|
584
|
|
|
|
|
|
|
Marpa::PP::Internal::Op::VIRTUAL_HEAD, |
585
|
|
|
|
|
|
|
$rule->[Marpa::PP::Internal::Rule::REAL_SYMBOL_COUNT]; |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
# assignment instead of comparison is deliberate |
589
|
|
|
|
|
|
|
elsif ( my $argc = |
590
|
|
|
|
|
|
|
scalar @{ $rule->[Marpa::PP::Internal::Rule::RHS] } ) |
591
|
|
|
|
|
|
|
{ |
592
|
4654
|
|
|
|
|
5216
|
push @{$ops}, Marpa::PP::Internal::Op::ARGC, $argc; |
|
4654
|
|
|
|
|
11864
|
|
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
5098
|
100
|
|
|
|
24311
|
if ( my $action = $rule->[Marpa::PP::Internal::Rule::ACTION] ) { |
596
|
3394
|
|
|
|
|
6509
|
my $closure = |
597
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
598
|
|
|
|
|
|
|
$action ); |
599
|
|
|
|
|
|
|
|
600
|
3394
|
50
|
|
|
|
6603
|
Marpa::PP::exception(qq{Could not resolve action name: "$action"}) |
601
|
|
|
|
|
|
|
if not defined $closure; |
602
|
3394
|
|
|
|
|
4364
|
push @{$ops}, Marpa::PP::Internal::Op::CALL, $closure; |
|
3394
|
|
|
|
|
5987
|
|
603
|
3394
|
|
|
|
|
8596
|
next RULE; |
604
|
|
|
|
|
|
|
} ## end if ( my $action = $rule->[Marpa::PP::Internal::Rule::ACTION...]) |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
# Try to resolve the LHS as a closure name, |
607
|
|
|
|
|
|
|
# if it is not internal. |
608
|
|
|
|
|
|
|
# If we can't resolve |
609
|
|
|
|
|
|
|
# the LHS as a closure name, it's not |
610
|
|
|
|
|
|
|
# a fatal error. |
611
|
1704
|
50
|
|
|
|
4485
|
if ( my $action = |
612
|
|
|
|
|
|
|
$rule->[Marpa::PP::Internal::Rule::LHS] |
613
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Symbol::NAME] ) |
614
|
|
|
|
|
|
|
{ |
615
|
1704
|
100
|
66
|
|
|
7468
|
if ($action !~ /[\]] \z/xms |
616
|
|
|
|
|
|
|
and defined( |
617
|
|
|
|
|
|
|
my $closure = |
618
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( |
619
|
|
|
|
|
|
|
$recce, $action |
620
|
|
|
|
|
|
|
) |
621
|
|
|
|
|
|
|
) |
622
|
|
|
|
|
|
|
) |
623
|
|
|
|
|
|
|
{ |
624
|
23
|
|
|
|
|
29
|
push @{$ops}, Marpa::PP::Internal::Op::CALL, $closure; |
|
23
|
|
|
|
|
45
|
|
625
|
23
|
|
|
|
|
58
|
next RULE; |
626
|
|
|
|
|
|
|
} ## end if ( $action !~ /[\]] \z/xms and defined( my $closure...)[) |
627
|
|
|
|
|
|
|
} ## end if ( my $action = $rule->[Marpa::PP::Internal::Rule::LHS...]) |
628
|
|
|
|
|
|
|
|
629
|
1681
|
100
|
|
|
|
3148
|
if ( defined $default_action_closure ) { |
630
|
484
|
|
|
|
|
604
|
push @{$ops}, Marpa::PP::Internal::Op::CALL, |
|
484
|
|
|
|
|
1006
|
|
631
|
|
|
|
|
|
|
$default_action_closure; |
632
|
484
|
|
|
|
|
1250
|
next RULE; |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# If there is no default action specified, the fallback |
636
|
|
|
|
|
|
|
# is to return an undef |
637
|
1197
|
|
|
|
|
1171
|
push @{$ops}, Marpa::PP::Internal::Op::CONSTANT_RESULT, |
|
1197
|
|
|
|
|
2960
|
|
638
|
|
|
|
|
|
|
$Marpa::PP::Internal::Recognizer::DEFAULT_ACTION_VALUE; |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
} ## end for my $rule ( @{$rules} ) |
641
|
|
|
|
|
|
|
|
642
|
235
|
|
|
|
|
1328
|
return $evaluator_rules; |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
} # set_actions |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
# Returns false if no parse |
647
|
|
|
|
|
|
|
sub do_rank_all { |
648
|
22
|
|
|
22
|
|
43
|
my ( $recce, $depth_by_id ) = @_; |
649
|
22
|
|
|
|
|
68
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
650
|
22
|
|
|
|
|
50
|
my $symbols = $grammar->[Marpa::PP::Internal::Grammar::SYMBOLS]; |
651
|
22
|
|
|
|
|
50
|
my $rules = $grammar->[Marpa::PP::Internal::Grammar::RULES]; |
652
|
|
|
|
|
|
|
|
653
|
22
|
|
|
|
|
44
|
my $cycle_ranking_action = |
654
|
|
|
|
|
|
|
$grammar->[Marpa::PP::Internal::Grammar::CYCLE_RANKING_ACTION]; |
655
|
22
|
|
|
|
|
29
|
my $cycle_closure; |
656
|
22
|
50
|
|
|
|
68
|
if ( defined $cycle_ranking_action ) { |
657
|
0
|
|
|
|
|
0
|
$cycle_closure = |
658
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
659
|
|
|
|
|
|
|
$cycle_ranking_action ); |
660
|
0
|
0
|
|
|
|
0
|
Marpa::PP::exception( |
661
|
|
|
|
|
|
|
"Could not resolve cycle ranking action named '$cycle_ranking_action'" |
662
|
|
|
|
|
|
|
) if not $cycle_closure; |
663
|
|
|
|
|
|
|
} ## end if ( defined $cycle_ranking_action ) |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
# Set up rank closures by symbol |
666
|
22
|
|
|
|
|
50
|
my %ranking_closures_by_symbol = (); |
667
|
22
|
|
|
|
|
43
|
SYMBOL: for my $symbol ( @{$symbols} ) { |
|
22
|
|
|
|
|
64
|
|
668
|
908
|
|
|
|
|
1295
|
my $ranking_action = |
669
|
|
|
|
|
|
|
$symbol->[Marpa::PP::Internal::Symbol::RANKING_ACTION]; |
670
|
908
|
50
|
|
|
|
1849
|
next SYMBOL if not defined $ranking_action; |
671
|
0
|
|
|
|
|
0
|
my $ranking_closure = |
672
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
673
|
|
|
|
|
|
|
$ranking_action ); |
674
|
0
|
|
|
|
|
0
|
my $symbol_name = $symbol->[Marpa::PP::Internal::Symbol::NAME]; |
675
|
0
|
0
|
|
|
|
0
|
Marpa::PP::exception( |
676
|
|
|
|
|
|
|
"Could not resolve ranking action for symbol.\n", |
677
|
|
|
|
|
|
|
qq{ Symbol was "$symbol_name".}, |
678
|
|
|
|
|
|
|
qq{ Ranking action was "$ranking_action".} |
679
|
|
|
|
|
|
|
) if not defined $ranking_closure; |
680
|
0
|
|
|
|
|
0
|
$ranking_closures_by_symbol{$symbol_name} = $ranking_closure; |
681
|
|
|
|
|
|
|
} # end for my $symbol ( @{$symbols} ) |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
# Get closure used in ranking, by rule |
684
|
22
|
|
|
|
|
64
|
my @ranking_closures_by_rule = (); |
685
|
22
|
|
|
|
|
35
|
RULE: for my $rule ( @{$rules} ) { |
|
22
|
|
|
|
|
57
|
|
686
|
|
|
|
|
|
|
|
687
|
1536
|
|
|
|
|
2175
|
my $ranking_action = |
688
|
|
|
|
|
|
|
$rule->[Marpa::PP::Internal::Rule::RANKING_ACTION]; |
689
|
1536
|
|
|
|
|
1646
|
my $ranking_closure; |
690
|
1536
|
|
|
|
|
1650
|
my $cycle_rule = $rule->[Marpa::PP::Internal::Rule::CYCLE]; |
691
|
|
|
|
|
|
|
|
692
|
1536
|
50
|
66
|
|
|
2844
|
Marpa::PP::exception( |
693
|
|
|
|
|
|
|
"Rule which cycles has an explicit ranking action\n", |
694
|
|
|
|
|
|
|
qq{ The ranking action is "$ranking_action"\n}, |
695
|
|
|
|
|
|
|
qq{ To solve this problem,\n}, |
696
|
|
|
|
|
|
|
qq{ Rewrite the grammar so that this rule does not cycle\n}, |
697
|
|
|
|
|
|
|
qq{ Or eliminate its ranking action.\n} |
698
|
|
|
|
|
|
|
) if $ranking_action and $cycle_rule; |
699
|
|
|
|
|
|
|
|
700
|
1536
|
100
|
|
|
|
2347
|
if ($ranking_action) { |
701
|
36
|
|
|
|
|
95
|
$ranking_closure = |
702
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
703
|
|
|
|
|
|
|
$ranking_action ); |
704
|
36
|
50
|
|
|
|
236
|
Marpa::PP::exception( |
705
|
|
|
|
|
|
|
"Ranking closure '$ranking_action' not found") |
706
|
|
|
|
|
|
|
if not defined $ranking_closure; |
707
|
|
|
|
|
|
|
} ## end if ($ranking_action) |
708
|
|
|
|
|
|
|
|
709
|
1536
|
50
|
|
|
|
2328
|
if ($cycle_rule) { |
710
|
0
|
|
|
|
|
0
|
$ranking_closure = $cycle_closure; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
1536
|
100
|
|
|
|
3292
|
next RULE if not $ranking_closure; |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
# If the RHS is empty ... |
716
|
|
|
|
|
|
|
# Empty rules are never in cycles -- they are either |
717
|
|
|
|
|
|
|
# unused (because of the CHAF rewrite) or the special |
718
|
|
|
|
|
|
|
# null start rule. |
719
|
36
|
100
|
|
|
|
41
|
if ( not scalar @{ $rule->[Marpa::PP::Internal::Rule::RHS] } ) { |
|
36
|
|
|
|
|
138
|
|
720
|
16
|
50
|
|
|
|
40
|
Marpa::PP::exception( |
721
|
|
|
|
|
|
|
"Ranking closure '$ranking_action' not found") |
722
|
|
|
|
|
|
|
if not defined $ranking_closure; |
723
|
|
|
|
|
|
|
|
724
|
16
|
|
|
|
|
52
|
$ranking_closures_by_symbol{ $rule |
725
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Rule::LHS] |
726
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Symbol::NULL_ALIAS] |
727
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Symbol::NAME] } = |
728
|
|
|
|
|
|
|
$ranking_closure; |
729
|
|
|
|
|
|
|
} ## end if ( not scalar @{ $rule->[Marpa::PP::Internal::Rule::RHS...]}) |
730
|
|
|
|
|
|
|
|
731
|
36
|
100
|
|
|
|
201
|
next RULE if not $rule->[Marpa::PP::Internal::Rule::USED]; |
732
|
|
|
|
|
|
|
|
733
|
16
|
|
|
|
|
43
|
$ranking_closures_by_rule[ $rule->[Marpa::PP::Internal::Rule::ID] ] = |
734
|
|
|
|
|
|
|
$ranking_closure; |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
} ## end for my $rule ( @{$rules} ) |
737
|
|
|
|
|
|
|
|
738
|
22
|
|
|
|
|
62
|
my $and_nodes = $recce->[Marpa::PP::Internal::Recognizer::AND_NODES]; |
739
|
22
|
|
|
|
|
40
|
my $or_nodes = $recce->[Marpa::PP::Internal::Recognizer::OR_NODES]; |
740
|
|
|
|
|
|
|
|
741
|
22
|
|
|
|
|
53
|
my @and_node_worklist = (); |
742
|
22
|
|
|
|
|
38
|
AND_NODE: for my $and_node_id ( 0 .. $#{$and_nodes} ) { |
|
22
|
|
|
|
|
76
|
|
743
|
|
|
|
|
|
|
|
744
|
1118
|
|
|
|
|
1697
|
my $and_node = $and_nodes->[$and_node_id]; |
745
|
1118
|
|
|
|
|
1882
|
my $rule_id = $and_node->[Marpa::PP::Internal::And_Node::RULE_ID]; |
746
|
1118
|
|
|
|
|
1289
|
my $rule_closure = $ranking_closures_by_rule[$rule_id]; |
747
|
1118
|
|
|
|
|
1273
|
my $token_name = |
748
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_NAME]; |
749
|
1118
|
|
|
|
|
1036
|
my $token_closure; |
750
|
1118
|
100
|
|
|
|
1971
|
if ($token_name) { |
751
|
242
|
|
|
|
|
366
|
$token_closure = $ranking_closures_by_symbol{$token_name}; |
752
|
|
|
|
|
|
|
} |
753
|
|
|
|
|
|
|
|
754
|
1118
|
|
|
|
|
1071
|
my $token_rank_ref; |
755
|
|
|
|
|
|
|
my $rule_rank_ref; |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
# It is a feature of the ranking closures that they are always |
758
|
|
|
|
|
|
|
# called once per instance, even if the result is never used. |
759
|
|
|
|
|
|
|
# This sometimes makes for unnecessary calls, |
760
|
|
|
|
|
|
|
# but it makes these closures predictable enough |
761
|
|
|
|
|
|
|
# to allow their use for side effects. |
762
|
|
|
|
|
|
|
EVALUATION: |
763
|
1118
|
|
|
|
|
2866
|
for my $evaluation_data ( |
764
|
|
|
|
|
|
|
[ \$token_rank_ref, $token_closure ], |
765
|
|
|
|
|
|
|
[ \$rule_rank_ref, $rule_closure ] |
766
|
|
|
|
|
|
|
) |
767
|
|
|
|
|
|
|
{ |
768
|
2236
|
|
|
|
|
2596
|
my ( $rank_ref_ref, $closure ) = @{$evaluation_data}; |
|
2236
|
|
|
|
|
3363
|
|
769
|
2236
|
100
|
|
|
|
5812
|
next EVALUATION if not defined $closure; |
770
|
|
|
|
|
|
|
|
771
|
125
|
|
|
|
|
155
|
my @warnings; |
772
|
|
|
|
|
|
|
my $eval_ok; |
773
|
0
|
|
|
|
|
0
|
my $rank_ref; |
774
|
125
|
|
|
|
|
316
|
DO_EVAL: { |
775
|
125
|
|
|
|
|
144
|
local $Marpa::PP::Internal::CONTEXT = |
776
|
|
|
|
|
|
|
[ 'and-node', $and_node, $recce ]; |
777
|
|
|
|
|
|
|
local $SIG{__WARN__} = |
778
|
125
|
|
|
0
|
|
882
|
sub { push @warnings, [ $_[0], ( caller 0 ) ]; }; |
|
0
|
|
|
|
|
0
|
|
779
|
125
|
|
|
|
|
196
|
$eval_ok = eval { $rank_ref = $closure->(); 1; }; |
|
125
|
|
|
|
|
381
|
|
|
125
|
|
|
|
|
1273
|
|
780
|
|
|
|
|
|
|
} ## end DO_EVAL: |
781
|
|
|
|
|
|
|
|
782
|
125
|
|
|
|
|
169
|
my $fatal_error; |
783
|
|
|
|
|
|
|
CHECK_FOR_ERROR: { |
784
|
125
|
50
|
50
|
|
|
514
|
if ( not $eval_ok or scalar @warnings ) { |
|
125
|
|
|
|
|
482
|
|
785
|
0
|
|
0
|
|
|
0
|
$fatal_error = $EVAL_ERROR // 'Fatal Error'; |
786
|
0
|
|
|
|
|
0
|
last CHECK_FOR_ERROR; |
787
|
|
|
|
|
|
|
} |
788
|
125
|
50
|
66
|
|
|
538
|
if ( defined $rank_ref and not ref $rank_ref ) { |
789
|
0
|
|
|
|
|
0
|
$fatal_error = |
790
|
|
|
|
|
|
|
"Invalid return value from ranking closure: $rank_ref"; |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
} ## end CHECK_FOR_ERROR: |
793
|
|
|
|
|
|
|
|
794
|
125
|
50
|
|
|
|
230
|
if ( defined $fatal_error ) { |
795
|
|
|
|
|
|
|
|
796
|
0
|
|
|
|
|
0
|
Marpa::PP::Internal::code_problems( |
797
|
|
|
|
|
|
|
{ fatal_error => $fatal_error, |
798
|
|
|
|
|
|
|
grammar => $grammar, |
799
|
|
|
|
|
|
|
eval_ok => $eval_ok, |
800
|
|
|
|
|
|
|
warnings => \@warnings, |
801
|
|
|
|
|
|
|
where => 'ranking and-node ' |
802
|
|
|
|
|
|
|
. $and_node->[Marpa::PP::Internal::And_Node::TAG], |
803
|
|
|
|
|
|
|
} |
804
|
|
|
|
|
|
|
); |
805
|
|
|
|
|
|
|
} ## end if ( defined $fatal_error ) |
806
|
|
|
|
|
|
|
|
807
|
125
|
|
100
|
|
|
291
|
${$rank_ref_ref} = $rank_ref // Marpa::PP::Internal::Value::SKIP; |
|
125
|
|
|
|
|
328
|
|
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
} ## end for my $evaluation_data ( [ \$token_rank_ref, $token_closure...]) |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
# Set the token rank if there is a token. |
812
|
|
|
|
|
|
|
# It is zero if there is no token, or |
813
|
|
|
|
|
|
|
# if there is one with no closure. |
814
|
|
|
|
|
|
|
# Note: token can never cause a cycle, but they |
815
|
|
|
|
|
|
|
# can cause an and-node to be skipped. |
816
|
1118
|
100
|
|
|
|
2860
|
if ($token_name) { |
817
|
242
|
|
100
|
|
|
822
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_RANK_REF] = |
818
|
|
|
|
|
|
|
$token_rank_ref // \0; |
819
|
|
|
|
|
|
|
} |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
# See if we can set the rank for this node to a constant. |
822
|
1118
|
|
|
|
|
1114
|
my $constant_rank_ref; |
823
|
|
|
|
|
|
|
SET_CONSTANT_RANK: { |
824
|
|
|
|
|
|
|
|
825
|
1118
|
50
|
66
|
|
|
1159
|
if ( defined $token_rank_ref && !ref $token_rank_ref ) { |
|
1118
|
|
|
|
|
2545
|
|
826
|
0
|
|
|
|
|
0
|
$constant_rank_ref = Marpa::PP::Internal::Value::SKIP; |
827
|
0
|
|
|
|
|
0
|
last SET_CONSTANT_RANK; |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
# If we have ranking closure for this rule, the rank |
831
|
|
|
|
|
|
|
# is constant: |
832
|
|
|
|
|
|
|
# 0 for a non-final node, |
833
|
|
|
|
|
|
|
# the result of the closure for a final one |
834
|
1118
|
100
|
|
|
|
1824
|
if ( defined $rule_rank_ref ) { |
835
|
45
|
100
|
|
|
|
101
|
$constant_rank_ref = |
836
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::VALUE_OPS] |
837
|
|
|
|
|
|
|
? $rule_rank_ref |
838
|
|
|
|
|
|
|
: \0; |
839
|
45
|
|
|
|
|
74
|
last SET_CONSTANT_RANK; |
840
|
|
|
|
|
|
|
} ## end if ( defined $rule_rank_ref ) |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
# It there is a token and no predecessor, the rank |
843
|
|
|
|
|
|
|
# of this rule is a constant: |
844
|
|
|
|
|
|
|
# 0 is there was not token symbol closure |
845
|
|
|
|
|
|
|
# the result of that closure if there was one |
846
|
1073
|
100
|
100
|
|
|
2767
|
if ( $token_name |
847
|
|
|
|
|
|
|
and not defined |
848
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::PREDECESSOR_ID] ) |
849
|
|
|
|
|
|
|
{ |
850
|
150
|
|
100
|
|
|
487
|
$constant_rank_ref = $token_rank_ref // \0; |
851
|
|
|
|
|
|
|
} ## end if ( $token_name and not defined $and_node->[...]) |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
} ## end SET_CONSTANT_RANK: |
854
|
|
|
|
|
|
|
|
855
|
1118
|
100
|
|
|
|
1910
|
if ( defined $constant_rank_ref ) { |
856
|
195
|
|
|
|
|
331
|
$and_node->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF] = |
857
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::CONSTANT_RANK_REF] |
858
|
|
|
|
|
|
|
= $constant_rank_ref; |
859
|
|
|
|
|
|
|
|
860
|
195
|
|
|
|
|
452
|
next AND_NODE; |
861
|
|
|
|
|
|
|
} ## end if ( defined $constant_rank_ref ) |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
# If we are here there is (so far) no constant rank |
864
|
|
|
|
|
|
|
# so we stack this and-node for depth-sensitive evaluation |
865
|
923
|
|
|
|
|
1732
|
push @and_node_worklist, $and_node_id; |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
} ## end for my $and_node_id ( 0 .. $#{$and_nodes} ) |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
# Now go through the and-nodes that require context to be ranked |
870
|
|
|
|
|
|
|
# This loop assumes that all cycles has been taken care of |
871
|
|
|
|
|
|
|
# with constant ranks |
872
|
22
|
|
|
|
|
95
|
AND_NODE: while ( defined( my $and_node_id = pop @and_node_worklist ) ) { |
873
|
|
|
|
|
|
|
|
874
|
44
|
|
|
44
|
|
445
|
no integer; |
|
44
|
|
|
|
|
103
|
|
|
44
|
|
|
|
|
334
|
|
875
|
|
|
|
|
|
|
|
876
|
927
|
|
|
|
|
7030
|
my $and_node = $and_nodes->[$and_node_id]; |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
# Go to next if we have already ranked this and-node |
879
|
|
|
|
|
|
|
next AND_NODE |
880
|
|
|
|
|
|
|
if defined |
881
|
927
|
100
|
|
|
|
1946
|
$and_node->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF]; |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
# The rank calculated so far from the |
884
|
|
|
|
|
|
|
# children |
885
|
925
|
|
|
|
|
1170
|
my $calculated_rank = 0; |
886
|
|
|
|
|
|
|
|
887
|
925
|
|
|
|
|
984
|
my $is_cycle = 0; |
888
|
925
|
|
|
|
|
944
|
my $is_skip = 0; |
889
|
|
|
|
|
|
|
OR_NODE: |
890
|
925
|
|
|
|
|
1295
|
for my $field ( |
891
|
|
|
|
|
|
|
Marpa::PP::Internal::And_Node::PREDECESSOR_ID, |
892
|
|
|
|
|
|
|
Marpa::PP::Internal::And_Node::CAUSE_ID, |
893
|
|
|
|
|
|
|
) |
894
|
|
|
|
|
|
|
{ |
895
|
1837
|
|
|
|
|
2400
|
my $or_node_id = $and_node->[$field]; |
896
|
1837
|
100
|
|
|
|
3836
|
next OR_NODE if not defined $or_node_id; |
897
|
|
|
|
|
|
|
|
898
|
1097
|
|
|
|
|
1483
|
my $or_node = $or_nodes->[$or_node_id]; |
899
|
1097
|
100
|
|
|
|
2938
|
if (defined( |
900
|
|
|
|
|
|
|
my $or_node_initial_rank_ref = |
901
|
|
|
|
|
|
|
$or_node |
902
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::INITIAL_RANK_REF] |
903
|
|
|
|
|
|
|
) |
904
|
|
|
|
|
|
|
) |
905
|
|
|
|
|
|
|
{ |
906
|
99
|
50
|
|
|
|
218
|
if ( ref $or_node_initial_rank_ref ) { |
907
|
99
|
|
|
|
|
104
|
$calculated_rank += ${$or_node_initial_rank_ref}; |
|
99
|
|
|
|
|
135
|
|
908
|
99
|
|
|
|
|
235
|
next OR_NODE; |
909
|
|
|
|
|
|
|
} |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
# At this point only possible value is skip |
912
|
0
|
|
|
|
|
0
|
$and_node->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF] = |
913
|
|
|
|
|
|
|
$and_node |
914
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::CONSTANT_RANK_REF] = |
915
|
|
|
|
|
|
|
Marpa::PP::Internal::Value::SKIP; |
916
|
|
|
|
|
|
|
|
917
|
0
|
|
|
|
|
0
|
next AND_NODE; |
918
|
|
|
|
|
|
|
} ## end if ( defined( my $or_node_initial_rank_ref = $or_node...)) |
919
|
998
|
|
|
|
|
1344
|
my @ranks = (); |
920
|
998
|
|
|
|
|
1231
|
my @unranked_and_nodes = (); |
921
|
998
|
|
|
|
|
2004
|
CHILD_AND_NODE: |
922
|
998
|
|
|
|
|
1049
|
for my $child_and_node_id ( |
923
|
|
|
|
|
|
|
@{ $or_node->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS] } ) |
924
|
|
|
|
|
|
|
{ |
925
|
1038
|
|
|
|
|
1680
|
my $rank_ref = |
926
|
|
|
|
|
|
|
$and_nodes->[$child_and_node_id] |
927
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF]; |
928
|
1038
|
100
|
|
|
|
1834
|
if ( not defined $rank_ref ) { |
929
|
2
|
|
|
|
|
4
|
push @unranked_and_nodes, $child_and_node_id; |
930
|
|
|
|
|
|
|
|
931
|
2
|
|
|
|
|
6
|
next CHILD_AND_NODE; |
932
|
|
|
|
|
|
|
} |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
# Right now the only defined scalar value for a rank is |
935
|
|
|
|
|
|
|
# Marpa::PP::Internal::Value::SKIP |
936
|
1036
|
100
|
|
|
|
4767
|
next CHILD_AND_NODE if not ref $rank_ref; |
937
|
|
|
|
|
|
|
|
938
|
933
|
|
|
|
|
989
|
push @ranks, ${$rank_ref}; |
|
933
|
|
|
|
|
2596
|
|
939
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
} ## end for my $child_and_node_id ( @{ $or_node->[...]}) |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
# If we have unranked child and nodes, those have to be |
943
|
|
|
|
|
|
|
# ranked first. Schedule the work and move on. |
944
|
998
|
100
|
|
|
|
2494
|
if ( scalar @unranked_and_nodes ) { |
945
|
|
|
|
|
|
|
|
946
|
2
|
|
|
|
|
3
|
push @and_node_worklist, $and_node_id, @unranked_and_nodes; |
947
|
2
|
|
|
|
|
18
|
next AND_NODE; |
948
|
|
|
|
|
|
|
} |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
# If there were no non-skipped and-nodes, the |
951
|
|
|
|
|
|
|
# parent and-node must also be skipped |
952
|
996
|
100
|
|
|
|
13044
|
if ( not scalar @ranks ) { |
953
|
103
|
|
|
|
|
271
|
$or_node->[Marpa::PP::Internal::Or_Node::INITIAL_RANK_REF] = |
954
|
|
|
|
|
|
|
$and_node |
955
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF] = |
956
|
|
|
|
|
|
|
$and_node |
957
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::CONSTANT_RANK_REF] = |
958
|
|
|
|
|
|
|
Marpa::PP::Internal::Value::SKIP; |
959
|
|
|
|
|
|
|
|
960
|
103
|
|
|
|
|
412
|
next AND_NODE; |
961
|
|
|
|
|
|
|
} ## end if ( not scalar @ranks ) |
962
|
|
|
|
|
|
|
|
963
|
893
|
|
|
|
|
1717
|
my $or_calculated_rank = List::Util::max @ranks; |
964
|
893
|
|
|
|
|
1972
|
$or_node->[Marpa::PP::Internal::Or_Node::INITIAL_RANK_REF] = |
965
|
|
|
|
|
|
|
\$or_calculated_rank; |
966
|
893
|
|
|
|
|
3207
|
$calculated_rank += $or_calculated_rank; |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
} ## end for my $field ( ...) |
969
|
|
|
|
|
|
|
|
970
|
820
|
|
|
|
|
1248
|
my $token_rank_ref = |
971
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_RANK_REF]; |
972
|
820
|
100
|
|
|
|
1367
|
$calculated_rank += defined $token_rank_ref ? ${$token_rank_ref} : 0; |
|
63
|
|
|
|
|
84
|
|
973
|
820
|
|
|
|
|
2882
|
$and_node->[Marpa::PP::Internal::And_Node::INITIAL_RANK_REF] = |
974
|
|
|
|
|
|
|
\$calculated_rank; |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
} ## end while ( defined( my $and_node_id = pop @and_node_worklist...)) |
977
|
|
|
|
|
|
|
|
978
|
22
|
|
|
|
|
96
|
return; |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
} ## end sub do_rank_all |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
# Does not modify stack |
983
|
|
|
|
|
|
|
sub Marpa::PP::Internal::Recognizer::evaluate { |
984
|
2228
|
|
|
2228
|
|
4049
|
my ( $recce, $stack ) = @_; |
985
|
2228
|
|
|
|
|
4927
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
986
|
2228
|
|
100
|
|
|
13084
|
my $trace_values = $recce->[Marpa::PP::Internal::Recognizer::TRACE_VALUES] |
987
|
|
|
|
|
|
|
// 0; |
988
|
|
|
|
|
|
|
|
989
|
2228
|
|
|
|
|
5791
|
my $rules = $grammar->[Marpa::PP::Internal::Grammar::RULES]; |
990
|
2228
|
|
|
|
|
4660
|
my $action_object_class = |
991
|
|
|
|
|
|
|
$grammar->[Marpa::PP::Internal::Grammar::ACTION_OBJECT]; |
992
|
|
|
|
|
|
|
|
993
|
2228
|
|
|
|
|
4472
|
my $action_object_constructor; |
994
|
2228
|
100
|
|
|
|
8018
|
if ( defined $action_object_class ) { |
995
|
1
|
|
|
|
|
3
|
my $constructor_name = $action_object_class . q{::new}; |
996
|
1
|
|
|
|
|
3
|
my $closure = |
997
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::resolve_semantics( $recce, |
998
|
|
|
|
|
|
|
$constructor_name ); |
999
|
1
|
50
|
|
|
|
8
|
Marpa::PP::exception( |
1000
|
|
|
|
|
|
|
qq{Could not find constructor "$constructor_name"}) |
1001
|
|
|
|
|
|
|
if not defined $closure; |
1002
|
1
|
|
|
|
|
2
|
$action_object_constructor = $closure; |
1003
|
|
|
|
|
|
|
} ## end if ( defined $action_object_class ) |
1004
|
|
|
|
|
|
|
|
1005
|
2228
|
|
|
|
|
3320
|
my $action_object; |
1006
|
2228
|
100
|
|
|
|
5251
|
if ($action_object_constructor) { |
1007
|
1
|
|
|
|
|
2
|
my @warnings; |
1008
|
|
|
|
|
|
|
my $eval_ok; |
1009
|
0
|
|
|
|
|
0
|
my $fatal_error; |
1010
|
1
|
|
|
|
|
3
|
DO_EVAL: { |
1011
|
1
|
|
|
|
|
10
|
local $EVAL_ERROR = undef; |
1012
|
|
|
|
|
|
|
local $SIG{__WARN__} = sub { |
1013
|
0
|
|
|
0
|
|
0
|
push @warnings, [ $_[0], ( caller 0 ) ]; |
1014
|
1
|
|
|
|
|
15
|
}; |
1015
|
|
|
|
|
|
|
|
1016
|
1
|
|
|
|
|
3
|
$eval_ok = eval { |
1017
|
1
|
|
|
|
|
7
|
$action_object = |
1018
|
|
|
|
|
|
|
$action_object_constructor->($action_object_class); |
1019
|
1
|
|
|
|
|
7
|
1; |
1020
|
|
|
|
|
|
|
}; |
1021
|
1
|
|
|
|
|
9
|
$fatal_error = $EVAL_ERROR; |
1022
|
|
|
|
|
|
|
} ## end DO_EVAL: |
1023
|
|
|
|
|
|
|
|
1024
|
1
|
50
|
33
|
|
|
10
|
if ( not $eval_ok or @warnings ) { |
1025
|
0
|
|
|
|
|
0
|
Marpa::PP::Internal::code_problems( |
1026
|
|
|
|
|
|
|
{ fatal_error => $fatal_error, |
1027
|
|
|
|
|
|
|
grammar => $grammar, |
1028
|
|
|
|
|
|
|
eval_ok => $eval_ok, |
1029
|
|
|
|
|
|
|
warnings => \@warnings, |
1030
|
|
|
|
|
|
|
where => 'constructing action object', |
1031
|
|
|
|
|
|
|
} |
1032
|
|
|
|
|
|
|
); |
1033
|
|
|
|
|
|
|
} ## end if ( not $eval_ok or @warnings ) |
1034
|
|
|
|
|
|
|
} ## end if ($action_object_constructor) |
1035
|
|
|
|
|
|
|
|
1036
|
2228
|
|
100
|
|
|
9838
|
$action_object //= {}; |
1037
|
|
|
|
|
|
|
|
1038
|
2228
|
|
|
|
|
9736
|
my @evaluation_stack = (); |
1039
|
2228
|
|
|
|
|
5407
|
my @virtual_rule_stack = (); |
1040
|
2228
|
|
|
|
|
3253
|
TREE_NODE: for my $and_node ( reverse @{$stack} ) { |
|
2228
|
|
|
|
|
5590
|
|
1041
|
|
|
|
|
|
|
|
1042
|
53361
|
50
|
|
|
|
124175
|
if ( $trace_values >= 3 ) { |
1043
|
0
|
|
|
|
|
0
|
for my $i ( reverse 0 .. $#evaluation_stack ) { |
1044
|
0
|
0
|
|
|
|
0
|
printf {$Marpa::PP::Internal::TRACE_FH} 'Stack position %3d:', |
|
0
|
|
|
|
|
0
|
|
1045
|
|
|
|
|
|
|
$i |
1046
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1047
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} q{ }, |
|
0
|
|
|
|
|
0
|
|
1048
|
|
|
|
|
|
|
Data::Dumper->new( [ $evaluation_stack[$i] ] )->Terse(1) |
1049
|
|
|
|
|
|
|
->Dump |
1050
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1051
|
|
|
|
|
|
|
} ## end for my $i ( reverse 0 .. $#evaluation_stack ) |
1052
|
|
|
|
|
|
|
} ## end if ( $trace_values >= 3 ) |
1053
|
|
|
|
|
|
|
|
1054
|
53361
|
|
|
|
|
149108
|
my $value_ref = $and_node->[Marpa::PP::Internal::And_Node::VALUE_REF]; |
1055
|
|
|
|
|
|
|
|
1056
|
53361
|
100
|
|
|
|
129792
|
if ( defined $value_ref ) { |
1057
|
|
|
|
|
|
|
|
1058
|
22616
|
|
|
|
|
38208
|
push @evaluation_stack, $value_ref; |
1059
|
|
|
|
|
|
|
|
1060
|
22616
|
100
|
|
|
|
53097
|
if ($trace_values) { |
1061
|
14
|
|
|
|
|
24
|
my $token_name = |
1062
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_NAME]; |
1063
|
|
|
|
|
|
|
|
1064
|
14
|
50
|
|
|
|
17
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
14
|
50
|
|
|
|
105
|
|
1065
|
|
|
|
|
|
|
'Pushed value from ', |
1066
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG], ': ', |
1067
|
|
|
|
|
|
|
( $token_name ? qq{$token_name = } : q{} ), |
1068
|
|
|
|
|
|
|
Data::Dumper->new( [$value_ref] )->Terse(1)->Dump |
1069
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1070
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
} # defined $value_ref |
1073
|
|
|
|
|
|
|
|
1074
|
53361
|
|
|
|
|
96882
|
my $ops = $and_node->[Marpa::PP::Internal::And_Node::VALUE_OPS]; |
1075
|
|
|
|
|
|
|
|
1076
|
53361
|
100
|
|
|
|
132691
|
next TREE_NODE if not defined $ops; |
1077
|
|
|
|
|
|
|
|
1078
|
32973
|
|
|
|
|
65777
|
my $current_data = []; |
1079
|
32973
|
|
|
|
|
50161
|
my $op_ix = 0; |
1080
|
32973
|
|
|
|
|
41647
|
while ( $op_ix < scalar @{$ops} ) { |
|
87754
|
|
|
|
|
310901
|
|
1081
|
54787
|
|
|
|
|
99895
|
given ( $ops->[ $op_ix++ ] ) { |
1082
|
|
|
|
|
|
|
|
1083
|
54787
|
|
|
|
|
98666
|
when (Marpa::PP::Internal::Op::ARGC) { |
1084
|
|
|
|
|
|
|
|
1085
|
20099
|
|
|
|
|
37736
|
my $argc = $ops->[ $op_ix++ ]; |
1086
|
|
|
|
|
|
|
|
1087
|
20099
|
100
|
|
|
|
42818
|
if ($trace_values) { |
1088
|
18
|
|
|
|
|
27
|
my $rule_id = $and_node |
1089
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::RULE_ID]; |
1090
|
18
|
|
|
|
|
26
|
my $rule = $rules->[$rule_id]; |
1091
|
18
|
50
|
|
|
|
21
|
say {$Marpa::PP::Internal::TRACE_FH} |
|
18
|
|
|
|
|
69
|
|
1092
|
|
|
|
|
|
|
'Popping ', |
1093
|
|
|
|
|
|
|
$argc, |
1094
|
|
|
|
|
|
|
' values to evaluate ', |
1095
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG], |
1096
|
|
|
|
|
|
|
', rule: ', Marpa::PP::brief_rule($rule) |
1097
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1098
|
|
|
|
|
|
|
'Could not print to trace file'); |
1099
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
$current_data = |
1102
|
20099
|
|
|
|
|
68661
|
[ map { ${$_} } |
|
28438
|
|
|
|
|
45584
|
|
|
28438
|
|
|
|
|
170854
|
|
1103
|
|
|
|
|
|
|
( splice @evaluation_stack, -$argc ) ]; |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::ARGC) |
1106
|
|
|
|
|
|
|
|
1107
|
34688
|
|
|
|
|
74049
|
when (Marpa::PP::Internal::Op::VIRTUAL_HEAD) { |
1108
|
1715
|
|
|
|
|
3964
|
my $real_symbol_count = $ops->[ $op_ix++ ]; |
1109
|
|
|
|
|
|
|
|
1110
|
1715
|
50
|
|
|
|
3816
|
if ($trace_values) { |
1111
|
0
|
|
|
|
|
0
|
my $rule_id = $and_node |
1112
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::RULE_ID]; |
1113
|
0
|
|
|
|
|
0
|
my $rule = $rules->[$rule_id]; |
1114
|
0
|
0
|
|
|
|
0
|
say {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1115
|
|
|
|
|
|
|
'Head of Virtual Rule: ', |
1116
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG], |
1117
|
|
|
|
|
|
|
', rule: ', Marpa::PP::brief_rule($rule), |
1118
|
|
|
|
|
|
|
"\n", |
1119
|
|
|
|
|
|
|
"Incrementing virtual rule by $real_symbol_count symbols\n", |
1120
|
|
|
|
|
|
|
'Currently ', |
1121
|
|
|
|
|
|
|
( scalar @virtual_rule_stack ), |
1122
|
|
|
|
|
|
|
' rules; ', $virtual_rule_stack[-1], ' symbols;', |
1123
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1124
|
|
|
|
|
|
|
'Could not print to trace file'); |
1125
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1126
|
|
|
|
|
|
|
|
1127
|
1715
|
|
|
|
|
2227
|
$real_symbol_count += pop @virtual_rule_stack; |
1128
|
13761
|
|
|
|
|
31452
|
$current_data = |
1129
|
1715
|
|
|
|
|
26783
|
[ map { ${$_} } |
|
13761
|
|
|
|
|
13203
|
|
1130
|
|
|
|
|
|
|
( splice @evaluation_stack, -$real_symbol_count ) |
1131
|
|
|
|
|
|
|
]; |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::VIRTUAL_HEAD) |
1134
|
|
|
|
|
|
|
|
1135
|
32973
|
|
|
|
|
44621
|
when (Marpa::PP::Internal::Op::VIRTUAL_KERNEL) { |
1136
|
7222
|
|
|
|
|
11005
|
my $real_symbol_count = $ops->[ $op_ix++ ]; |
1137
|
7222
|
|
|
|
|
18108
|
$virtual_rule_stack[-1] += $real_symbol_count; |
1138
|
|
|
|
|
|
|
|
1139
|
7222
|
50
|
|
|
|
21381
|
if ($trace_values) { |
1140
|
0
|
|
|
|
|
0
|
my $rule_id = $and_node |
1141
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::RULE_ID]; |
1142
|
0
|
|
|
|
|
0
|
my $rule = $rules->[$rule_id]; |
1143
|
0
|
0
|
|
|
|
0
|
say {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1144
|
|
|
|
|
|
|
'Virtual Rule: ', |
1145
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG], |
1146
|
|
|
|
|
|
|
', rule: ', Marpa::PP::brief_rule($rule), |
1147
|
|
|
|
|
|
|
"\nAdding $real_symbol_count", |
1148
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1149
|
|
|
|
|
|
|
'Could not print to trace file'); |
1150
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::VIRTUAL_KERNEL) |
1153
|
|
|
|
|
|
|
|
1154
|
25751
|
|
|
|
|
44091
|
when (Marpa::PP::Internal::Op::VIRTUAL_TAIL) { |
1155
|
3937
|
|
|
|
|
13724
|
my $real_symbol_count = $ops->[ $op_ix++ ]; |
1156
|
|
|
|
|
|
|
|
1157
|
3937
|
100
|
|
|
|
8638
|
if ($trace_values) { |
1158
|
2
|
|
|
|
|
4
|
my $rule_id = $and_node |
1159
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::RULE_ID]; |
1160
|
2
|
|
|
|
|
5
|
my $rule = $rules->[$rule_id]; |
1161
|
2
|
50
|
|
|
|
4
|
say {$Marpa::PP::Internal::TRACE_FH} |
|
2
|
|
|
|
|
11
|
|
1162
|
|
|
|
|
|
|
'New Virtual Rule: ', |
1163
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::TAG], |
1164
|
|
|
|
|
|
|
', rule: ', Marpa::PP::brief_rule($rule), |
1165
|
|
|
|
|
|
|
"\nReal symbol count is $real_symbol_count", |
1166
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1167
|
|
|
|
|
|
|
'Could not print to trace file'); |
1168
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1169
|
|
|
|
|
|
|
|
1170
|
3937
|
|
|
|
|
11591
|
push @virtual_rule_stack, $real_symbol_count; |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::VIRTUAL_TAIL) |
1173
|
|
|
|
|
|
|
|
1174
|
21814
|
|
|
|
|
30107
|
when (Marpa::PP::Internal::Op::CONSTANT_RESULT) { |
1175
|
6573
|
|
|
|
|
11161
|
my $result = $ops->[ $op_ix++ ]; |
1176
|
6573
|
50
|
|
|
|
12877
|
if ($trace_values) { |
1177
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1178
|
|
|
|
|
|
|
'Constant result: ', |
1179
|
|
|
|
|
|
|
'Pushing 1 value on stack: ', |
1180
|
|
|
|
|
|
|
Data::Dumper->new( [$result] )->Terse(1)->Dump |
1181
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1182
|
|
|
|
|
|
|
'Could not print to trace file'); |
1183
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1184
|
6573
|
|
|
|
|
14604
|
push @evaluation_stack, $result; |
1185
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::CONSTANT_RESULT) |
1186
|
|
|
|
|
|
|
|
1187
|
15241
|
|
|
|
|
31939
|
when (Marpa::PP::Internal::Op::CALL) { |
1188
|
15241
|
|
|
|
|
27369
|
my $closure = $ops->[ $op_ix++ ]; |
1189
|
15241
|
|
|
|
|
36198
|
my $rule_id = |
1190
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::RULE_ID]; |
1191
|
15241
|
|
|
|
|
33728
|
my $rule = $rules->[$rule_id]; |
1192
|
15241
|
|
|
|
|
25764
|
my $original_rule = |
1193
|
|
|
|
|
|
|
$rule->[Marpa::PP::Internal::Rule::ORIGINAL_RULE]; |
1194
|
15241
|
100
|
|
|
|
45365
|
if ( $original_rule |
1195
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Rule::DISCARD_SEPARATION] ) |
1196
|
|
|
|
|
|
|
{ |
1197
|
32
|
|
|
|
|
105
|
$current_data = [ |
1198
|
241
|
|
|
|
|
435
|
@{$current_data}[ |
1199
|
32
|
|
|
|
|
82
|
grep { not $_ % 2 } 0 .. $#{$current_data} |
|
32
|
|
|
|
|
80
|
|
1200
|
|
|
|
|
|
|
] |
1201
|
|
|
|
|
|
|
]; |
1202
|
|
|
|
|
|
|
} ## end if ( $original_rule->[...]) |
1203
|
15241
|
|
|
|
|
20910
|
my $result; |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
my @warnings; |
1206
|
0
|
|
|
|
|
0
|
my $eval_ok; |
1207
|
|
|
|
|
|
|
DO_EVAL: { |
1208
|
15241
|
|
|
|
|
26999
|
local $SIG{__WARN__} = sub { |
1209
|
4
|
|
|
4
|
|
108
|
push @warnings, [ $_[0], ( caller 0 ) ]; |
1210
|
15241
|
|
|
|
|
135052
|
}; |
1211
|
|
|
|
|
|
|
|
1212
|
15241
|
|
|
|
|
53551
|
$eval_ok = eval { |
1213
|
15241
|
|
|
|
|
61967
|
$result = |
1214
|
|
|
|
|
|
|
$closure->( $action_object, |
1215
|
15241
|
|
|
|
|
41838
|
@{$current_data} ); |
1216
|
15237
|
|
|
|
|
961417
|
1; |
1217
|
|
|
|
|
|
|
}; |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
} ## end DO_EVAL: |
1220
|
|
|
|
|
|
|
|
1221
|
15241
|
100
|
100
|
|
|
105306
|
if ( not $eval_ok or @warnings ) { |
1222
|
6
|
|
|
|
|
16
|
my $fatal_error = $EVAL_ERROR; |
1223
|
6
|
|
|
|
|
50
|
Marpa::PP::Internal::code_problems( |
1224
|
|
|
|
|
|
|
{ fatal_error => $fatal_error, |
1225
|
|
|
|
|
|
|
grammar => $grammar, |
1226
|
|
|
|
|
|
|
eval_ok => $eval_ok, |
1227
|
|
|
|
|
|
|
warnings => \@warnings, |
1228
|
|
|
|
|
|
|
where => 'computing value', |
1229
|
|
|
|
|
|
|
long_where => 'Computing value for rule: ' |
1230
|
|
|
|
|
|
|
. Marpa::PP::brief_rule($rule), |
1231
|
|
|
|
|
|
|
} |
1232
|
|
|
|
|
|
|
); |
1233
|
|
|
|
|
|
|
} ## end if ( not $eval_ok or @warnings ) |
1234
|
|
|
|
|
|
|
|
1235
|
15235
|
100
|
|
|
|
51444
|
if ($trace_values) { |
1236
|
18
|
50
|
|
|
|
21
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
18
|
|
|
|
|
82
|
|
1237
|
|
|
|
|
|
|
'Calculated and pushed value: ', |
1238
|
|
|
|
|
|
|
Data::Dumper->new( [$result] )->Terse(1)->Dump |
1239
|
|
|
|
|
|
|
or Marpa::PP::exception( |
1240
|
|
|
|
|
|
|
'print to trace handle failed'); |
1241
|
|
|
|
|
|
|
} ## end if ($trace_values) |
1242
|
|
|
|
|
|
|
|
1243
|
15235
|
|
|
|
|
68272
|
push @evaluation_stack, \$result; |
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
} ## end when (Marpa::PP::Internal::Op::CALL) |
1246
|
|
|
|
|
|
|
|
1247
|
0
|
|
|
|
|
0
|
default { |
1248
|
0
|
|
|
|
|
0
|
Marpa::PP::exception("Unknown evaluator Op: $_"); |
1249
|
|
|
|
|
|
|
} |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
} ## end given |
1252
|
|
|
|
|
|
|
} ## end while ( $op_ix < scalar @{$ops} ) |
1253
|
|
|
|
|
|
|
|
1254
|
|
|
|
|
|
|
} # TREE_NODE |
1255
|
|
|
|
|
|
|
|
1256
|
2222
|
|
|
|
|
36492
|
return pop @evaluation_stack; |
1257
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Internal::Recognizer::evaluate |
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
# null parse is special case |
1260
|
|
|
|
|
|
|
sub Marpa::PP::Internal::Recognizer::do_null_parse { |
1261
|
18
|
|
|
18
|
|
35
|
my ( $recce, $start_rule ) = @_; |
1262
|
|
|
|
|
|
|
|
1263
|
18
|
|
|
|
|
37
|
my $start_symbol = $start_rule->[Marpa::PP::Internal::Rule::LHS]; |
1264
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
# Cannot increment the null parse |
1266
|
18
|
50
|
|
|
|
60
|
return if $recce->[Marpa::PP::Internal::Recognizer::PARSE_COUNT]++; |
1267
|
18
|
|
|
|
|
35
|
my $null_values = $recce->[Marpa::PP::Internal::Recognizer::NULL_VALUES]; |
1268
|
18
|
|
|
|
|
42
|
my $evaluator_rules = |
1269
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::EVALUATOR_RULES]; |
1270
|
|
|
|
|
|
|
|
1271
|
18
|
|
|
|
|
32
|
my $start_symbol_id = $start_symbol->[Marpa::PP::Internal::Symbol::ID]; |
1272
|
18
|
|
|
|
|
30
|
my $start_rule_id = $start_rule->[Marpa::PP::Internal::Rule::ID]; |
1273
|
|
|
|
|
|
|
|
1274
|
18
|
|
|
|
|
38
|
my $and_node = []; |
1275
|
18
|
|
|
|
|
59
|
$#{$and_node} = Marpa::PP::Internal::And_Node::LAST_FIELD; |
|
18
|
|
|
|
|
82
|
|
1276
|
18
|
|
|
|
|
54
|
$and_node->[Marpa::PP::Internal::And_Node::VALUE_REF] = |
1277
|
|
|
|
|
|
|
\( $null_values->[$start_symbol_id] ); |
1278
|
18
|
|
|
|
|
48
|
$and_node->[Marpa::PP::Internal::And_Node::RULE_ID] = |
1279
|
|
|
|
|
|
|
$start_rule->[Marpa::PP::Internal::Rule::ID]; |
1280
|
18
|
|
|
|
|
1155
|
$and_node->[Marpa::PP::Internal::And_Node::VALUE_OPS] = |
1281
|
|
|
|
|
|
|
$evaluator_rules->[$start_rule_id]; |
1282
|
|
|
|
|
|
|
|
1283
|
18
|
|
|
|
|
47
|
$and_node->[Marpa::PP::Internal::And_Node::POSITION] = 0; |
1284
|
18
|
|
|
|
|
37
|
$and_node->[Marpa::PP::Internal::And_Node::START_EARLEME] = 0; |
1285
|
18
|
|
|
|
|
35
|
$and_node->[Marpa::PP::Internal::And_Node::CAUSE_EARLEME] = 0; |
1286
|
18
|
|
|
|
|
34
|
$and_node->[Marpa::PP::Internal::And_Node::END_EARLEME] = 0; |
1287
|
18
|
|
|
|
|
36
|
$and_node->[Marpa::PP::Internal::And_Node::ID] = 0; |
1288
|
18
|
|
|
|
|
45
|
my $symbol_name = $start_symbol->[Marpa::PP::Internal::Symbol::NAME]; |
1289
|
18
|
|
|
|
|
36
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_NAME] = $symbol_name; |
1290
|
18
|
|
|
|
|
74
|
$and_node->[Marpa::PP::Internal::And_Node::TAG] = |
1291
|
|
|
|
|
|
|
Marpa::PP::Recognizer::and_node_tag( $recce, $and_node ); |
1292
|
|
|
|
|
|
|
|
1293
|
18
|
|
|
|
|
51
|
$recce->[Marpa::PP::Internal::Recognizer::AND_NODES]->[0] = $and_node; |
1294
|
|
|
|
|
|
|
|
1295
|
18
|
|
|
|
|
129
|
return Marpa::PP::Internal::Recognizer::evaluate( $recce, [$and_node] ); |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Internal::Recognizer::do_null_parse |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
# Returns false if no parse |
1300
|
|
|
|
|
|
|
sub Marpa::PP::Recognizer::value { |
1301
|
2313
|
|
|
2313
|
1
|
110219
|
my ( $recce, @arg_hashes ) = @_; |
1302
|
|
|
|
|
|
|
|
1303
|
2313
|
|
|
|
|
7647
|
my $parse_set_arg = $recce->[Marpa::PP::Internal::Recognizer::END]; |
1304
|
|
|
|
|
|
|
|
1305
|
2313
|
|
|
|
|
21625
|
my $trace_tasks = $recce->[Marpa::PP::Internal::Recognizer::TRACE_TASKS]; |
1306
|
2313
|
|
|
|
|
7447
|
local $Marpa::PP::Internal::TRACE_FH = |
1307
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_FILE_HANDLE]; |
1308
|
|
|
|
|
|
|
|
1309
|
2313
|
|
|
|
|
5164
|
my $and_nodes = $recce->[Marpa::PP::Internal::Recognizer::AND_NODES]; |
1310
|
2313
|
|
|
|
|
5518
|
my $or_nodes = $recce->[Marpa::PP::Internal::Recognizer::OR_NODES]; |
1311
|
2313
|
|
|
|
|
4493
|
my $ranking_method = |
1312
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::RANKING_METHOD]; |
1313
|
|
|
|
|
|
|
|
1314
|
2313
|
50
|
|
|
|
11904
|
if ( $recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE] ) { |
1315
|
0
|
|
|
|
|
0
|
Marpa::PP::exception( |
1316
|
|
|
|
|
|
|
qq{Arguments were passed directly to value() in a previous call\n}, |
1317
|
|
|
|
|
|
|
qq{Only one call to value() is allowed per recognizer when arguments are passed directly\n}, |
1318
|
|
|
|
|
|
|
qq{This is the second call to value()\n} |
1319
|
|
|
|
|
|
|
); |
1320
|
|
|
|
|
|
|
} ## end if ( $recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE...]) |
1321
|
|
|
|
|
|
|
|
1322
|
2313
|
|
|
|
|
8636
|
my $parse_count = $recce->[Marpa::PP::Internal::Recognizer::PARSE_COUNT]; |
1323
|
2313
|
|
|
|
|
3689
|
my $max_parses = $recce->[Marpa::PP::Internal::Recognizer::MAX_PARSES]; |
1324
|
2313
|
50
|
66
|
|
|
37506
|
if ( $max_parses and $parse_count > $max_parses ) { |
1325
|
0
|
|
|
|
|
0
|
Marpa::PP::exception("Maximum parse count ($max_parses) exceeded"); |
1326
|
|
|
|
|
|
|
} |
1327
|
|
|
|
|
|
|
|
1328
|
2313
|
|
|
|
|
6390
|
for my $arg_hash (@arg_hashes) { |
1329
|
|
|
|
|
|
|
|
1330
|
7
|
50
|
|
|
|
38
|
if ( exists $arg_hash->{end} ) { |
1331
|
0
|
0
|
|
|
|
0
|
if ($parse_count) { |
1332
|
0
|
|
|
|
|
0
|
Marpa::PP::exception( |
1333
|
|
|
|
|
|
|
q{Cannot change "end" after first parse result}); |
1334
|
|
|
|
|
|
|
} |
1335
|
0
|
|
|
|
|
0
|
$recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE] = 1; |
1336
|
0
|
|
|
|
|
0
|
$parse_set_arg = $arg_hash->{end}; |
1337
|
0
|
|
|
|
|
0
|
delete $arg_hash->{end}; |
1338
|
|
|
|
|
|
|
} ## end if ( exists $arg_hash->{end} ) |
1339
|
|
|
|
|
|
|
|
1340
|
7
|
50
|
|
|
|
30
|
if ( exists $arg_hash->{closures} ) { |
1341
|
0
|
0
|
|
|
|
0
|
if ($parse_count) { |
1342
|
0
|
|
|
|
|
0
|
Marpa::PP::exception( |
1343
|
|
|
|
|
|
|
q{Cannot change "closures" after first parse result}); |
1344
|
|
|
|
|
|
|
} |
1345
|
0
|
|
|
|
|
0
|
$recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE] = 1; |
1346
|
0
|
|
|
|
|
0
|
my $closures = $arg_hash->{closures}; |
1347
|
0
|
|
|
|
|
0
|
while ( my ( $action, $closure ) = each %{$closures} ) { |
|
0
|
|
|
|
|
0
|
|
1348
|
0
|
0
|
|
|
|
0
|
Marpa::PP::exception(qq{Bad closure for action "$action"}) |
1349
|
|
|
|
|
|
|
if ref $closure ne 'CODE'; |
1350
|
|
|
|
|
|
|
} |
1351
|
0
|
|
|
|
|
0
|
$recce->[Marpa::PP::Internal::Recognizer::CLOSURES] = $closures; |
1352
|
0
|
|
|
|
|
0
|
delete $arg_hash->{closures}; |
1353
|
|
|
|
|
|
|
} ## end if ( exists $arg_hash->{closures} ) |
1354
|
|
|
|
|
|
|
|
1355
|
7
|
50
|
|
|
|
34
|
if ( exists $arg_hash->{trace_actions} ) { |
1356
|
0
|
|
|
|
|
0
|
$recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE] = 1; |
1357
|
0
|
|
|
|
|
0
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_ACTIONS] = |
1358
|
|
|
|
|
|
|
$arg_hash->{trace_actions}; |
1359
|
0
|
|
|
|
|
0
|
delete $arg_hash->{trace_actions}; |
1360
|
|
|
|
|
|
|
} ## end if ( exists $arg_hash->{trace_actions} ) |
1361
|
|
|
|
|
|
|
|
1362
|
7
|
100
|
|
|
|
44
|
if ( exists $arg_hash->{trace_values} ) { |
1363
|
2
|
|
|
|
|
6
|
$recce->[Marpa::PP::Internal::Recognizer::SINGLE_PARSE_MODE] = 1; |
1364
|
2
|
|
|
|
|
5
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_VALUES] = |
1365
|
|
|
|
|
|
|
$arg_hash->{trace_values}; |
1366
|
2
|
|
|
|
|
7
|
delete $arg_hash->{trace_values}; |
1367
|
|
|
|
|
|
|
} ## end if ( exists $arg_hash->{trace_values} ) |
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
# A typo made its way into the documentation, so now it's a |
1370
|
|
|
|
|
|
|
# synonym. |
1371
|
7
|
|
|
|
|
22
|
for my $trace_fh_alias (qw(trace_fh trace_file_handle)) { |
1372
|
14
|
100
|
|
|
|
66
|
if ( exists $arg_hash->{$trace_fh_alias} ) { |
1373
|
2
|
|
|
|
|
7
|
$recce->[Marpa::PP::Internal::Recognizer::TRACE_FILE_HANDLE] = |
1374
|
|
|
|
|
|
|
$Marpa::PP::Internal::TRACE_FH = |
1375
|
|
|
|
|
|
|
$arg_hash->{$trace_fh_alias}; |
1376
|
2
|
|
|
|
|
6
|
delete $arg_hash->{$trace_fh_alias}; |
1377
|
|
|
|
|
|
|
} ## end if ( exists $arg_hash->{$trace_fh_alias} ) |
1378
|
|
|
|
|
|
|
} ## end for my $trace_fh_alias (qw(trace_fh trace_file_handle)) |
1379
|
|
|
|
|
|
|
|
1380
|
7
|
|
|
|
|
21
|
my @unknown_arg_names = keys %{$arg_hash}; |
|
7
|
|
|
|
|
25
|
|
1381
|
7
|
50
|
|
|
|
48
|
Marpa::PP::exception( |
1382
|
|
|
|
|
|
|
'Unknown named argument(s) to Marpa::PP::Recognizer::value: ', |
1383
|
|
|
|
|
|
|
( join q{ }, @unknown_arg_names ) ) |
1384
|
|
|
|
|
|
|
if @unknown_arg_names; |
1385
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
} ## end for my $arg_hash (@arg_hashes) |
1387
|
|
|
|
|
|
|
|
1388
|
2313
|
|
|
|
|
4316
|
my $grammar = $recce->[Marpa::PP::Internal::Recognizer::GRAMMAR]; |
1389
|
2313
|
|
|
|
|
5195
|
my $earley_sets = $recce->[Marpa::PP::Internal::Recognizer::EARLEY_SETS]; |
1390
|
|
|
|
|
|
|
|
1391
|
2313
|
|
|
|
|
15824
|
my $furthest_earleme = |
1392
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::FURTHEST_EARLEME]; |
1393
|
2313
|
|
|
|
|
4649
|
my $last_completed_earleme = |
1394
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::LAST_COMPLETED_EARLEME]; |
1395
|
2313
|
50
|
|
|
|
15653
|
Marpa::PP::exception( |
1396
|
|
|
|
|
|
|
"Attempt to evaluate incompletely recognized parse:\n", |
1397
|
|
|
|
|
|
|
" Last token ends at location $furthest_earleme\n", |
1398
|
|
|
|
|
|
|
" Recognition done only as far as location $last_completed_earleme\n" |
1399
|
|
|
|
|
|
|
) if $furthest_earleme > $last_completed_earleme; |
1400
|
|
|
|
|
|
|
|
1401
|
2313
|
|
|
|
|
8381
|
my $rules = $grammar->[Marpa::PP::Internal::Grammar::RULES]; |
1402
|
2313
|
|
|
|
|
5677
|
my $symbols = $grammar->[Marpa::PP::Internal::Grammar::SYMBOLS]; |
1403
|
|
|
|
|
|
|
|
1404
|
2313
|
|
100
|
|
|
9716
|
my $current_parse_set = $parse_set_arg |
1405
|
|
|
|
|
|
|
// $recce->[Marpa::PP::Internal::Recognizer::FURTHEST_EARLEME]; |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
# Look for the start item and start rule |
1408
|
2313
|
|
|
|
|
5282
|
my $earley_set = $earley_sets->[$current_parse_set]; |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
# Perhaps this call should be moved. |
1411
|
|
|
|
|
|
|
# The null values are currently a function of the grammar, |
1412
|
|
|
|
|
|
|
# and should be constant for the life of a recognizer. |
1413
|
2313
|
|
66
|
|
|
10187
|
my $null_values = |
1414
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::NULL_VALUES] //= |
1415
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::set_null_values($recce); |
1416
|
|
|
|
|
|
|
|
1417
|
2313
|
|
|
|
|
5306
|
my @task_list; |
1418
|
|
|
|
|
|
|
my $start_item; |
1419
|
0
|
|
|
|
|
0
|
my $start_rule; |
1420
|
2313
|
100
|
|
|
|
6111
|
if ($parse_count) { |
1421
|
2078
|
|
|
|
|
8216
|
@task_list = ( [Marpa::PP::Internal::Task::ITERATE] ); |
1422
|
|
|
|
|
|
|
} |
1423
|
|
|
|
|
|
|
else { |
1424
|
235
|
|
|
|
|
436
|
my $start_state; |
1425
|
|
|
|
|
|
|
|
1426
|
235
|
|
|
|
|
5127
|
EARLEY_ITEM: |
1427
|
235
|
|
|
|
|
358
|
for my $item ( |
1428
|
|
|
|
|
|
|
@{ $earley_set->[Marpa::PP::Internal::Earley_Set::ITEMS] } ) |
1429
|
|
|
|
|
|
|
{ |
1430
|
1521
|
|
|
|
|
2160
|
$start_state = $item->[Marpa::PP::Internal::Earley_Item::STATE]; |
1431
|
1521
|
|
|
|
|
2078
|
$start_rule = |
1432
|
|
|
|
|
|
|
$start_state->[Marpa::PP::Internal::AHFA::START_RULE]; |
1433
|
1521
|
100
|
|
|
|
3987
|
next EARLEY_ITEM if not $start_rule; |
1434
|
235
|
|
|
|
|
385
|
$start_item = $item; |
1435
|
235
|
|
|
|
|
596
|
last EARLEY_ITEM; |
1436
|
|
|
|
|
|
|
} ## end for my $item ( @{ $earley_set->[...]}) |
1437
|
|
|
|
|
|
|
|
1438
|
235
|
50
|
|
|
|
750
|
return if not $start_rule; |
1439
|
|
|
|
|
|
|
|
1440
|
235
|
|
|
|
|
890
|
$recce->[Marpa::PP::Internal::Recognizer::EVALUATOR_RULES] = |
1441
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::set_actions($recce); |
1442
|
|
|
|
|
|
|
|
1443
|
235
|
100
|
|
|
|
6744
|
return Marpa::PP::Internal::Recognizer::do_null_parse( $recce, |
1444
|
|
|
|
|
|
|
$start_rule ) |
1445
|
|
|
|
|
|
|
if $start_rule->[Marpa::PP::Internal::Rule::LHS] |
1446
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Symbol::NULLING]; |
1447
|
|
|
|
|
|
|
|
1448
|
217
|
|
|
|
|
557
|
@task_list = (); |
1449
|
217
|
|
|
|
|
646
|
push @task_list, [Marpa::PP::Internal::Task::INITIALIZE]; |
1450
|
|
|
|
|
|
|
} ## end else [ if ($parse_count) ] |
1451
|
|
|
|
|
|
|
|
1452
|
2295
|
|
|
|
|
8838
|
$recce->[Marpa::PP::Internal::Recognizer::PARSE_COUNT]++; |
1453
|
|
|
|
|
|
|
|
1454
|
2295
|
|
|
|
|
4614
|
my $evaluator_rules = |
1455
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::EVALUATOR_RULES]; |
1456
|
2295
|
|
|
|
|
3454
|
my $iteration_stack = |
1457
|
|
|
|
|
|
|
$recce->[Marpa::PP::Internal::Recognizer::ITERATION_STACK]; |
1458
|
|
|
|
|
|
|
|
1459
|
2295
|
|
|
|
|
3094
|
my $iteration_node_worklist; |
1460
|
2295
|
|
|
|
|
4225
|
my @and_node_in_use = (); |
1461
|
2295
|
|
|
|
|
8572
|
for my $iteration_node ( @{$iteration_stack} ) { |
|
2295
|
|
|
|
|
6211
|
|
1462
|
44524
|
|
|
|
|
73661
|
my $choices = |
1463
|
|
|
|
|
|
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
1464
|
44524
|
|
|
|
|
71483
|
my $choice = $choices->[0]; |
1465
|
44524
|
|
|
|
|
76078
|
my $and_node = $choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
1466
|
44524
|
|
|
|
|
85084
|
my $and_node_id = $and_node->[Marpa::PP::Internal::And_Node::ID]; |
1467
|
44524
|
|
|
|
|
132035
|
$and_node_in_use[$and_node_id] = 1; |
1468
|
|
|
|
|
|
|
} ## end for my $iteration_node ( @{$iteration_stack} ) |
1469
|
|
|
|
|
|
|
|
1470
|
2295
|
|
|
|
|
41430
|
TASK: while ( my $task = pop @task_list ) { |
1471
|
|
|
|
|
|
|
|
1472
|
103961
|
|
|
|
|
188109
|
my ( $task_type, @task_data ) = @{$task}; |
|
103961
|
|
|
|
|
272870
|
|
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
# Create the unpopulated top or-node |
1475
|
103961
|
100
|
|
|
|
287872
|
if ( $task_type == Marpa::PP::Internal::Task::INITIALIZE ) { |
1476
|
|
|
|
|
|
|
|
1477
|
217
|
50
|
|
|
|
843
|
if ($trace_tasks) { |
1478
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1479
|
|
|
|
|
|
|
'Task: INITIALIZE; ', |
1480
|
|
|
|
|
|
|
( scalar @task_list ), " tasks pending\n" |
1481
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1482
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
1483
|
|
|
|
|
|
|
|
1484
|
217
|
|
|
|
|
621
|
my $start_rule_id = $start_rule->[Marpa::PP::Internal::Rule::ID]; |
1485
|
|
|
|
|
|
|
|
1486
|
217
|
|
|
|
|
517
|
my $start_or_node = []; |
1487
|
217
|
|
|
|
|
605
|
$start_or_node->[Marpa::PP::Internal::Or_Node::ID] = 0; |
1488
|
217
|
|
|
|
|
422
|
$start_or_node->[Marpa::PP::Internal::Or_Node::ITEM] = |
1489
|
|
|
|
|
|
|
$start_item; |
1490
|
217
|
|
|
|
|
422
|
$start_or_node->[Marpa::PP::Internal::Or_Node::RULE_ID] = |
1491
|
|
|
|
|
|
|
$start_rule_id; |
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
# Start or-node cannot cycle |
1494
|
217
|
|
|
|
|
741
|
$start_or_node->[Marpa::PP::Internal::Or_Node::CYCLE] = 0; |
1495
|
217
|
|
|
|
|
746
|
$start_or_node->[Marpa::PP::Internal::Or_Node::POSITION] = |
1496
|
217
|
|
|
|
|
352
|
scalar @{ $start_rule->[Marpa::PP::Internal::Rule::RHS] }; |
1497
|
|
|
|
|
|
|
{ |
1498
|
217
|
|
|
|
|
352
|
my $start_or_node_tag = |
|
217
|
|
|
|
|
1034
|
|
1499
|
|
|
|
|
|
|
$start_or_node->[Marpa::PP::Internal::Or_Node::TAG] = |
1500
|
|
|
|
|
|
|
Marpa::PP::Recognizer::or_node_tag( $recce, |
1501
|
|
|
|
|
|
|
$start_or_node ); |
1502
|
217
|
|
|
|
|
939
|
$recce->[Marpa::PP::Internal::Recognizer::OR_NODE_HASH] |
1503
|
|
|
|
|
|
|
->{$start_or_node_tag} = $start_or_node; |
1504
|
|
|
|
|
|
|
} |
1505
|
|
|
|
|
|
|
|
1506
|
|
|
|
|
|
|
# Zero out the evaluation |
1507
|
217
|
|
|
|
|
377
|
$#{$and_nodes} = -1; |
|
217
|
|
|
|
|
930
|
|
1508
|
217
|
|
|
|
|
498
|
$#{$or_nodes} = -1; |
|
217
|
|
|
|
|
587
|
|
1509
|
217
|
|
|
|
|
336
|
$#{$iteration_stack} = -1; |
|
217
|
|
|
|
|
639
|
|
1510
|
217
|
|
|
|
|
531
|
$#and_node_in_use = -1; |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
# Populate the start or-node |
1513
|
217
|
|
|
|
|
513
|
$or_nodes->[0] = $start_or_node; |
1514
|
|
|
|
|
|
|
|
1515
|
217
|
|
|
|
|
479
|
my $start_iteration_node = []; |
1516
|
217
|
|
|
|
|
511
|
$start_iteration_node |
1517
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::OR_NODE] = |
1518
|
|
|
|
|
|
|
$start_or_node; |
1519
|
|
|
|
|
|
|
|
1520
|
217
|
|
|
|
|
424
|
@task_list = (); |
1521
|
217
|
|
|
|
|
807
|
push @task_list, [Marpa::PP::Internal::Task::FIX_TREE], |
1522
|
|
|
|
|
|
|
[ |
1523
|
|
|
|
|
|
|
Marpa::PP::Internal::Task::STACK_INODE, |
1524
|
|
|
|
|
|
|
$start_iteration_node |
1525
|
|
|
|
|
|
|
]; |
1526
|
|
|
|
|
|
|
|
1527
|
217
|
100
|
|
|
|
790
|
if ( $ranking_method eq 'constant' ) { |
1528
|
22
|
|
|
|
|
54
|
push @task_list, [Marpa::PP::Internal::Task::RANK_ALL],; |
1529
|
|
|
|
|
|
|
} |
1530
|
|
|
|
|
|
|
|
1531
|
217
|
|
|
|
|
992
|
push @task_list, |
1532
|
|
|
|
|
|
|
[ |
1533
|
|
|
|
|
|
|
Marpa::PP::Internal::Task::POPULATE_DEPTH, 0, |
1534
|
|
|
|
|
|
|
[$start_or_node] |
1535
|
|
|
|
|
|
|
], |
1536
|
|
|
|
|
|
|
[ |
1537
|
|
|
|
|
|
|
Marpa::PP::Internal::Task::POPULATE_OR_NODE, |
1538
|
|
|
|
|
|
|
$start_or_node |
1539
|
|
|
|
|
|
|
]; |
1540
|
|
|
|
|
|
|
|
1541
|
217
|
|
|
|
|
1023
|
next TASK; |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
} ## end if ( $task_type == Marpa::PP::Internal::Task::INITIALIZE) |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
# Special processing for the top iteration node |
1546
|
103744
|
100
|
|
|
|
266016
|
if ( $task_type == Marpa::PP::Internal::Task::ITERATE ) { |
1547
|
|
|
|
|
|
|
|
1548
|
2089
|
50
|
|
|
|
10440
|
if ($trace_tasks) { |
1549
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1550
|
|
|
|
|
|
|
'Task: ITERATE; ', |
1551
|
|
|
|
|
|
|
( scalar @task_list ), " tasks pending\n" |
1552
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1553
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
1554
|
|
|
|
|
|
|
|
1555
|
2089
|
|
|
|
|
4124
|
$iteration_node_worklist = undef; |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
# In this pass, we go up the iteration stack, |
1558
|
|
|
|
|
|
|
# looking a node which we can iterate. |
1559
|
2089
|
|
|
|
|
4443
|
my $iteration_node; |
1560
|
34464
|
|
|
|
|
127412
|
ITERATION_NODE: |
1561
|
2089
|
|
|
|
|
4529
|
while ( $iteration_node = pop @{$iteration_stack} ) { |
1562
|
|
|
|
|
|
|
|
1563
|
34379
|
|
|
|
|
100690
|
my $choices = $iteration_node |
1564
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
# Eliminate the current choice |
1567
|
34379
|
|
|
|
|
56904
|
my $choice = $choices->[0]; |
1568
|
34379
|
|
|
|
|
61372
|
my $and_node = |
1569
|
|
|
|
|
|
|
$choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
1570
|
34379
|
|
|
|
|
61363
|
my $and_node_id = |
1571
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::ID]; |
1572
|
34379
|
|
|
|
|
77329
|
$and_node_in_use[$and_node_id] = undef; |
1573
|
34379
|
|
|
|
|
48062
|
shift @{$choices}; |
|
34379
|
|
|
|
|
74394
|
|
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
# Throw away choices until we find one that does not cycle |
1576
|
34379
|
|
|
|
|
67470
|
CHOICE: while ( scalar @{$choices} ) { |
|
34388
|
|
|
|
|
91951
|
|
1577
|
2013
|
|
|
|
|
5461
|
$choice = $choices->[0]; |
1578
|
2013
|
|
|
|
|
4324
|
$and_node = |
1579
|
|
|
|
|
|
|
$choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
1580
|
2013
|
|
|
|
|
3575
|
$and_node_id = |
1581
|
|
|
|
|
|
|
$and_node->[Marpa::PP::Internal::And_Node::ID]; |
1582
|
2013
|
100
|
|
|
|
6013
|
last CHOICE if not $and_node_in_use[$and_node_id]; |
1583
|
9
|
|
|
|
|
17
|
shift @{$choices}; |
|
9
|
|
|
|
|
21
|
|
1584
|
|
|
|
|
|
|
} ## end while ( scalar @{$choices} ) |
1585
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
# Climb the parent links, marking the ranks |
1587
|
|
|
|
|
|
|
# of the nodes "dirty", until we hit one this is |
1588
|
|
|
|
|
|
|
# already dirty |
1589
|
34379
|
|
|
|
|
89305
|
my $direct_parent = $iteration_node |
1590
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::PARENT]; |
1591
|
|
|
|
|
|
|
PARENT: |
1592
|
34379
|
|
|
|
|
99495
|
for ( my $parent = $direct_parent; defined $parent; ) { |
1593
|
59957
|
|
|
|
|
118579
|
my $parent_node = $iteration_stack->[$parent]; |
1594
|
|
|
|
|
|
|
last PARENT |
1595
|
59957
|
100
|
|
|
|
200883
|
if not $parent_node |
1596
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CLEAN]; |
1597
|
27778
|
|
|
|
|
44936
|
$parent_node->[Marpa::PP::Internal::Iteration_Node::CLEAN] |
1598
|
|
|
|
|
|
|
= 0; |
1599
|
27778
|
|
|
|
|
67327
|
$parent = $parent_node |
1600
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::PARENT]; |
1601
|
|
|
|
|
|
|
} ## end for ( my $parent = $direct_parent; defined $parent; ) |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
# This or-node is already populated, |
1604
|
|
|
|
|
|
|
# or it would not have been put |
1605
|
|
|
|
|
|
|
# onto the iteration stack |
1606
|
34379
|
|
|
|
|
67859
|
$choices = $iteration_node |
1607
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
1608
|
|
|
|
|
|
|
|
1609
|
34379
|
100
|
|
|
|
43005
|
if ( not scalar @{$choices} ) { |
|
34379
|
|
|
|
|
95125
|
|
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
# For the node just popped off the stack |
1612
|
|
|
|
|
|
|
# unset the pointer to it in its parent |
1613
|
32375
|
100
|
|
|
|
86111
|
if ( defined $direct_parent ) { |
1614
|
|
|
|
|
|
|
|
1615
|
|
|
|
|
|
|
#<<< cycles on perltidy version 20090616 |
1616
|
32302
|
|
|
|
|
57106
|
my $child_type = $iteration_node->[ |
1617
|
|
|
|
|
|
|
Marpa::PP::Internal::Iteration_Node::CHILD_TYPE ]; |
1618
|
|
|
|
|
|
|
#>>> |
1619
|
|
|
|
|
|
|
# |
1620
|
32302
|
100
|
|
|
|
87598
|
$iteration_stack->[$direct_parent]->[ |
1621
|
|
|
|
|
|
|
$child_type |
1622
|
|
|
|
|
|
|
== Marpa::PP::Internal::And_Node::PREDECESSOR_ID |
1623
|
|
|
|
|
|
|
? Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX |
1624
|
|
|
|
|
|
|
: Marpa::PP::Internal::Iteration_Node::CAUSE_IX |
1625
|
|
|
|
|
|
|
] |
1626
|
|
|
|
|
|
|
= undef; |
1627
|
|
|
|
|
|
|
} ## end if ( defined $direct_parent ) |
1628
|
32375
|
|
|
|
|
143750
|
next ITERATION_NODE; |
1629
|
|
|
|
|
|
|
} ## end if ( not scalar @{$choices} ) |
1630
|
|
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
# Dirty the iteration node and put it back |
1632
|
|
|
|
|
|
|
# on the stack |
1633
|
|
|
|
|
|
|
$iteration_node |
1634
|
2004
|
|
|
|
|
3824
|
->[Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX] = |
1635
|
|
|
|
|
|
|
undef; |
1636
|
2004
|
|
|
|
|
3116
|
$iteration_node |
1637
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CAUSE_IX] = undef; |
1638
|
2004
|
|
|
|
|
3124
|
$iteration_node->[Marpa::PP::Internal::Iteration_Node::CLEAN] |
1639
|
|
|
|
|
|
|
= 0; |
1640
|
2004
|
|
|
|
|
5864
|
push @{$iteration_stack}, $iteration_node; |
|
2004
|
|
|
|
|
4178
|
|
1641
|
|
|
|
|
|
|
|
1642
|
2004
|
|
|
|
|
15284
|
$choice = $choices->[0]; |
1643
|
2004
|
|
|
|
|
3459
|
$and_node = $choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
1644
|
2004
|
|
|
|
|
3195
|
$and_node_id = $and_node->[Marpa::PP::Internal::And_Node::ID]; |
1645
|
2004
|
|
|
|
|
3160
|
$and_node_in_use[$and_node_id] = 1; |
1646
|
|
|
|
|
|
|
|
1647
|
2004
|
|
|
|
|
4235
|
last ITERATION_NODE; |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
} ## end while ( $iteration_node = pop @{$iteration_stack} ) |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
# If we hit the top of the stack without finding any node |
1652
|
|
|
|
|
|
|
# to iterate, that is it for parsing. |
1653
|
2089
|
100
|
|
|
|
6647
|
return if not defined $iteration_node; |
1654
|
|
|
|
|
|
|
|
1655
|
2004
|
|
|
|
|
7413
|
push @task_list, [Marpa::PP::Internal::Task::FIX_TREE]; |
1656
|
|
|
|
|
|
|
|
1657
|
2004
|
|
|
|
|
9683
|
next TASK; |
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
} ## end if ( $task_type == Marpa::PP::Internal::Task::ITERATE) |
1660
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
# This task is set up to rerun itself until explicitly exited |
1662
|
|
|
|
|
|
|
FIX_TREE_LOOP: |
1663
|
101655
|
|
|
|
|
279611
|
while ( $task_type == Marpa::PP::Internal::Task::FIX_TREE ) { |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
# If the work list is undefined, initialize it to the entire stack |
1666
|
96703
|
|
100
|
|
|
285807
|
$iteration_node_worklist //= [ 0 .. $#{$iteration_stack} ]; |
|
2217
|
|
|
|
|
14623
|
|
1667
|
96703
|
100
|
|
|
|
147877
|
next TASK if not scalar @{$iteration_node_worklist}; |
|
96703
|
|
|
|
|
320858
|
|
1668
|
94493
|
|
|
|
|
212147
|
my $working_node_ix = $iteration_node_worklist->[-1]; |
1669
|
|
|
|
|
|
|
|
1670
|
94493
|
50
|
|
|
|
231530
|
if ($trace_tasks) { |
1671
|
0
|
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1672
|
|
|
|
|
|
|
q{Task: FIX_TREE; }, |
1673
|
0
|
0
|
|
|
|
0
|
( scalar @{$iteration_node_worklist} ), |
1674
|
|
|
|
|
|
|
" current iteration node #$working_node_ix; ", |
1675
|
|
|
|
|
|
|
( scalar @task_list ), " tasks pending\n" |
1676
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1677
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
1678
|
|
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
# We are done fixing the tree is the worklist is empty |
1680
|
|
|
|
|
|
|
|
1681
|
94493
|
|
|
|
|
175996
|
my $working_node = $iteration_stack->[$working_node_ix]; |
1682
|
94493
|
|
|
|
|
151980
|
my $choices = |
1683
|
|
|
|
|
|
|
$working_node->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
1684
|
94493
|
|
|
|
|
193458
|
my $choice = $choices->[0]; |
1685
|
94493
|
|
|
|
|
144567
|
my $working_and_node = |
1686
|
|
|
|
|
|
|
$choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
1687
|
|
|
|
|
|
|
|
1688
|
|
|
|
|
|
|
FIELD: |
1689
|
94493
|
|
|
|
|
220782
|
for my $field ( Marpa::PP::Internal::Iteration_Node::CAUSE_IX, |
1690
|
|
|
|
|
|
|
Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX |
1691
|
|
|
|
|
|
|
) |
1692
|
|
|
|
|
|
|
{ |
1693
|
168302
|
|
|
|
|
281026
|
my $ix = $working_node->[$field]; |
1694
|
168302
|
100
|
|
|
|
570935
|
next FIELD if defined $ix; |
1695
|
94389
|
100
|
|
|
|
224623
|
my $and_node_field = |
1696
|
|
|
|
|
|
|
$field |
1697
|
|
|
|
|
|
|
== Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX |
1698
|
|
|
|
|
|
|
? Marpa::PP::Internal::And_Node::PREDECESSOR_ID |
1699
|
|
|
|
|
|
|
: Marpa::PP::Internal::And_Node::CAUSE_ID; |
1700
|
|
|
|
|
|
|
|
1701
|
94389
|
|
|
|
|
187434
|
my $or_node_id = $working_and_node->[$and_node_field]; |
1702
|
94389
|
100
|
|
|
|
231218
|
if ( not defined $or_node_id ) { |
1703
|
53341
|
|
|
|
|
117283
|
$working_node->[$field] = -999_999_999; |
1704
|
53341
|
|
|
|
|
185607
|
next FIELD; |
1705
|
|
|
|
|
|
|
} |
1706
|
|
|
|
|
|
|
|
1707
|
41048
|
|
|
|
|
107119
|
my $new_iteration_node = []; |
1708
|
41048
|
|
|
|
|
99423
|
$new_iteration_node |
1709
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::OR_NODE] = |
1710
|
|
|
|
|
|
|
$or_nodes->[$or_node_id]; |
1711
|
41048
|
|
|
|
|
83272
|
$new_iteration_node |
1712
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::PARENT] = |
1713
|
|
|
|
|
|
|
$working_node_ix; |
1714
|
41048
|
|
|
|
|
81557
|
$new_iteration_node |
1715
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHILD_TYPE] = |
1716
|
|
|
|
|
|
|
$and_node_field; |
1717
|
|
|
|
|
|
|
|
1718
|
|
|
|
|
|
|
# Restack the current task, adding a task to create |
1719
|
|
|
|
|
|
|
# the child iteration node |
1720
|
41048
|
|
|
|
|
108837
|
push @task_list, $task, |
1721
|
|
|
|
|
|
|
[ |
1722
|
|
|
|
|
|
|
Marpa::PP::Internal::Task::STACK_INODE, |
1723
|
|
|
|
|
|
|
$new_iteration_node |
1724
|
|
|
|
|
|
|
]; |
1725
|
41048
|
|
|
|
|
210456
|
next TASK; |
1726
|
|
|
|
|
|
|
} ## end for my $field ( ...) |
1727
|
|
|
|
|
|
|
|
1728
|
53445
|
|
|
|
|
157749
|
$working_node->[Marpa::PP::Internal::Iteration_Node::CLEAN] = 1; |
1729
|
53445
|
|
|
|
|
64413
|
pop @{$iteration_node_worklist}; |
|
53445
|
|
|
|
|
100652
|
|
1730
|
53445
|
|
|
|
|
196015
|
next FIX_TREE_LOOP; |
1731
|
|
|
|
|
|
|
|
1732
|
|
|
|
|
|
|
} ## end while ( $task_type == Marpa::PP::Internal::Task::FIX_TREE) |
1733
|
|
|
|
|
|
|
|
1734
|
58397
|
100
|
|
|
|
149381
|
if ( $task_type == Marpa::PP::Internal::Task::POPULATE_OR_NODE ) { |
1735
|
|
|
|
|
|
|
|
1736
|
13140
|
|
|
|
|
48586
|
my $work_or_node = $task_data[0]; |
1737
|
|
|
|
|
|
|
|
1738
|
13140
|
50
|
|
|
|
24767
|
if ($trace_tasks) { |
1739
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
1740
|
|
|
|
|
|
|
'Task: POPULATE_OR_NODE o', |
1741
|
|
|
|
|
|
|
$work_or_node->[Marpa::PP::Internal::Or_Node::ID], |
1742
|
|
|
|
|
|
|
q{; }, ( scalar @task_list ), " tasks pending\n" |
1743
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
1744
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
1745
|
|
|
|
|
|
|
|
1746
|
13140
|
|
|
|
|
33305
|
my $work_node_name = |
1747
|
|
|
|
|
|
|
$work_or_node->[Marpa::PP::Internal::Or_Node::TAG]; |
1748
|
|
|
|
|
|
|
|
1749
|
|
|
|
|
|
|
# SET Should be the same for all items |
1750
|
13140
|
|
|
|
|
21300
|
my $or_node_item = |
1751
|
|
|
|
|
|
|
$work_or_node->[Marpa::PP::Internal::Or_Node::ITEM]; |
1752
|
|
|
|
|
|
|
|
1753
|
13140
|
|
|
|
|
30411
|
my $work_set = |
1754
|
|
|
|
|
|
|
$or_node_item->[Marpa::PP::Internal::Earley_Item::SET]; |
1755
|
13140
|
|
|
|
|
19910
|
my $work_node_origin = |
1756
|
|
|
|
|
|
|
$or_node_item->[Marpa::PP::Internal::Earley_Item::ORIGIN]; |
1757
|
|
|
|
|
|
|
|
1758
|
13140
|
|
|
|
|
18622
|
my $work_rule_id = |
1759
|
|
|
|
|
|
|
$work_or_node->[Marpa::PP::Internal::Or_Node::RULE_ID]; |
1760
|
13140
|
|
|
|
|
25948
|
my $work_rule = $rules->[$work_rule_id]; |
1761
|
13140
|
|
|
|
|
19197
|
my $work_position = |
1762
|
|
|
|
|
|
|
$work_or_node->[Marpa::PP::Internal::Or_Node::POSITION] - 1; |
1763
|
13140
|
|
|
|
|
26689
|
my $work_symbol = |
1764
|
|
|
|
|
|
|
$work_rule->[Marpa::PP::Internal::Rule::RHS] |
1765
|
|
|
|
|
|
|
->[$work_position]; |
1766
|
13140
|
|
|
|
|
28290
|
my $work_symbol_name = |
1767
|
|
|
|
|
|
|
$work_symbol->[Marpa::PP::Internal::Symbol::NAME]; |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
{ |
1770
|
|
|
|
|
|
|
|
1771
|
13140
|
|
|
|
|
16638
|
my $item = $or_node_item; |
|
13140
|
|
|
|
|
16200
|
|
1772
|
13140
|
|
|
|
|
17559
|
my $or_sapling_set = $work_set; |
1773
|
|
|
|
|
|
|
|
1774
|
13140
|
100
|
|
|
|
47233
|
my $leo_links = |
1775
|
|
|
|
|
|
|
defined |
1776
|
|
|
|
|
|
|
$item->[Marpa::PP::Internal::Earley_Item::IS_LEO_EXPANDED] |
1777
|
|
|
|
|
|
|
? [] |
1778
|
|
|
|
|
|
|
: $item->[Marpa::PP::Internal::Earley_Item::LEO_LINKS]; |
1779
|
13140
|
|
100
|
|
|
40314
|
$leo_links //= []; |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
# If this is a Leo completion, translate the Leo links |
1782
|
13140
|
|
|
|
|
15903
|
for my $leo_link ( @{$leo_links} ) { |
|
13140
|
|
|
|
|
54049
|
|
1783
|
|
|
|
|
|
|
|
1784
|
1255
|
|
|
|
|
2749
|
my ( $leo_item, $cause ) = @{$leo_link}; |
|
1255
|
|
|
|
|
4094
|
|
1785
|
|
|
|
|
|
|
|
1786
|
1255
|
|
|
|
|
2821
|
my $next_leo_item = $leo_item |
1787
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Leo_Item::PREDECESSOR]; |
1788
|
1255
|
|
|
|
|
2383
|
my $leo_symbol_name = $leo_item |
1789
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Leo_Item::LEO_POSTDOT_SYMBOL]; |
1790
|
1255
|
|
|
|
|
2149
|
my $leo_base_item = |
1791
|
|
|
|
|
|
|
$leo_item->[Marpa::PP::Internal::Leo_Item::BASE]; |
1792
|
|
|
|
|
|
|
|
1793
|
1255
|
|
|
|
|
14405
|
my $next_links = [ [ $leo_base_item, $cause, ] ]; |
1794
|
|
|
|
|
|
|
|
1795
|
1255
|
|
|
|
|
1651
|
LEO_ITEM: for ( ;; ) { |
1796
|
|
|
|
|
|
|
|
1797
|
2779
|
100
|
|
|
|
14683
|
if ( not $next_leo_item ) { |
1798
|
|
|
|
|
|
|
|
1799
|
|
|
|
|
|
|
# die join " ", __FILE__, __LINE__, "next link cnt", (scalar @{$next_links}) |
1800
|
|
|
|
|
|
|
# if scalar @{$next_links} != 1; |
1801
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
#<<< perltidy cycles as of version 20090616 |
1803
|
1255
|
|
|
|
|
3109
|
push @{ $item |
|
1255
|
|
|
|
|
2615
|
|
1804
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::LINKS |
1805
|
|
|
|
|
|
|
] }, |
1806
|
1255
|
|
|
|
|
1587
|
@{$next_links}; |
1807
|
|
|
|
|
|
|
#<<< |
1808
|
|
|
|
|
|
|
|
1809
|
|
|
|
|
|
|
# Now that the Leo links are translated, mark the |
1810
|
|
|
|
|
|
|
# Earley item accordingly |
1811
|
1255
|
|
|
|
|
2129
|
$item->[Marpa::PP::Internal::Earley_Item::IS_LEO_EXPANDED] = 1; |
1812
|
|
|
|
|
|
|
|
1813
|
1255
|
|
|
|
|
6962
|
last LEO_ITEM; |
1814
|
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
} ## end if ( not $next_leo_item ) |
1816
|
|
|
|
|
|
|
|
1817
|
1524
|
|
|
|
|
7018
|
my ( undef, $base_to_state ) = |
1818
|
1524
|
|
|
|
|
2832
|
@{ $leo_base_item |
1819
|
|
|
|
|
|
|
->[ Marpa::PP::Internal::Earley_Item::STATE ] |
1820
|
|
|
|
|
|
|
->[Marpa::PP::Internal::AHFA::TRANSITION] |
1821
|
|
|
|
|
|
|
->{$leo_symbol_name} }; |
1822
|
1524
|
|
|
|
|
3055
|
my $origin = $next_leo_item |
1823
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Leo_Item::SET]; |
1824
|
|
|
|
|
|
|
|
1825
|
1524
|
|
|
|
|
6631
|
my $name = sprintf |
1826
|
|
|
|
|
|
|
'S%d@%d-%d', |
1827
|
|
|
|
|
|
|
$base_to_state->[Marpa::PP::Internal::AHFA::ID], |
1828
|
|
|
|
|
|
|
$origin, |
1829
|
|
|
|
|
|
|
$or_sapling_set; |
1830
|
1524
|
|
|
|
|
3988
|
my $hash_key = join q{:}, |
1831
|
|
|
|
|
|
|
$base_to_state->[Marpa::PP::Internal::AHFA::ID], |
1832
|
|
|
|
|
|
|
$origin; |
1833
|
1524
|
|
|
|
|
4156
|
my $earley_hash = |
1834
|
|
|
|
|
|
|
$earley_sets->[$or_sapling_set] |
1835
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Set::HASH]; |
1836
|
|
|
|
|
|
|
|
1837
|
1524
|
|
|
|
|
3587
|
my $target_item = $earley_hash->{$hash_key}; |
1838
|
1524
|
100
|
|
|
|
4284
|
if ( not defined $target_item ) { |
1839
|
1306
|
|
|
|
|
2850
|
$target_item = []; |
1840
|
1306
|
|
|
|
|
5202
|
$target_item |
1841
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::ID] = |
1842
|
|
|
|
|
|
|
$recce->[ |
1843
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::NEXT_EARLEY_ITEM_ID |
1844
|
|
|
|
|
|
|
]++; |
1845
|
1306
|
|
|
|
|
4164
|
$target_item |
1846
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::ORIGIN] = |
1847
|
|
|
|
|
|
|
$origin; |
1848
|
1306
|
|
|
|
|
2019
|
$target_item |
1849
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::STATE] = |
1850
|
|
|
|
|
|
|
$base_to_state; |
1851
|
1306
|
|
|
|
|
4084
|
$target_item |
1852
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::LINKS] = |
1853
|
|
|
|
|
|
|
[]; |
1854
|
1306
|
|
|
|
|
5367
|
$target_item |
1855
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::SET] = |
1856
|
|
|
|
|
|
|
$or_sapling_set; |
1857
|
1306
|
|
|
|
|
4659
|
$earley_hash->{$hash_key} = $target_item; |
1858
|
1306
|
|
|
|
|
1858
|
push @{ $earley_sets->[$or_sapling_set] |
|
1306
|
|
|
|
|
3818
|
|
1859
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Set::ITEMS] |
1860
|
|
|
|
|
|
|
}, $target_item; |
1861
|
|
|
|
|
|
|
} ## end if ( not defined $target_item ) |
1862
|
|
|
|
|
|
|
|
1863
|
1524
|
|
|
|
|
2346
|
push @{ $target_item |
|
1524
|
|
|
|
|
3069
|
|
1864
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::LINKS] }, |
1865
|
1524
|
|
|
|
|
2371
|
@{$next_links}; |
1866
|
|
|
|
|
|
|
|
1867
|
1524
|
|
|
|
|
2096
|
$leo_item = $next_leo_item; |
1868
|
1524
|
|
|
|
|
2755
|
$next_leo_item = $leo_item |
1869
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Leo_Item::PREDECESSOR]; |
1870
|
1524
|
|
|
|
|
2196
|
$leo_base_item = |
1871
|
|
|
|
|
|
|
$leo_item->[Marpa::PP::Internal::Leo_Item::BASE]; |
1872
|
1524
|
|
|
|
|
5155
|
$leo_symbol_name = |
1873
|
|
|
|
|
|
|
$leo_item->[Marpa::PP::Internal::Leo_Item::LEO_POSTDOT_SYMBOL]; |
1874
|
|
|
|
|
|
|
|
1875
|
1524
|
|
|
|
|
9142
|
$next_links = [ [ $leo_base_item, $target_item, $leo_symbol_name ] ]; |
1876
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
} ## end for ( ;; ) |
1878
|
|
|
|
|
|
|
} ## end for my $leo_link ( @{$leo_links} ) |
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
} |
1881
|
|
|
|
|
|
|
|
1882
|
13140
|
|
|
|
|
21307
|
my @link_worklist; |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
CREATE_LINK_WORKLIST: { |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
# Several Earley items may be the source of the same or-node, |
1887
|
|
|
|
|
|
|
# but the or-node only keeps track of one. This is sufficient, |
1888
|
|
|
|
|
|
|
# because the Earley item is tracked by the or-node only for its |
1889
|
|
|
|
|
|
|
# links, and the links for every Earley item which is the source |
1890
|
|
|
|
|
|
|
# of the same or-node must be the same. There's more about this |
1891
|
|
|
|
|
|
|
# in the libmarpa docs. |
1892
|
|
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
# link worklist item is $predecessor, $cause, $token_name, $value_ref |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
# All predecessors apply to a |
1896
|
|
|
|
|
|
|
# nulling work symbol. |
1897
|
|
|
|
|
|
|
|
1898
|
13140
|
100
|
|
|
|
14001
|
if ( $work_symbol->[Marpa::PP::Internal::Symbol::NULLING] ) { |
|
13140
|
|
|
|
|
46939
|
|
1899
|
996
|
|
|
|
|
1754
|
my $nulling_symbol_id = |
1900
|
|
|
|
|
|
|
$work_symbol->[Marpa::PP::Internal::Symbol::ID]; |
1901
|
996
|
|
|
|
|
1705
|
my $value_ref = \$null_values->[$nulling_symbol_id]; |
1902
|
996
|
|
|
|
|
3385
|
@link_worklist = |
1903
|
|
|
|
|
|
|
[ $or_node_item, undef, $work_symbol_name, $value_ref ]; |
1904
|
996
|
|
|
|
|
2448
|
last CREATE_LINK_WORKLIST; |
1905
|
|
|
|
|
|
|
} ## end if ( $work_symbol->[...]) |
1906
|
|
|
|
|
|
|
|
1907
|
|
|
|
|
|
|
# Collect links for or node items |
1908
|
|
|
|
|
|
|
# into link work items |
1909
|
|
|
|
|
|
|
@link_worklist = |
1910
|
12144
|
|
|
|
|
13537
|
@{ $or_node_item->[Marpa::PP::Internal::Earley_Item::LINKS] }; |
|
12144
|
|
|
|
|
73087
|
|
1911
|
|
|
|
|
|
|
|
1912
|
|
|
|
|
|
|
} ## end CREATE_LINK_WORKLIST: |
1913
|
|
|
|
|
|
|
|
1914
|
|
|
|
|
|
|
# The and node data is put into the hash, only to be taken out immediately, |
1915
|
|
|
|
|
|
|
# but in the process the very important step of eliminating duplicates |
1916
|
|
|
|
|
|
|
# is accomplished. |
1917
|
13140
|
|
|
|
|
48797
|
my %and_node_data = (); |
1918
|
|
|
|
|
|
|
|
1919
|
13140
|
|
|
|
|
37505
|
LINK_WORK_ITEM: for my $link_work_item (@link_worklist) { |
1920
|
|
|
|
|
|
|
|
1921
|
14994
|
|
|
|
|
45962
|
my ( $predecessor, $cause, $symbol_name, $value_ref ) = |
1922
|
14994
|
|
|
|
|
20116
|
@{$link_work_item}; |
1923
|
|
|
|
|
|
|
|
1924
|
|
|
|
|
|
|
# next LINK_WORK_ITEM if $symbol_name ne $work_symbol_name; |
1925
|
|
|
|
|
|
|
|
1926
|
14994
|
|
|
|
|
22992
|
my $cause_earleme = $work_node_origin; |
1927
|
14994
|
|
|
|
|
18733
|
my $predecessor_id; |
1928
|
|
|
|
|
|
|
my $predecessor_name; |
1929
|
|
|
|
|
|
|
|
1930
|
14994
|
100
|
|
|
|
54852
|
if ( $work_position > 0 ) { |
1931
|
|
|
|
|
|
|
|
1932
|
4597
|
|
|
|
|
8105
|
$cause_earleme = |
1933
|
|
|
|
|
|
|
$predecessor->[Marpa::PP::Internal::Earley_Item::SET]; |
1934
|
|
|
|
|
|
|
|
1935
|
4597
|
|
|
|
|
27216
|
$predecessor_name = |
1936
|
|
|
|
|
|
|
"R$work_rule_id:$work_position" . q{@} |
1937
|
|
|
|
|
|
|
. $predecessor |
1938
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Earley_Item::ORIGIN] . q{-} |
1939
|
|
|
|
|
|
|
. $cause_earleme; |
1940
|
|
|
|
|
|
|
|
1941
|
4597
|
|
|
|
|
17066
|
FIND_PREDECESSOR: { |
1942
|
4597
|
|
|
|
|
5238
|
my $predecessor_or_node = |
1943
|
|
|
|
|
|
|
$recce |
1944
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Recognizer::OR_NODE_HASH] |
1945
|
|
|
|
|
|
|
->{$predecessor_name}; |
1946
|
4597
|
100
|
|
|
|
10184
|
if ($predecessor_or_node) { |
1947
|
1084
|
|
|
|
|
1515
|
$predecessor_id = $predecessor_or_node |
1948
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::ID]; |
1949
|
|
|
|
|
|
|
|
1950
|
1084
|
|
|
|
|
2039
|
last FIND_PREDECESSOR; |
1951
|
|
|
|
|
|
|
|
1952
|
|
|
|
|
|
|
} ## end if ($predecessor_or_node) |
1953
|
|
|
|
|
|
|
|
1954
|
3513
|
|
|
|
|
5559
|
$predecessor_or_node = []; |
1955
|
3513
|
|
|
|
|
8061
|
$predecessor_or_node |
1956
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::TAG] = |
1957
|
|
|
|
|
|
|
$predecessor_name; |
1958
|
3513
|
|
|
|
|
10207
|
$recce |
1959
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Recognizer::OR_NODE_HASH] |
1960
|
|
|
|
|
|
|
->{$predecessor_name} = $predecessor_or_node; |
1961
|
3513
|
|
|
|
|
6269
|
$predecessor_or_node |
1962
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::RULE_ID] = |
1963
|
|
|
|
|
|
|
$work_rule_id; |
1964
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
# nulling nodes are never part of cycles |
1966
|
|
|
|
|
|
|
# thanks to the CHAF rewrite |
1967
|
3513
|
|
100
|
|
|
13460
|
$predecessor_or_node |
1968
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::CYCLE] = |
1969
|
|
|
|
|
|
|
$work_rule |
1970
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Rule::VIRTUAL_CYCLE] |
1971
|
|
|
|
|
|
|
&& $cause_earleme != $work_node_origin; |
1972
|
3513
|
|
|
|
|
7053
|
$predecessor_or_node |
1973
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::POSITION] = |
1974
|
|
|
|
|
|
|
$work_position; |
1975
|
3513
|
|
|
|
|
4741
|
$predecessor_or_node |
1976
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::ITEM] = |
1977
|
|
|
|
|
|
|
$predecessor; |
1978
|
3513
|
|
|
|
|
7689
|
$predecessor_id = |
1979
|
3513
|
|
|
|
|
3899
|
( push @{$or_nodes}, $predecessor_or_node ) - 1; |
1980
|
|
|
|
|
|
|
|
1981
|
3513
|
50
|
|
|
|
8401
|
Marpa::PP::exception( |
1982
|
|
|
|
|
|
|
"Too many or-nodes for evaluator: $predecessor_id" |
1983
|
|
|
|
|
|
|
) |
1984
|
|
|
|
|
|
|
if $predecessor_id |
1985
|
|
|
|
|
|
|
& ~(Marpa::PP::Internal::N_FORMAT_MAX); |
1986
|
3513
|
|
|
|
|
11391
|
$predecessor_or_node |
1987
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::ID] = |
1988
|
|
|
|
|
|
|
$predecessor_id; |
1989
|
|
|
|
|
|
|
|
1990
|
|
|
|
|
|
|
} ## end FIND_PREDECESSOR: |
1991
|
|
|
|
|
|
|
|
1992
|
|
|
|
|
|
|
} ## end if ( $work_position > 0 ) |
1993
|
|
|
|
|
|
|
|
1994
|
14994
|
|
|
|
|
16745
|
my $cause_id; |
1995
|
|
|
|
|
|
|
|
1996
|
14994
|
100
|
|
|
|
54806
|
if ( defined $cause ) { |
1997
|
|
|
|
|
|
|
|
1998
|
11536
|
|
|
|
|
20362
|
my $cause_symbol_id = |
1999
|
|
|
|
|
|
|
$work_symbol->[Marpa::PP::Internal::Symbol::ID]; |
2000
|
|
|
|
|
|
|
|
2001
|
11536
|
|
|
|
|
25253
|
my $state = |
2002
|
|
|
|
|
|
|
$cause->[Marpa::PP::Internal::Earley_Item::STATE]; |
2003
|
|
|
|
|
|
|
|
2004
|
11536
|
|
|
|
|
13996
|
for my $cause_rule ( |
|
11536
|
|
|
|
|
36692
|
|
2005
|
|
|
|
|
|
|
@{ $state |
2006
|
|
|
|
|
|
|
->[Marpa::PP::Internal::AHFA::COMPLETE_RULES] |
2007
|
|
|
|
|
|
|
->[$cause_symbol_id] |
2008
|
|
|
|
|
|
|
} |
2009
|
|
|
|
|
|
|
) |
2010
|
|
|
|
|
|
|
{ |
2011
|
|
|
|
|
|
|
|
2012
|
11596
|
|
|
|
|
21219
|
my $cause_rule_id = |
2013
|
|
|
|
|
|
|
$cause_rule->[Marpa::PP::Internal::Rule::ID]; |
2014
|
|
|
|
|
|
|
|
2015
|
11596
|
|
|
|
|
59756
|
my $cause_name = |
2016
|
|
|
|
|
|
|
"R$cause_rule_id:" |
2017
|
11596
|
|
|
|
|
22854
|
. (scalar @{ $cause_rule->[Marpa::PP::Internal::Rule::RHS] }) |
2018
|
|
|
|
|
|
|
. q{@} |
2019
|
|
|
|
|
|
|
. $cause->[Marpa::PP::Internal::Earley_Item::ORIGIN] |
2020
|
|
|
|
|
|
|
. q{-} |
2021
|
|
|
|
|
|
|
. $cause->[Marpa::PP::Internal::Earley_Item::SET]; |
2022
|
|
|
|
|
|
|
|
2023
|
11596
|
|
|
|
|
30828
|
FIND_CAUSE: { |
2024
|
11596
|
|
|
|
|
15915
|
my $cause_or_node = |
2025
|
|
|
|
|
|
|
$recce->[ |
2026
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::OR_NODE_HASH] |
2027
|
|
|
|
|
|
|
->{$cause_name}; |
2028
|
11596
|
100
|
|
|
|
65896
|
if ($cause_or_node) { |
2029
|
2186
|
|
|
|
|
3161
|
$cause_id = $cause_or_node |
2030
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::ID]; |
2031
|
2186
|
|
|
|
|
4321
|
last FIND_CAUSE; |
2032
|
|
|
|
|
|
|
} ## end if ($cause_or_node) |
2033
|
|
|
|
|
|
|
|
2034
|
9410
|
|
|
|
|
19425
|
$cause_or_node = []; |
2035
|
9410
|
|
|
|
|
28415
|
$cause_or_node |
2036
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::TAG] = |
2037
|
|
|
|
|
|
|
$cause_name; |
2038
|
9410
|
|
|
|
|
34687
|
$recce->[ |
2039
|
|
|
|
|
|
|
Marpa::PP::Internal::Recognizer::OR_NODE_HASH] |
2040
|
|
|
|
|
|
|
->{$cause_name} = $cause_or_node; |
2041
|
9410
|
|
|
|
|
19459
|
$cause_or_node |
2042
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::RULE_ID] = |
2043
|
|
|
|
|
|
|
$cause_rule_id; |
2044
|
|
|
|
|
|
|
|
2045
|
|
|
|
|
|
|
# nulling nodes are never part of cycles |
2046
|
|
|
|
|
|
|
# thanks to the CHAF rewrite |
2047
|
9410
|
|
66
|
|
|
35208
|
$cause_or_node |
2048
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::CYCLE] = |
2049
|
|
|
|
|
|
|
$cause_rule |
2050
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Rule::VIRTUAL_CYCLE] |
2051
|
|
|
|
|
|
|
&& $cause_earleme != $work_set; |
2052
|
9410
|
|
|
|
|
33543
|
$cause_or_node |
2053
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::POSITION] = |
2054
|
9410
|
|
|
|
|
17023
|
scalar @{ $cause_rule |
2055
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Rule::RHS] }; |
2056
|
9410
|
|
|
|
|
17220
|
$cause_or_node ->[Marpa::PP::Internal::Or_Node::ITEM] = |
2057
|
|
|
|
|
|
|
$cause; |
2058
|
9410
|
|
|
|
|
23805
|
$cause_id = |
2059
|
9410
|
|
|
|
|
10341
|
( push @{$or_nodes}, $cause_or_node ) - 1; |
2060
|
|
|
|
|
|
|
|
2061
|
9410
|
50
|
|
|
|
25015
|
Marpa::PP::exception( |
2062
|
|
|
|
|
|
|
"Too many or-nodes for evaluator: $cause_id") |
2063
|
|
|
|
|
|
|
if $cause_id |
2064
|
|
|
|
|
|
|
& ~(Marpa::PP::Internal::N_FORMAT_MAX); |
2065
|
9410
|
|
|
|
|
19730
|
$cause_or_node->[Marpa::PP::Internal::Or_Node::ID] |
2066
|
|
|
|
|
|
|
= $cause_id; |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
} ## end FIND_CAUSE: |
2069
|
|
|
|
|
|
|
|
2070
|
11596
|
|
|
|
|
32751
|
my $and_node = []; |
2071
|
|
|
|
|
|
|
#<<< cycles in perltidy as of 5 Jul 2010 |
2072
|
11596
|
|
|
|
|
30615
|
$and_node |
2073
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::PREDECESSOR_ID |
2074
|
|
|
|
|
|
|
] = $predecessor_id; |
2075
|
|
|
|
|
|
|
#>>> |
2076
|
11596
|
|
|
|
|
35467
|
$and_node |
2077
|
|
|
|
|
|
|
->[Marpa::PP::Internal::And_Node::CAUSE_EARLEME] = |
2078
|
|
|
|
|
|
|
$cause_earleme; |
2079
|
11596
|
|
|
|
|
35651
|
$and_node->[Marpa::PP::Internal::And_Node::CAUSE_ID] = |
2080
|
|
|
|
|
|
|
$cause_id; |
2081
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
$and_node_data{ |
2083
|
11596
|
|
100
|
|
|
141222
|
join q{:}, |
2084
|
|
|
|
|
|
|
( $predecessor_id // q{} ), |
2085
|
|
|
|
|
|
|
$cause_id |
2086
|
|
|
|
|
|
|
} |
2087
|
|
|
|
|
|
|
= $and_node; |
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
} ## end for |
2090
|
|
|
|
|
|
|
|
2091
|
11536
|
|
|
|
|
44686
|
next LINK_WORK_ITEM; |
2092
|
|
|
|
|
|
|
|
2093
|
|
|
|
|
|
|
} # if cause |
2094
|
|
|
|
|
|
|
|
2095
|
3458
|
|
|
|
|
5859
|
my $and_node = []; |
2096
|
3458
|
|
|
|
|
13719
|
$and_node->[Marpa::PP::Internal::And_Node::PREDECESSOR_ID] = |
2097
|
|
|
|
|
|
|
$predecessor_id; |
2098
|
3458
|
|
|
|
|
16734
|
$and_node->[Marpa::PP::Internal::And_Node::CAUSE_EARLEME] = |
2099
|
|
|
|
|
|
|
$cause_earleme; |
2100
|
3458
|
|
|
|
|
7289
|
$and_node->[Marpa::PP::Internal::And_Node::TOKEN_NAME] = |
2101
|
|
|
|
|
|
|
$symbol_name; |
2102
|
3458
|
|
|
|
|
4798
|
$and_node->[Marpa::PP::Internal::And_Node::VALUE_REF] = |
2103
|
|
|
|
|
|
|
$value_ref; |
2104
|
|
|
|
|
|
|
|
2105
|
|
|
|
|
|
|
$and_node_data{ |
2106
|
3458
|
|
100
|
|
|
27077
|
join q{:}, ( $predecessor_id // q{} ), |
2107
|
|
|
|
|
|
|
q{}, $symbol_name |
2108
|
|
|
|
|
|
|
} |
2109
|
|
|
|
|
|
|
= $and_node; |
2110
|
|
|
|
|
|
|
|
2111
|
|
|
|
|
|
|
} ## end for |
2112
|
|
|
|
|
|
|
|
2113
|
14025
|
|
|
|
|
52783
|
my @child_and_nodes = |
2114
|
13140
|
|
|
|
|
40707
|
map { $and_node_data{$_} } sort keys %and_node_data; |
2115
|
|
|
|
|
|
|
|
2116
|
13140
|
|
|
|
|
32773
|
for my $and_node (@child_and_nodes) { |
2117
|
|
|
|
|
|
|
|
2118
|
14025
|
|
|
|
|
31387
|
$and_node->[Marpa::PP::Internal::And_Node::RULE_ID] = |
2119
|
|
|
|
|
|
|
$work_rule_id; |
2120
|
|
|
|
|
|
|
|
2121
|
14025
|
|
|
|
|
84488
|
$and_node->[Marpa::PP::Internal::And_Node::VALUE_OPS] = |
2122
|
|
|
|
|
|
|
$work_position |
2123
|
14025
|
100
|
|
|
|
24986
|
== $#{ $work_rule->[Marpa::PP::Internal::Rule::RHS] } |
2124
|
|
|
|
|
|
|
? $evaluator_rules |
2125
|
|
|
|
|
|
|
->[ $work_rule->[Marpa::PP::Internal::Rule::ID] ] |
2126
|
|
|
|
|
|
|
: undef; |
2127
|
|
|
|
|
|
|
|
2128
|
14025
|
|
|
|
|
42685
|
$and_node->[Marpa::PP::Internal::And_Node::POSITION] = |
2129
|
|
|
|
|
|
|
$work_position; |
2130
|
14025
|
|
|
|
|
27759
|
$and_node->[Marpa::PP::Internal::And_Node::START_EARLEME] = |
2131
|
|
|
|
|
|
|
$work_node_origin; |
2132
|
14025
|
|
|
|
|
25367
|
$and_node->[Marpa::PP::Internal::And_Node::END_EARLEME] = |
2133
|
|
|
|
|
|
|
$work_set; |
2134
|
14025
|
|
|
|
|
21344
|
my $id = ( push @{$and_nodes}, $and_node ) - 1; |
|
14025
|
|
|
|
|
34445
|
|
2135
|
14025
|
50
|
|
|
|
41433
|
Marpa::PP::exception("Too many and-nodes for evaluator: $id") |
2136
|
|
|
|
|
|
|
if $id & ~(Marpa::PP::Internal::N_FORMAT_MAX); |
2137
|
14025
|
|
|
|
|
22561
|
$and_node->[Marpa::PP::Internal::And_Node::ID] = $id; |
2138
|
14025
|
|
|
|
|
49461
|
$and_node->[Marpa::PP::Internal::And_Node::TAG] = |
2139
|
|
|
|
|
|
|
Marpa::PP::Recognizer::and_node_tag( $recce, $and_node ); |
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
} ## end for my $and_node (@child_and_nodes) |
2142
|
|
|
|
|
|
|
|
2143
|
|
|
|
|
|
|
# Populate the or-node, now that we have ID's for all the and-nodes |
2144
|
14025
|
|
|
|
|
84365
|
$work_or_node->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS] = |
2145
|
13140
|
|
|
|
|
44557
|
[ map { $_->[Marpa::PP::Internal::And_Node::ID] } |
2146
|
|
|
|
|
|
|
@child_and_nodes ]; |
2147
|
|
|
|
|
|
|
|
2148
|
13140
|
|
|
|
|
102398
|
next TASK; |
2149
|
|
|
|
|
|
|
} ## end if ( $task_type == ...) |
2150
|
|
|
|
|
|
|
|
2151
|
45257
|
100
|
|
|
|
118450
|
if ( $task_type == Marpa::PP::Internal::Task::STACK_INODE ) { |
2152
|
|
|
|
|
|
|
|
2153
|
41271
|
|
|
|
|
62295
|
my $work_iteration_node = $task_data[0]; |
2154
|
41271
|
|
|
|
|
85059
|
my $or_node = $work_iteration_node |
2155
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::OR_NODE]; |
2156
|
|
|
|
|
|
|
|
2157
|
41271
|
50
|
|
|
|
90226
|
if ($trace_tasks) { |
2158
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
2159
|
|
|
|
|
|
|
'Task: STACK_INODE o', |
2160
|
|
|
|
|
|
|
$or_node->[Marpa::PP::Internal::Or_Node::ID], |
2161
|
|
|
|
|
|
|
q{; }, ( scalar @task_list ), " tasks pending\n" |
2162
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
2163
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
2164
|
|
|
|
|
|
|
|
2165
|
41271
|
|
|
|
|
92281
|
my $and_node_ids = |
2166
|
|
|
|
|
|
|
$or_node->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS]; |
2167
|
|
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
# If the or-node is not populated, |
2169
|
|
|
|
|
|
|
# restack this task, and stack a task to populate the |
2170
|
|
|
|
|
|
|
# or-node on top of it. |
2171
|
41271
|
50
|
|
|
|
114252
|
if ( not defined $and_node_ids ) { |
2172
|
0
|
|
|
|
|
0
|
push @task_list, $task, |
2173
|
|
|
|
|
|
|
[ Marpa::PP::Internal::Task::POPULATE_OR_NODE, $or_node ]; |
2174
|
0
|
|
|
|
|
0
|
next TASK; |
2175
|
|
|
|
|
|
|
} |
2176
|
|
|
|
|
|
|
|
2177
|
41271
|
|
|
|
|
68064
|
my $choices = $work_iteration_node |
2178
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHOICES]; |
2179
|
|
|
|
|
|
|
|
2180
|
|
|
|
|
|
|
# At this point we know the iteration node is populated, so if we don't |
2181
|
|
|
|
|
|
|
# have the choices list initialized, we can do so now. |
2182
|
41271
|
100
|
|
|
|
115894
|
if ( not defined $choices ) { |
2183
|
|
|
|
|
|
|
|
2184
|
41265
|
100
|
|
|
|
105784
|
if ( $ranking_method eq 'constant' ) { |
2185
|
44
|
|
|
44
|
|
467713
|
no integer; |
|
44
|
|
|
|
|
160
|
|
|
44
|
|
|
|
|
391
|
|
2186
|
302
|
|
|
|
|
453
|
my @choices = (); |
2187
|
302
|
|
|
|
|
314
|
AND_NODE: for my $and_node_id ( @{$and_node_ids} ) { |
|
302
|
|
|
|
|
561
|
|
2188
|
356
|
|
|
|
|
508
|
my $and_node = $and_nodes->[$and_node_id]; |
2189
|
356
|
|
|
|
|
469
|
my $new_choice = []; |
2190
|
356
|
|
|
|
|
638
|
$new_choice->[Marpa::PP::Internal::Choice::AND_NODE] = |
2191
|
|
|
|
|
|
|
$and_node; |
2192
|
|
|
|
|
|
|
|
2193
|
|
|
|
|
|
|
#<<< cycles on perltidy 20090616 |
2194
|
356
|
|
|
|
|
473
|
my $rank_ref = $and_node->[ |
2195
|
|
|
|
|
|
|
Marpa::PP::Internal::And_Node::INITIAL_RANK_REF ]; |
2196
|
|
|
|
|
|
|
#>>> |
2197
|
356
|
50
|
|
|
|
687
|
die "Undefined rank for a$and_node_id" |
2198
|
|
|
|
|
|
|
if not defined $rank_ref; |
2199
|
356
|
100
|
|
|
|
750
|
next AND_NODE if not ref $rank_ref; |
2200
|
352
|
|
|
|
|
592
|
$new_choice->[Marpa::PP::Internal::Choice::RANK] = |
2201
|
352
|
|
|
|
|
354
|
${$rank_ref}; |
2202
|
352
|
|
|
|
|
968
|
push @choices, $new_choice; |
2203
|
|
|
|
|
|
|
} ## end for my $and_node_id ( @{$and_node_ids} ) |
2204
|
|
|
|
|
|
|
## no critic (BuiltinFunctions::ProhibitReverseSortBlock) |
2205
|
|
|
|
|
|
|
$choices = [ |
2206
|
54
|
|
|
|
|
242
|
sort { |
2207
|
302
|
|
|
|
|
963
|
$b->[Marpa::PP::Internal::Choice::RANK] |
2208
|
|
|
|
|
|
|
<=> $a->[Marpa::PP::Internal::Choice::RANK] |
2209
|
|
|
|
|
|
|
} @choices |
2210
|
|
|
|
|
|
|
]; |
2211
|
|
|
|
|
|
|
} ## end if ( $ranking_method eq 'constant' ) |
2212
|
|
|
|
|
|
|
else { |
2213
|
43006
|
|
|
|
|
265275
|
$choices = |
2214
|
40963
|
|
|
|
|
64795
|
[ map { [ $and_nodes->[$_], 0 ] } @{$and_node_ids} ]; |
|
40963
|
|
|
|
|
86999
|
|
2215
|
|
|
|
|
|
|
} |
2216
|
41265
|
|
|
|
|
102354
|
$work_iteration_node |
2217
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHOICES] = |
2218
|
|
|
|
|
|
|
$choices; |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
} ## end if ( not defined $choices ) |
2221
|
|
|
|
|
|
|
|
2222
|
|
|
|
|
|
|
# Due to skipping, even an initialized set of choices |
2223
|
|
|
|
|
|
|
# may be empty. If it is, throw away the stack and iterate. |
2224
|
41271
|
100
|
|
|
|
48007
|
if ( not scalar @{$choices} ) { |
|
41271
|
|
|
|
|
112689
|
|
2225
|
|
|
|
|
|
|
|
2226
|
4
|
|
|
|
|
14
|
@task_list = ( [Marpa::PP::Internal::Task::ITERATE] ); |
2227
|
4
|
|
|
|
|
20
|
next TASK; |
2228
|
|
|
|
|
|
|
} |
2229
|
|
|
|
|
|
|
|
2230
|
|
|
|
|
|
|
# Make our choice and set RANK |
2231
|
41267
|
|
|
|
|
81237
|
my $choice = $choices->[0]; |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
# Rank is left until later to be initialized |
2234
|
|
|
|
|
|
|
|
2235
|
41267
|
|
|
|
|
71580
|
my $and_node = $choice->[Marpa::PP::Internal::Choice::AND_NODE]; |
2236
|
41267
|
|
|
|
|
70752
|
my $and_node_id = $and_node->[Marpa::PP::Internal::And_Node::ID]; |
2237
|
41267
|
|
|
|
|
53209
|
my $next_iteration_stack_ix = scalar @{$iteration_stack}; |
|
41267
|
|
|
|
|
67112
|
|
2238
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
# Check if we are about to cycle. |
2240
|
41267
|
100
|
|
|
|
140291
|
if ( $and_node_in_use[$and_node_id] ) { |
2241
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
# If there is another choice, increment choice and restack |
2243
|
|
|
|
|
|
|
# this task ... |
2244
|
|
|
|
|
|
|
# |
2245
|
|
|
|
|
|
|
# This iteration node is not yet on the stack, so we |
2246
|
|
|
|
|
|
|
# don't need to do anything with the pointers. |
2247
|
13
|
100
|
|
|
|
27
|
if ( scalar @{$choices} > 1 ) { |
|
13
|
|
|
|
|
44
|
|
2248
|
6
|
|
|
|
|
10
|
shift @{$choices}; |
|
6
|
|
|
|
|
56
|
|
2249
|
6
|
|
|
|
|
18
|
push @task_list, $task; |
2250
|
6
|
|
|
|
|
28
|
next TASK; |
2251
|
|
|
|
|
|
|
} |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
# Otherwise, throw away all pending tasks and |
2254
|
|
|
|
|
|
|
# iterate |
2255
|
7
|
|
|
|
|
410
|
@task_list = ( [Marpa::PP::Internal::Task::ITERATE] ); |
2256
|
7
|
|
|
|
|
43
|
next TASK; |
2257
|
|
|
|
|
|
|
} ## end if ( $and_node_in_use[$and_node_id] ) |
2258
|
41254
|
|
|
|
|
69491
|
$and_node_in_use[$and_node_id] = 1; |
2259
|
|
|
|
|
|
|
|
2260
|
|
|
|
|
|
|
# Tell the parent that the new iteration node is its child. |
2261
|
41254
|
100
|
|
|
|
125044
|
if (defined( |
2262
|
|
|
|
|
|
|
my $child_type = |
2263
|
|
|
|
|
|
|
$work_iteration_node |
2264
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::CHILD_TYPE] |
2265
|
|
|
|
|
|
|
) |
2266
|
|
|
|
|
|
|
) |
2267
|
|
|
|
|
|
|
{ |
2268
|
41041
|
|
|
|
|
79940
|
my $parent_ix = $work_iteration_node |
2269
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Iteration_Node::PARENT]; |
2270
|
41041
|
|
|
|
|
137450
|
$iteration_stack->[$parent_ix]->[ |
2271
|
|
|
|
|
|
|
$child_type |
2272
|
|
|
|
|
|
|
== Marpa::PP::Internal::And_Node::PREDECESSOR_ID |
2273
|
|
|
|
|
|
|
? Marpa::PP::Internal::Iteration_Node::PREDECESSOR_IX |
2274
|
|
|
|
|
|
|
: Marpa::PP::Internal::Iteration_Node::CAUSE_IX |
2275
|
|
|
|
|
|
|
] |
2276
|
41041
|
100
|
|
|
|
46842
|
= scalar @{$iteration_stack}; |
2277
|
|
|
|
|
|
|
} ## end if ( defined( my $child_type = $work_iteration_node->...)) |
2278
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
# If we are keeping an iteration node worklist, |
2280
|
|
|
|
|
|
|
# add this node to it. |
2281
|
41041
|
|
|
|
|
64336
|
defined $iteration_node_worklist |
2282
|
41041
|
|
|
|
|
97424
|
and push @{$iteration_node_worklist}, |
2283
|
41254
|
100
|
|
|
|
138695
|
scalar @{$iteration_stack}; |
2284
|
|
|
|
|
|
|
|
2285
|
41254
|
|
|
|
|
75035
|
push @{$iteration_stack}, $work_iteration_node; |
|
41254
|
|
|
|
|
85062
|
|
2286
|
|
|
|
|
|
|
|
2287
|
41254
|
|
|
|
|
294566
|
next TASK; |
2288
|
|
|
|
|
|
|
|
2289
|
|
|
|
|
|
|
} ## end if ( $task_type == Marpa::PP::Internal::Task::STACK_INODE) |
2290
|
|
|
|
|
|
|
|
2291
|
3986
|
100
|
|
|
|
7457
|
if ( $task_type == Marpa::PP::Internal::Task::RANK_ALL ) { |
2292
|
|
|
|
|
|
|
|
2293
|
22
|
50
|
|
|
|
68
|
if ($trace_tasks) { |
2294
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} 'Task: RANK_ALL; ', |
|
0
|
|
|
|
|
0
|
|
2295
|
|
|
|
|
|
|
( scalar @task_list ), " tasks pending\n" |
2296
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
2297
|
|
|
|
|
|
|
} |
2298
|
|
|
|
|
|
|
|
2299
|
22
|
|
|
|
|
89
|
do_rank_all($recce); |
2300
|
|
|
|
|
|
|
|
2301
|
22
|
|
|
|
|
208
|
next TASK; |
2302
|
|
|
|
|
|
|
} ## end if ( $task_type == Marpa::PP::Internal::Task::RANK_ALL) |
2303
|
|
|
|
|
|
|
|
2304
|
|
|
|
|
|
|
# This task is for pre-populating the entire and-node and or-node |
2305
|
|
|
|
|
|
|
# space one "depth level" at a time. It is used when ranking is |
2306
|
|
|
|
|
|
|
# being done, because to rank you need to make a pre-pass through |
2307
|
|
|
|
|
|
|
# the entire and-node and or-node space. |
2308
|
|
|
|
|
|
|
# |
2309
|
|
|
|
|
|
|
# As a side effect, depths are calculated for all the and-nodes. |
2310
|
3964
|
50
|
|
|
|
8739
|
if ( $task_type == Marpa::PP::Internal::Task::POPULATE_DEPTH ) { |
2311
|
3964
|
|
|
|
|
6314
|
my ( $depth, $or_node_list ) = @task_data; |
2312
|
|
|
|
|
|
|
|
2313
|
3964
|
50
|
|
|
|
9331
|
if ($trace_tasks) { |
2314
|
0
|
0
|
|
|
|
0
|
print {$Marpa::PP::Internal::TRACE_FH} |
|
0
|
|
|
|
|
0
|
|
2315
|
|
|
|
|
|
|
'Task: POPULATE_DEPTH; ', |
2316
|
|
|
|
|
|
|
( scalar @task_list ), " tasks pending\n" |
2317
|
|
|
|
|
|
|
or Marpa::PP::exception('print to trace handle failed'); |
2318
|
|
|
|
|
|
|
} ## end if ($trace_tasks) |
2319
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
# We can assume all or-nodes in the list are populated |
2321
|
|
|
|
|
|
|
|
2322
|
3964
|
|
|
|
|
6096
|
my %or_nodes_at_next_depth = (); |
2323
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
# Assign a depth to all the and-node children which |
2325
|
|
|
|
|
|
|
# do not already have one assigned. |
2326
|
3964
|
|
|
|
|
4827
|
for my $and_node_id ( |
|
13140
|
|
|
|
|
67885
|
|
2327
|
13140
|
|
|
|
|
13567
|
map { @{ $_->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS] } } |
|
3964
|
|
|
|
|
10389
|
|
2328
|
|
|
|
|
|
|
@{$or_node_list} ) |
2329
|
|
|
|
|
|
|
{ |
2330
|
14025
|
|
|
|
|
22252
|
my $and_node = $and_nodes->[$and_node_id]; |
2331
|
|
|
|
|
|
|
FIELD: |
2332
|
14025
|
|
|
|
|
24188
|
for my $field ( |
2333
|
|
|
|
|
|
|
Marpa::PP::Internal::And_Node::PREDECESSOR_ID, |
2334
|
|
|
|
|
|
|
Marpa::PP::Internal::And_Node::CAUSE_ID |
2335
|
|
|
|
|
|
|
) |
2336
|
|
|
|
|
|
|
{ |
2337
|
28050
|
|
|
|
|
54560
|
my $child_or_node_id = $and_node->[$field]; |
2338
|
28050
|
100
|
|
|
|
79415
|
next FIELD if not defined $child_or_node_id; |
2339
|
|
|
|
|
|
|
|
2340
|
14758
|
|
|
|
|
24213
|
my $next_depth_or_node = $or_nodes->[$child_or_node_id]; |
2341
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
# Push onto list only if child or-node |
2343
|
|
|
|
|
|
|
# is not already populated |
2344
|
14758
|
100
|
|
|
|
112378
|
$next_depth_or_node |
2345
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Or_Node::AND_NODE_IDS] |
2346
|
|
|
|
|
|
|
or $or_nodes_at_next_depth{$next_depth_or_node} = |
2347
|
|
|
|
|
|
|
$next_depth_or_node; |
2348
|
|
|
|
|
|
|
|
2349
|
|
|
|
|
|
|
} ## end for my $field ( ...) |
2350
|
|
|
|
|
|
|
|
2351
|
|
|
|
|
|
|
} ## end for my $and_node_id ( map { @{ $_->[...]}}) |
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
# No or-nodes at next depth? |
2354
|
|
|
|
|
|
|
# Great, we are done! |
2355
|
12923
|
|
|
|
|
32128
|
my @or_nodes_at_next_depth = |
2356
|
3964
|
|
|
|
|
19117
|
map { $or_nodes_at_next_depth{$_} } |
2357
|
|
|
|
|
|
|
sort keys %or_nodes_at_next_depth; |
2358
|
3964
|
100
|
|
|
|
15182
|
next TASK if not scalar @or_nodes_at_next_depth; |
2359
|
|
|
|
|
|
|
|
2360
|
12923
|
|
|
|
|
32946
|
push @task_list, |
2361
|
|
|
|
|
|
|
[ |
2362
|
|
|
|
|
|
|
Marpa::PP::Internal::Task::POPULATE_DEPTH, $depth + 1, |
2363
|
|
|
|
|
|
|
\@or_nodes_at_next_depth |
2364
|
|
|
|
|
|
|
], |
2365
|
3747
|
|
|
|
|
12466
|
map { [ Marpa::PP::Internal::Task::POPULATE_OR_NODE, $_ ] } |
2366
|
|
|
|
|
|
|
@or_nodes_at_next_depth; |
2367
|
|
|
|
|
|
|
|
2368
|
3747
|
|
|
|
|
33801
|
next TASK; |
2369
|
|
|
|
|
|
|
|
2370
|
|
|
|
|
|
|
} ## end if ( $task_type == Marpa::PP::Internal::Task::POPULATE_DEPTH) |
2371
|
|
|
|
|
|
|
|
2372
|
|
|
|
|
|
|
Marpa::PP::internal_error( |
2373
|
0
|
|
|
|
|
0
|
"Internal error: Unknown task type: $task_type"); |
2374
|
|
|
|
|
|
|
|
2375
|
|
|
|
|
|
|
} ## end while ( my $task = pop @task_list ) |
2376
|
|
|
|
|
|
|
|
2377
|
53403
|
|
|
|
|
131794
|
my @stack = map { |
2378
|
2210
|
|
|
|
|
8216
|
$_->[Marpa::PP::Internal::Iteration_Node::CHOICES]->[0] |
2379
|
|
|
|
|
|
|
->[Marpa::PP::Internal::Choice::AND_NODE] |
2380
|
2210
|
|
|
|
|
4480
|
} @{$iteration_stack}; |
2381
|
|
|
|
|
|
|
|
2382
|
2210
|
|
|
|
|
13601
|
return Marpa::PP::Internal::Recognizer::evaluate( $recce, \@stack ); |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Recognizer::value |
2385
|
|
|
|
|
|
|
|
2386
|
|
|
|
|
|
|
1; |