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