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::Perl; |
17
|
|
|
|
|
|
|
|
18
|
2
|
|
|
2
|
|
16347
|
use 5.010; |
|
2
|
|
|
|
|
10
|
|
|
2
|
|
|
|
|
122
|
|
19
|
2
|
|
|
2
|
|
13
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
77
|
|
20
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
128
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
package Marpa::PP::Internal::Perl; |
23
|
|
|
|
|
|
|
|
24
|
2
|
|
|
2
|
|
1462
|
use charnames ':full'; |
|
2
|
|
|
|
|
103560
|
|
|
2
|
|
|
|
|
16
|
|
25
|
2
|
|
|
2
|
|
524
|
use English qw( -no_match_vars ); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
18
|
|
26
|
|
|
|
|
|
|
|
27
|
2
|
|
|
2
|
|
2576
|
use Marpa::PP::Perl::Version; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
26541
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# This code is about Perl GRAMMAR. |
30
|
|
|
|
|
|
|
# If you're looking here |
31
|
|
|
|
|
|
|
# for a Perl SEMANTICS here, |
32
|
|
|
|
|
|
|
# you won't find one. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my $reference_grammar = <<'END_OF_GRAMMAR'; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# This is taken from perly.y for Perl 5.12.1 |
37
|
|
|
|
|
|
|
prog: prog ::= lineseq ; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# /* An ordinary block */ |
40
|
|
|
|
|
|
|
block: block ::= '{' lineseq '}' ; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
mblock ::= '{' lineseq '}' ; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# /* A collection of "lines" in the program */ |
45
|
|
|
|
|
|
|
lineseq_t: lineseq ::= ; |
46
|
|
|
|
|
|
|
lineseq__decl: lineseq ::= lineseq decl ; |
47
|
|
|
|
|
|
|
lineseq__line: lineseq ::= lineseq line ; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# /* A "line" in the program */ |
50
|
|
|
|
|
|
|
line ::= label cond ; |
51
|
|
|
|
|
|
|
line ::= loop ; # /* loops add their own labels */ |
52
|
|
|
|
|
|
|
line ::= switch ; # /* ... and so do switches */ |
53
|
|
|
|
|
|
|
line ::= label case ; |
54
|
|
|
|
|
|
|
line ::= label ';' ; |
55
|
|
|
|
|
|
|
line__sideff: line ::= label sideff ';' ; |
56
|
|
|
|
|
|
|
line ::= label PLUGSTMT ; |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
/* An expression which may have a side-effect */ |
59
|
|
|
|
|
|
|
sideff ::= error ; |
60
|
|
|
|
|
|
|
sideff: sideff ::= expr ; |
61
|
|
|
|
|
|
|
sideff ::= expr IF expr ; |
62
|
|
|
|
|
|
|
sideff ::= expr UNLESS expr ; |
63
|
|
|
|
|
|
|
sideff ::= expr WHILE expr ; |
64
|
|
|
|
|
|
|
sideff ::= expr UNTIL iexpr ; |
65
|
|
|
|
|
|
|
sideff ::= expr FOR expr ; |
66
|
|
|
|
|
|
|
sideff ::= expr WHEN expr ; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
/* else and elsif blocks */ |
69
|
|
|
|
|
|
|
else ::= ; /* NULL */ |
70
|
|
|
|
|
|
|
else ::= ELSE mblock ; |
71
|
|
|
|
|
|
|
else ::= ELSIF '(' mexpr ')' mblock else ; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
/* Real conditional expressions */ |
74
|
|
|
|
|
|
|
cond ::= IF '(' mexpr ')' mblock else ; |
75
|
|
|
|
|
|
|
cond ::= UNLESS '(' miexpr ')' mblock else ; |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
/* Cases for a switch statement */ |
78
|
|
|
|
|
|
|
case ::= WHEN '(' remember mexpr ')' mblock ; |
79
|
|
|
|
|
|
|
case ::= DEFAULT block ; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
/* Continue blocks */ |
82
|
|
|
|
|
|
|
cont ::= ; /* NULL */ |
83
|
|
|
|
|
|
|
cont ::= CONTINUE block ; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
/* Loops: while, until, for, and a bare block */ |
86
|
|
|
|
|
|
|
loop ::= label WHILE '(' remember texpr ')' mintro mblock cont ; |
87
|
|
|
|
|
|
|
loop ::= label UNTIL '(' remember iexpr ')' mintro mblock cont ; |
88
|
|
|
|
|
|
|
loop ::= label FOR MY remember my_scalar '(' mexpr ')' mblock cont ; |
89
|
|
|
|
|
|
|
loop ::= label FOR scalar '(' remember mexpr ')' mblock cont ; |
90
|
|
|
|
|
|
|
loop ::= label FOR '(' remember mexpr ')' mblock cont ; |
91
|
|
|
|
|
|
|
loop ::= label FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')' mblock ; |
92
|
|
|
|
|
|
|
/* basically fake up an initialize-while lineseq */ |
93
|
|
|
|
|
|
|
loop ::= label block cont ; /* a block is a loop that happens once */ |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
/* Switch blocks */ |
96
|
|
|
|
|
|
|
switch ::= label GIVEN '(' remember mydefsv mexpr ')' mblock ; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
/* determine whether there are any new my declarations */ |
99
|
|
|
|
|
|
|
mintro ::= ; /* NULL */ |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
/* Normal expression */ |
102
|
|
|
|
|
|
|
nexpr ::= ; |
103
|
|
|
|
|
|
|
nexpr ::= sideff ; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
/* Boolean expression */ |
106
|
|
|
|
|
|
|
texpr ::= ; /* NULL means true */ |
107
|
|
|
|
|
|
|
texpr ::= expr ; |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
/* Inverted boolean expression */ |
110
|
|
|
|
|
|
|
iexpr ::= expr ; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
/* Expression with its own lexical scope */ |
113
|
|
|
|
|
|
|
mexpr ::= expr ; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
mnexpr ::= nexpr ; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
miexpr ::= iexpr ; |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
/* Optional "MAIN:"-style loop labels */ |
120
|
|
|
|
|
|
|
label ::= ; /* empty */ |
121
|
|
|
|
|
|
|
label ::= LABEL ; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
/* Some kind of declaration - just hang on peg in the parse tree */ |
124
|
|
|
|
|
|
|
decl ::= format ; |
125
|
|
|
|
|
|
|
decl ::= subrout ; |
126
|
|
|
|
|
|
|
decl ::= mysubrout ; |
127
|
|
|
|
|
|
|
decl ::= package ; |
128
|
|
|
|
|
|
|
decl ::= use ; |
129
|
|
|
|
|
|
|
decl ::= peg ; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
peg ::= PEG ; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
format ::= FORMAT startformsub formname block ; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
formname ::= WORD ; |
136
|
|
|
|
|
|
|
formname ::= ; /* NULL */ |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
/* Unimplemented "my sub foo { }" */ |
139
|
|
|
|
|
|
|
mysubrout ::= MYSUB startsub subname proto subattrlist subbody ; |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
/* Subroutine definition */ |
142
|
|
|
|
|
|
|
subrout ::= SUB startsub subname proto subattrlist subbody ; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
startsub ::= ; /* NULL */ /* start a regular subroutine scope */ |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
startanonsub ::= ; /* NULL */ /* start an anonymous subroutine scope */ |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
startformsub ::= ; /* NULL */ /* start a format subroutine scope */ |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
/* Name of a subroutine - must be a bareword, could be special */ |
151
|
|
|
|
|
|
|
subname ::= WORD ; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
/* Subroutine prototype */ |
154
|
|
|
|
|
|
|
proto ::= ; /* NULL */ |
155
|
|
|
|
|
|
|
proto ::= THING ; |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
/* Optional list of subroutine attributes */ |
158
|
|
|
|
|
|
|
subattrlist ::= ; /* NULL */ |
159
|
|
|
|
|
|
|
subattrlist ::= COLONATTR THING ; |
160
|
|
|
|
|
|
|
subattrlist ::= COLONATTR ; |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
/* List of attributes for a "my" variable declaration */ |
163
|
|
|
|
|
|
|
myattrlist ::= COLONATTR THING ; |
164
|
|
|
|
|
|
|
myattrlist ::= COLONATTR ; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
/* Subroutine body - either null or a block */ |
167
|
|
|
|
|
|
|
subbody ::= block ; |
168
|
|
|
|
|
|
|
subbody ::= ';' ; |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
package ::= PACKAGE WORD WORD ';' ; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
use ::= USE startsub WORD WORD listexpr ';' ; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
/* Ordinary expressions; logical combinations */ |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
expr: expr ::= or_expr; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# %left OROP DOROP |
179
|
|
|
|
|
|
|
or_expr: or_expr ::= or_expr OROP and_expr ; |
180
|
|
|
|
|
|
|
or_expr__dor: or_expr ::= or_expr DOROP and_expr ; |
181
|
|
|
|
|
|
|
or_expr__t : or_expr ::= and_expr ; |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# %left ANDOP |
184
|
|
|
|
|
|
|
and_expr: and_expr ::= and_expr ANDOP argexpr ; |
185
|
|
|
|
|
|
|
and_expr__t: and_expr ::= argexpr ; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
/* Expressions are a list of terms joined by commas */ |
188
|
|
|
|
|
|
|
argexpr__comma: argexpr ::= argexpr ',' ; |
189
|
|
|
|
|
|
|
argexpr: argexpr ::= argexpr ',' term ; |
190
|
|
|
|
|
|
|
argexpr__t: argexpr ::= term ; |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
/* Names of methods. May use $object->$methodname */ |
193
|
|
|
|
|
|
|
method ::= METHOD ; |
194
|
|
|
|
|
|
|
method ::= scalar ; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# %nonassoc PREC_LOW |
198
|
|
|
|
|
|
|
# %nonassoc LOOPEX |
199
|
|
|
|
|
|
|
# %left OROP DOROP |
200
|
|
|
|
|
|
|
# %left ANDOP |
201
|
|
|
|
|
|
|
# %right NOTOP |
202
|
|
|
|
|
|
|
# %nonassoc LSTOP LSTOPSUB |
203
|
|
|
|
|
|
|
# %left ',' |
204
|
|
|
|
|
|
|
# %right ASSIGNOP |
205
|
|
|
|
|
|
|
# %right '?' ':' |
206
|
|
|
|
|
|
|
# %nonassoc DOTDOT YADAYADA |
207
|
|
|
|
|
|
|
# %left OROR DORDOR |
208
|
|
|
|
|
|
|
# %left ANDAND |
209
|
|
|
|
|
|
|
# %left BITOROP |
210
|
|
|
|
|
|
|
# %left BITANDOP |
211
|
|
|
|
|
|
|
# %nonassoc EQOP |
212
|
|
|
|
|
|
|
# %nonassoc RELOP |
213
|
|
|
|
|
|
|
# %nonassoc UNIOP UNIOPSUB |
214
|
|
|
|
|
|
|
# %nonassoc REQUIRE |
215
|
|
|
|
|
|
|
# %left SHIFTOP |
216
|
|
|
|
|
|
|
# %left ADDOP |
217
|
|
|
|
|
|
|
# %left MULOP |
218
|
|
|
|
|
|
|
# %left MATCHOP |
219
|
|
|
|
|
|
|
# %right '!' '~' UMINUS REFGEN |
220
|
|
|
|
|
|
|
# %right POWOP |
221
|
|
|
|
|
|
|
# %nonassoc PREINC PREDEC POSTINC POSTDEC |
222
|
|
|
|
|
|
|
# %left ARROW |
223
|
|
|
|
|
|
|
# %nonassoc ')' |
224
|
|
|
|
|
|
|
# %left '(' |
225
|
|
|
|
|
|
|
# %left '[' '{' |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# %nonassoc PREC_LOW |
228
|
|
|
|
|
|
|
# no terms |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# %nonassoc LOOPEX |
231
|
|
|
|
|
|
|
term__t: term ::= term_notop ; |
232
|
|
|
|
|
|
|
term ::= LOOPEX ; /* loop exiting command (goto, last, dump, etc) */ |
233
|
|
|
|
|
|
|
term ::= LOOPEX term_notop ; |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
# %left OROP DOROP |
236
|
|
|
|
|
|
|
# %left ANDOP |
237
|
|
|
|
|
|
|
# no terms, just expr's |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# %right NOTOP |
240
|
|
|
|
|
|
|
term_notop__t: term_notop ::= term_listop ; |
241
|
|
|
|
|
|
|
term_notop ::= NOTOP argexpr ; /* not $foo */ |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# %nonassoc LSTOP LSTOPSUB |
244
|
|
|
|
|
|
|
/* List operators */ |
245
|
|
|
|
|
|
|
term_listop__t: term_listop ::= term_assign ; |
246
|
|
|
|
|
|
|
term_listop ::= LSTOP indirob argexpr ; /* map {...} @args or print $fh @args */ |
247
|
|
|
|
|
|
|
term_lstop: term_listop ::= LSTOP listexpr ; /* print @args */ |
248
|
|
|
|
|
|
|
term_listop ::= LSTOPSUB startanonsub block listexpr ; |
249
|
|
|
|
|
|
|
term_listop ::= METHOD indirob listexpr ; /* new Class @args */ |
250
|
|
|
|
|
|
|
term_assign_lstop: term_listop ::= term_cond ASSIGNOP term_listop ; /* $x = bless $x, $y */ |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# /* sub f(&@); f { foo } ... */ /* ... @bar */ |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# %left ',' |
255
|
|
|
|
|
|
|
# no terms |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# %right ASSIGNOP |
258
|
|
|
|
|
|
|
/* Binary operators between terms */ |
259
|
|
|
|
|
|
|
term_assign__t: term_assign ::= term_cond ; |
260
|
|
|
|
|
|
|
# $x = $y |
261
|
|
|
|
|
|
|
term_assign: term_assign ::= term_cond ASSIGNOP term_assign ; |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
# %right '?' ':' |
264
|
|
|
|
|
|
|
term_cond__t: term_cond ::= term_dotdot ; |
265
|
|
|
|
|
|
|
term_cond: term_cond ::= term_dotdot '?' term_cond ':' term_cond ; |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# %nonassoc DOTDOT YADAYADA |
268
|
|
|
|
|
|
|
term_dotdot__t: term_dotdot ::= term_oror ; |
269
|
|
|
|
|
|
|
# $x..$y, $x...$y */ |
270
|
|
|
|
|
|
|
term_dotdot: term_dotdot ::= term_oror DOTDOT term_oror ; |
271
|
|
|
|
|
|
|
YADAYADA: term_dotdot ::= YADAYADA ; |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# %left OROR DORDOR |
274
|
|
|
|
|
|
|
term_oror__t: term_oror ::= term_andand ; |
275
|
|
|
|
|
|
|
term_oror ::= term_oror OROR term_andand ; /* $x || $y */ |
276
|
|
|
|
|
|
|
term_oror ::= term_oror DORDOR term_andand ; /* $x // $y */ |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
# %left ANDAND |
279
|
|
|
|
|
|
|
term_andand__t: term_andand ::= term_bitorop ; |
280
|
|
|
|
|
|
|
term_andand ::= term_andand ANDAND term_bitorop ; /* $x && $y */ |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# %left BITOROP |
283
|
|
|
|
|
|
|
term_bitorop__t: term_bitorop ::= term_bitandop; |
284
|
|
|
|
|
|
|
term_bitorop ::= term_bitorop BITOROP term_bitandop ; /* $x | $y */ |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# %left BITANDOP |
287
|
|
|
|
|
|
|
term_bitandop__t: term_bitandop ::= term_eqop ; |
288
|
|
|
|
|
|
|
term_bitandop ::= term_bitandop BITANDOP term_eqop ; /* $x & $y */ |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
# %nonassoc EQOP |
291
|
|
|
|
|
|
|
term_eqop__t: term_eqop ::= term_relop ; |
292
|
|
|
|
|
|
|
term_eqop ::= term_relop EQOP term_relop ; /* $x == $y, $x eq $y */ |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# %nonassoc RELOP |
295
|
|
|
|
|
|
|
term_relop__t: term_relop ::= term_uniop ; |
296
|
|
|
|
|
|
|
term_relop ::= term_uniop RELOP term_uniop ; /* $x > $y, etc. */ |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# %nonassoc UNIOP UNIOPSUB |
299
|
|
|
|
|
|
|
term_uniop__t: term_uniop ::= term_require ; |
300
|
|
|
|
|
|
|
uniop: term_uniop ::= UNIOP ; /* Unary op, $_ implied */ |
301
|
|
|
|
|
|
|
term_uniop ::= UNIOP block ; /* eval { foo }* */ |
302
|
|
|
|
|
|
|
term_uniop ::= UNIOP term_require ; /* Unary op */ |
303
|
|
|
|
|
|
|
term_uniop ::= UNIOPSUB ; |
304
|
|
|
|
|
|
|
term_uniop ::= UNIOPSUB term_require ; /* Sub treated as unop */ |
305
|
|
|
|
|
|
|
/* Things called with "do" */ |
306
|
|
|
|
|
|
|
term_uniop ::= DO term_require ; /* do $filename */ |
307
|
|
|
|
|
|
|
/* "my" declarations, with optional attributes */ |
308
|
|
|
|
|
|
|
# MY has no precedence |
309
|
|
|
|
|
|
|
# so apparently %prec UNIOP for term ::= myattrterm does the job |
310
|
|
|
|
|
|
|
term_myattr: term_uniop ::= MY myterm myattrlist ; |
311
|
|
|
|
|
|
|
term_my: term_uniop ::= MY myterm ; |
312
|
|
|
|
|
|
|
term_local: term_uniop ::= LOCAL term_require ; |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# %nonassoc REQUIRE |
315
|
|
|
|
|
|
|
term_require__t: term_require ::= term_shiftop ; |
316
|
|
|
|
|
|
|
term_require ::= REQUIRE ; /* require, $_ implied */ |
317
|
|
|
|
|
|
|
term_require ::= REQUIRE term_shiftop ; /* require Foo */ |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# %left SHIFTOP |
320
|
|
|
|
|
|
|
term_shiftop__t: term_shiftop ::= term_addop ; |
321
|
|
|
|
|
|
|
term_shiftop ::= term_shiftop SHIFTOP term_addop ; /* $x >> $y, $x << $y */ |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
# %left ADDOP |
324
|
|
|
|
|
|
|
term_addop__t: term_addop ::= term_mulop ; |
325
|
|
|
|
|
|
|
term_addop ::= term_addop ADDOP term_mulop ; /* $x + $y */ |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# %left MULOP |
328
|
|
|
|
|
|
|
term_mulop__t: term_mulop ::= term_matchop ; |
329
|
|
|
|
|
|
|
term_mulop ::= term_mulop MULOP term_matchop ; /* $x * $y, $x x $y */ |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# %left MATCHOP |
332
|
|
|
|
|
|
|
term_matchop__t: term_matchop ::= term_uminus ; |
333
|
|
|
|
|
|
|
term_matchop ::= term_matchop MATCHOP term_uminus ; /* $x =~ /$y/ */ |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
# %right '!' '~' UMINUS REFGEN |
336
|
|
|
|
|
|
|
term_uminus__t: term_uminus ::= term_powop ; |
337
|
|
|
|
|
|
|
term_uminus ::= '!' term_uminus ; /* !$x */ |
338
|
|
|
|
|
|
|
term_uminus ::= '~' term_uminus ; /* ~$x */ |
339
|
|
|
|
|
|
|
/* Unary operators and terms */ |
340
|
|
|
|
|
|
|
term_uminus ::= '-' term_uminus ; /* -$x */ |
341
|
|
|
|
|
|
|
term_uminus ::= '+' term_uminus ; /* +$x */ |
342
|
|
|
|
|
|
|
refgen: term_uminus ::= REFGEN term_uminus ; /* \$x, \@y, \%z */ |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
# %right POWOP |
345
|
|
|
|
|
|
|
term_powop__t: term_powop ::= term_increment ; |
346
|
|
|
|
|
|
|
term_powop ::= term_increment POWOP term_powop ; /* $x ** $y */ |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
# %nonassoc PREINC PREDEC POSTINC POSTDEC |
349
|
|
|
|
|
|
|
term_increment__t: term_increment ::= term_arrow ; |
350
|
|
|
|
|
|
|
term_increment ::= term_arrow POSTINC ; /* $x++ */ |
351
|
|
|
|
|
|
|
term_increment ::= term_arrow POSTDEC ; /* $x-- */ |
352
|
|
|
|
|
|
|
term_increment ::= PREINC term_arrow ; /* ++$x */ |
353
|
|
|
|
|
|
|
term_increment ::= PREDEC term_arrow ; /* --$x */ |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
# %left ARROW |
356
|
|
|
|
|
|
|
term_arrow__t: term_arrow ::= term_hi ; |
357
|
|
|
|
|
|
|
term_arrow ::= term_arrow ARROW method '(' listexprcom ')' ; /* $foo->bar(list) */ |
358
|
|
|
|
|
|
|
term_arrow ::= term_arrow ARROW method ; /* $foo->bar */ |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
# Able to collapse the last few |
361
|
|
|
|
|
|
|
# because no RHS terms |
362
|
|
|
|
|
|
|
# %nonassoc ')' |
363
|
|
|
|
|
|
|
# %left '(' |
364
|
|
|
|
|
|
|
# %left '[' '{' -- no terms at this precedence |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
term_hi ::= DO WORD '(' ')' ; /* do somesub() */ |
367
|
|
|
|
|
|
|
term_hi ::= DO WORD '(' expr ')' ; /* do somesub(@args) */ |
368
|
|
|
|
|
|
|
term_hi ::= DO scalar '(' ')' ; /* do $subref () */ |
369
|
|
|
|
|
|
|
term_hi ::= DO scalar '(' expr ')' ; /* do $subref (@args) */ |
370
|
|
|
|
|
|
|
term_hi__parens: term_hi ::= '(' expr ')' ; |
371
|
|
|
|
|
|
|
term_hi ::= '(' ')' ; |
372
|
|
|
|
|
|
|
term_hi ::= amper '(' ')' ; /* &foo() */ |
373
|
|
|
|
|
|
|
term_hi ::= amper '(' expr ')' ; /* &foo(@args) */ |
374
|
|
|
|
|
|
|
term_hi ::= FUNC0 '(' ')' ; |
375
|
|
|
|
|
|
|
term_hi ::= FUNC1 '(' ')' ; /* not () */ |
376
|
|
|
|
|
|
|
term_hi ::= FUNC1 '(' expr ')' ; /* not($foo) */ |
377
|
|
|
|
|
|
|
term_hi ::= PMFUNC '(' argexpr ')' ; /* m//, s///, tr/// */ |
378
|
|
|
|
|
|
|
term_hi ::= FUNC '(' indirob expr ')' ; /* print ($fh @args */ |
379
|
|
|
|
|
|
|
term_hi ::= FUNCMETH indirob '(' listexprcom ')' ; /* method $object (@args) */ |
380
|
|
|
|
|
|
|
term_hi ::= FUNC '(' listexprcom ')' ; /* print (@args) */ |
381
|
|
|
|
|
|
|
anon_hash: term_hi ::= HASHBRACK expr ';' '}' ; /* { foo => "Bar" } */ |
382
|
|
|
|
|
|
|
anon_empty_hash: term_hi ::= HASHBRACK ';' '}' ; /* { } (';' by tokener) */ |
383
|
|
|
|
|
|
|
term_hi ::= ANONSUB startanonsub proto subattrlist block ; |
384
|
|
|
|
|
|
|
do_block: term_hi ::= DO block ; /* do { code */ |
385
|
|
|
|
|
|
|
term_hi__scalar: term_hi ::= scalar ; |
386
|
|
|
|
|
|
|
term_hi__star: term_hi ::= star ; |
387
|
|
|
|
|
|
|
term_hi__hsh: term_hi ::= hsh ; |
388
|
|
|
|
|
|
|
term_hi__ary: term_hi ::= ary ; |
389
|
|
|
|
|
|
|
# $#x, $#{ something } |
390
|
|
|
|
|
|
|
term_hi__arylen: term_hi ::= arylen ; |
391
|
|
|
|
|
|
|
term_hi__subscripted: term_hi ::= subscripted ; |
392
|
|
|
|
|
|
|
term_hi__THING: term_hi ::= THING ; |
393
|
|
|
|
|
|
|
/* Constructors for anonymous data */ |
394
|
|
|
|
|
|
|
term_hi__anon_array: term_hi ::= '[' expr ']' ; |
395
|
|
|
|
|
|
|
term_hi__anon_empty_array: term_hi ::= '[' ']' ; |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# Some kind of subscripted expression |
398
|
|
|
|
|
|
|
subscripted ::= star '{' expr ';' '}' ; /* *main::{something} */ |
399
|
|
|
|
|
|
|
array_index: subscripted ::= scalar '[' expr ']' ; /* $array[$element] */ |
400
|
|
|
|
|
|
|
term_hi__arrow_array: subscripted ::= term_hi ARROW '[' expr ']' ; /* somearef->[$element] */ |
401
|
|
|
|
|
|
|
array_index_r: subscripted ::= subscripted '[' expr ']' ; /* $foo->[$bar]->[$baz] */ |
402
|
|
|
|
|
|
|
hash_index: subscripted ::= scalar '{' expr ';' '}' ; /* $foo->{bar();} */ |
403
|
|
|
|
|
|
|
term_hi__arrow_hash: subscripted ::= term_hi ARROW '{' expr ';' '}' ; /* somehref->{bar();} */ |
404
|
|
|
|
|
|
|
hash_index_r: subscripted ::= subscripted '{' expr ';' '}' ; /* $foo->[bar]->{baz;} */ |
405
|
|
|
|
|
|
|
subscripted ::= term_hi ARROW '(' ')' ; /* $subref->() */ |
406
|
|
|
|
|
|
|
subscripted ::= term_hi ARROW '(' expr ')' ; /* $subref->(@args) */ |
407
|
|
|
|
|
|
|
subscripted ::= subscripted '(' expr ')' ; /* $foo->{bar}->(@args) */ |
408
|
|
|
|
|
|
|
subscripted ::= subscripted '(' ')' ; /* $foo->{bar}->() */ |
409
|
|
|
|
|
|
|
subscripted ::= '(' expr ')' '[' expr ']' ; /* list slice */ |
410
|
|
|
|
|
|
|
subscripted ::= '(' ')' '[' expr ']' ; /* empty list slice! */ |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
term_hi ::= ary '[' expr ']' ; /* array slice */ |
413
|
|
|
|
|
|
|
term_hi ::= ary '{' expr ';' '}' ; /* @hash{@keys} */ |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
term_hi ::= amper ; /* &foo; */ |
416
|
|
|
|
|
|
|
term_hi ::= NOAMP WORD listexpr ; /* foo(@args) */ |
417
|
|
|
|
|
|
|
term_hi ::= FUNC0 ; /* Nullary operator */ |
418
|
|
|
|
|
|
|
term_hi ::= FUNC0SUB ; /* Sub treated as nullop */ |
419
|
|
|
|
|
|
|
term_hi ::= WORD ; |
420
|
|
|
|
|
|
|
term_hi ::= PLUGEXPR ; |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
# End of list of terms |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
/* Things that can be "my"'d */ |
425
|
|
|
|
|
|
|
myterm_scalar: myterm ::= scalar ; |
426
|
|
|
|
|
|
|
myterm_hash: myterm ::= hsh ; |
427
|
|
|
|
|
|
|
myterm_array: myterm ::= ary ; |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
/* Basic list expressions */ |
430
|
|
|
|
|
|
|
# Essentially, a listexpr is a nullable argexpr |
431
|
|
|
|
|
|
|
listexpr_t: listexpr ::= ; /* NULL */ |
432
|
|
|
|
|
|
|
listexpr: listexpr ::= argexpr ; |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
# In perly.y listexprcom occurs only inside parentheses |
435
|
|
|
|
|
|
|
listexprcom ::= ; /* NULL */ |
436
|
|
|
|
|
|
|
listexprcom ::= expr ; |
437
|
|
|
|
|
|
|
listexprcom ::= expr ',' ; |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
/* A little bit of trickery to make "for my $foo (@bar)" actually be lexical */ |
440
|
|
|
|
|
|
|
my_scalar ::= scalar ; |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
amper ::= '&' indirob ; |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
scalar: scalar ::= '$' indirob ; |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
ary ::= '@' indirob ; |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
hsh ::= '%' indirob ; |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
arylen ::= DOLSHARP indirob ; |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
star ::= '*' indirob ; |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
/* Indirect objects */ |
455
|
|
|
|
|
|
|
indirob__WORD: indirob ::= WORD ; |
456
|
|
|
|
|
|
|
indirob ::= scalar ; |
457
|
|
|
|
|
|
|
indirob__block: indirob ::= block ; |
458
|
|
|
|
|
|
|
indirob ::= PRIVATEREF ; |
459
|
|
|
|
|
|
|
END_OF_GRAMMAR |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars) |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
my %symbol_name = ( |
464
|
|
|
|
|
|
|
q{'~'} => 'TILDE', |
465
|
|
|
|
|
|
|
q{'-'} => 'MINUS', |
466
|
|
|
|
|
|
|
q{','} => 'COMMA', |
467
|
|
|
|
|
|
|
q{';'} => 'SEMI', |
468
|
|
|
|
|
|
|
q{':'} => 'COLON', |
469
|
|
|
|
|
|
|
q{'!'} => 'BANG', |
470
|
|
|
|
|
|
|
q{'?'} => 'QUESTION', |
471
|
|
|
|
|
|
|
q{'('} => 'LPAREN', |
472
|
|
|
|
|
|
|
q{')'} => 'RPAREN', |
473
|
|
|
|
|
|
|
q{'['} => 'LSQUARE', |
474
|
|
|
|
|
|
|
q{']'} => 'RSQUARE', |
475
|
|
|
|
|
|
|
q['{'] => 'LCURLY', |
476
|
|
|
|
|
|
|
q['}'] => 'RCURLY', |
477
|
|
|
|
|
|
|
q{'@'} => 'ATSIGN', |
478
|
|
|
|
|
|
|
q{'$'} => 'DOLLAR', |
479
|
|
|
|
|
|
|
q{'*'} => 'ASTERISK', |
480
|
|
|
|
|
|
|
q{'&'} => 'AMPERSAND', |
481
|
|
|
|
|
|
|
q{'%'} => 'PERCENT', |
482
|
|
|
|
|
|
|
q{'+'} => 'PLUS', |
483
|
|
|
|
|
|
|
); |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
my %perl_type_by_cast = ( |
486
|
|
|
|
|
|
|
q{\\} => 'REFGEN', |
487
|
|
|
|
|
|
|
q{$} => 'DOLLAR', |
488
|
|
|
|
|
|
|
q{@} => 'ATSIGN', |
489
|
|
|
|
|
|
|
q{%} => 'PERCENT', |
490
|
|
|
|
|
|
|
); |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
my %perl_type_by_structure = ( |
493
|
|
|
|
|
|
|
q{(} => 'LPAREN', |
494
|
|
|
|
|
|
|
q{)} => 'RPAREN', |
495
|
|
|
|
|
|
|
q{[} => 'LSQUARE', |
496
|
|
|
|
|
|
|
q{]} => 'RSQUARE', |
497
|
|
|
|
|
|
|
q[{] => 'LCURLY', |
498
|
|
|
|
|
|
|
q[}] => 'RCURLY', |
499
|
|
|
|
|
|
|
q{;} => 'SEMI', |
500
|
|
|
|
|
|
|
); |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
my %perl_type_by_op = ( |
503
|
|
|
|
|
|
|
q{->} => 'ARROW', # 1 |
504
|
|
|
|
|
|
|
q{--} => 'PREDEC', # 2 |
505
|
|
|
|
|
|
|
q{++} => 'PREINC', # 2 |
506
|
|
|
|
|
|
|
q{**} => 'POWOP', # 3 |
507
|
|
|
|
|
|
|
q{~} => 'TILDE', # 4 |
508
|
|
|
|
|
|
|
q{!} => 'BANG', # 4 |
509
|
|
|
|
|
|
|
q{\\} => 'REFGEN', # 4 |
510
|
|
|
|
|
|
|
q{=~} => 'MATCHOP', # 5 |
511
|
|
|
|
|
|
|
q{!~} => 'MATCHOP', # 5 |
512
|
|
|
|
|
|
|
q{/} => 'MULOP', # 6 |
513
|
|
|
|
|
|
|
q{*} => 'MULOP', # 6 |
514
|
|
|
|
|
|
|
q{%} => 'MULOP', # 6 |
515
|
|
|
|
|
|
|
q{x} => 'MULOP', # 6 |
516
|
|
|
|
|
|
|
q{-} => 'MINUS', # 7 |
517
|
|
|
|
|
|
|
q{.} => 'ADDOP', # 7 |
518
|
|
|
|
|
|
|
q{+} => 'PLUS', # 7 |
519
|
|
|
|
|
|
|
q{<<} => 'SHIFTOP', # 8 |
520
|
|
|
|
|
|
|
q{>>} => 'SHIFTOP', # 8 |
521
|
|
|
|
|
|
|
q{-A} => 'UNIOP', # 9 |
522
|
|
|
|
|
|
|
q{-b} => 'UNIOP', # 9 |
523
|
|
|
|
|
|
|
q{-B} => 'UNIOP', # 9 |
524
|
|
|
|
|
|
|
q{-c} => 'UNIOP', # 9 |
525
|
|
|
|
|
|
|
q{-C} => 'UNIOP', # 9 |
526
|
|
|
|
|
|
|
q{-d} => 'UNIOP', # 9 |
527
|
|
|
|
|
|
|
q{-e} => 'UNIOP', # 9 |
528
|
|
|
|
|
|
|
q{-f} => 'UNIOP', # 9 |
529
|
|
|
|
|
|
|
q{-g} => 'UNIOP', # 9 |
530
|
|
|
|
|
|
|
q{-k} => 'UNIOP', # 9 |
531
|
|
|
|
|
|
|
q{-l} => 'UNIOP', # 9 |
532
|
|
|
|
|
|
|
q{-M} => 'UNIOP', # 9 |
533
|
|
|
|
|
|
|
q{-o} => 'UNIOP', # 9 |
534
|
|
|
|
|
|
|
q{-O} => 'UNIOP', # 9 |
535
|
|
|
|
|
|
|
q{-p} => 'UNIOP', # 9 |
536
|
|
|
|
|
|
|
q{-r} => 'UNIOP', # 9 |
537
|
|
|
|
|
|
|
q{-R} => 'UNIOP', # 9 |
538
|
|
|
|
|
|
|
q{-s} => 'UNIOP', # 9 |
539
|
|
|
|
|
|
|
q{-S} => 'UNIOP', # 9 |
540
|
|
|
|
|
|
|
q{-t} => 'UNIOP', # 9 |
541
|
|
|
|
|
|
|
q{-T} => 'UNIOP', # 9 |
542
|
|
|
|
|
|
|
q{-u} => 'UNIOP', # 9 |
543
|
|
|
|
|
|
|
q{-w} => 'UNIOP', # 9 |
544
|
|
|
|
|
|
|
q{-W} => 'UNIOP', # 9 |
545
|
|
|
|
|
|
|
q{-x} => 'UNIOP', # 9 |
546
|
|
|
|
|
|
|
q{-X} => 'UNIOP', # 9 |
547
|
|
|
|
|
|
|
q{-z} => 'UNIOP', # 9 |
548
|
|
|
|
|
|
|
q{ge} => 'RELOP', # 10 |
549
|
|
|
|
|
|
|
q{gt} => 'RELOP', # 10 |
550
|
|
|
|
|
|
|
q{le} => 'RELOP', # 10 |
551
|
|
|
|
|
|
|
q{lt} => 'RELOP', # 10 |
552
|
|
|
|
|
|
|
q{<=} => 'RELOP', # 10 |
553
|
|
|
|
|
|
|
q{<} => 'RELOP', # 10 |
554
|
|
|
|
|
|
|
q{>=} => 'RELOP', # 10 |
555
|
|
|
|
|
|
|
q{>} => 'RELOP', # 10 |
556
|
|
|
|
|
|
|
q{cmp} => 'EQOP', # 11 |
557
|
|
|
|
|
|
|
q{eq} => 'EQOP', # 11 |
558
|
|
|
|
|
|
|
q{ne} => 'EQOP', # 11 |
559
|
|
|
|
|
|
|
q{~~} => 'EQOP', # 11 |
560
|
|
|
|
|
|
|
q{<=>} => 'EQOP', # 11 |
561
|
|
|
|
|
|
|
q{==} => 'EQOP', # 11 |
562
|
|
|
|
|
|
|
q{!=} => 'EQOP', # 11 |
563
|
|
|
|
|
|
|
q{&} => 'BITANDOP', # 12 |
564
|
|
|
|
|
|
|
q{^} => 'BITOROP', # 13 |
565
|
|
|
|
|
|
|
q{|} => 'BITOROP', # 13 |
566
|
|
|
|
|
|
|
q{&&} => 'ANDAND', # 14 |
567
|
|
|
|
|
|
|
q{||} => 'OROR', # 15 |
568
|
|
|
|
|
|
|
q{//} => 'DORDOR', # 15 |
569
|
|
|
|
|
|
|
q{..} => 'DOTDOT', # 16 |
570
|
|
|
|
|
|
|
q{...} => 'YADAYADA', # 17 |
571
|
|
|
|
|
|
|
q{:} => 'COLON', # 18 |
572
|
|
|
|
|
|
|
q{?} => 'QUESTION', # 18 |
573
|
|
|
|
|
|
|
q{^=} => 'ASSIGNOP', # 19 |
574
|
|
|
|
|
|
|
q{<<=} => 'ASSIGNOP', # 19 |
575
|
|
|
|
|
|
|
q{=} => 'ASSIGNOP', # 19 |
576
|
|
|
|
|
|
|
q{>>=} => 'ASSIGNOP', # 19 |
577
|
|
|
|
|
|
|
q{|=} => 'ASSIGNOP', # 19 |
578
|
|
|
|
|
|
|
q{||=} => 'ASSIGNOP', # 19 |
579
|
|
|
|
|
|
|
q{-=} => 'ASSIGNOP', # 19 |
580
|
|
|
|
|
|
|
q{/=} => 'ASSIGNOP', # 19 |
581
|
|
|
|
|
|
|
q{.=} => 'ASSIGNOP', # 19 |
582
|
|
|
|
|
|
|
q{*=} => 'ASSIGNOP', # 19 |
583
|
|
|
|
|
|
|
q{**=} => 'ASSIGNOP', # 19 |
584
|
|
|
|
|
|
|
q{&=} => 'ASSIGNOP', # 19 |
585
|
|
|
|
|
|
|
q{&&=} => 'ASSIGNOP', # 19 |
586
|
|
|
|
|
|
|
q{%=} => 'ASSIGNOP', # 19 |
587
|
|
|
|
|
|
|
q{+=} => 'ASSIGNOP', # 19 |
588
|
|
|
|
|
|
|
q{x=} => 'ASSIGNOP', # 19 |
589
|
|
|
|
|
|
|
q{,} => 'COMMA', # 20 |
590
|
|
|
|
|
|
|
q{=>} => 'COMMA', # 20 |
591
|
|
|
|
|
|
|
q{not} => 'NOTOP', # 22 |
592
|
|
|
|
|
|
|
q{and} => 'ANDOP', # 23 |
593
|
|
|
|
|
|
|
q{or} => 'OROP', # 24 |
594
|
|
|
|
|
|
|
q{xor} => 'DOROP', # 24 |
595
|
|
|
|
|
|
|
); |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
my %perl_type_by_word = ( |
598
|
|
|
|
|
|
|
'AUTOLOAD' => 'PHASER -- TO BE DETERMINED', |
599
|
|
|
|
|
|
|
'BEGIN' => 'PHASER -- TO BE DETERMINED', |
600
|
|
|
|
|
|
|
'CHECK' => 'PHASER -- TO BE DETERMINED', |
601
|
|
|
|
|
|
|
'CORE' => 'TO_BE_DETERMINED', |
602
|
|
|
|
|
|
|
'DESTROY' => 'PHASER -- TO BE DETERMINED', |
603
|
|
|
|
|
|
|
'END' => 'PHASER -- TO BE DETERMINED', |
604
|
|
|
|
|
|
|
'INIT' => 'PHASER -- TO BE DETERMINED', |
605
|
|
|
|
|
|
|
'NULL' => 'TO_BE_DETERMINED', |
606
|
|
|
|
|
|
|
'UNITCHECK' => 'PHASER -- TO BE DETERMINED', |
607
|
|
|
|
|
|
|
'__DATA__' => 'TO_BE_DETERMINED', |
608
|
|
|
|
|
|
|
'__END__' => 'TO_BE_DETERMINED', |
609
|
|
|
|
|
|
|
'__FILE__' => 'THING', |
610
|
|
|
|
|
|
|
'__LINE__' => 'THING', |
611
|
|
|
|
|
|
|
'__PACKAGE__' => 'THING', |
612
|
|
|
|
|
|
|
'abs' => 'UNIOP', |
613
|
|
|
|
|
|
|
'accept' => 'LSTOP', |
614
|
|
|
|
|
|
|
'alarm' => 'UNIOP', |
615
|
|
|
|
|
|
|
'atan2' => 'LSTOP', |
616
|
|
|
|
|
|
|
'bind' => 'LSTOP', |
617
|
|
|
|
|
|
|
'binmode' => 'LSTOP', |
618
|
|
|
|
|
|
|
'bless' => 'LSTOP', |
619
|
|
|
|
|
|
|
'bless' => 'LSTOP', |
620
|
|
|
|
|
|
|
'break' => 'LOOPEX', |
621
|
|
|
|
|
|
|
'caller' => 'UNIOP', |
622
|
|
|
|
|
|
|
'chdir' => 'UNIOP', |
623
|
|
|
|
|
|
|
'chmod' => 'LSTOP', |
624
|
|
|
|
|
|
|
'chomp' => 'UNIOP', |
625
|
|
|
|
|
|
|
'chop' => 'UNIOP', |
626
|
|
|
|
|
|
|
'chown' => 'LSTOP', |
627
|
|
|
|
|
|
|
'chr' => 'UNIOP', |
628
|
|
|
|
|
|
|
'chroot' => 'UNIOP', |
629
|
|
|
|
|
|
|
'close' => 'UNIOP', |
630
|
|
|
|
|
|
|
'closedir' => 'UNIOP', |
631
|
|
|
|
|
|
|
'connect' => 'LSTOP', |
632
|
|
|
|
|
|
|
'continue' => 'CONTINUE', |
633
|
|
|
|
|
|
|
'cos' => 'UNIOP', |
634
|
|
|
|
|
|
|
'crypt' => 'LSTOP', |
635
|
|
|
|
|
|
|
'dbmclose' => 'UNIOP', |
636
|
|
|
|
|
|
|
'dbmopen' => 'LSTOP', |
637
|
|
|
|
|
|
|
'default' => 'DEFAULT', |
638
|
|
|
|
|
|
|
'defined' => 'UNIOP', |
639
|
|
|
|
|
|
|
'delete' => 'UNIOP', |
640
|
|
|
|
|
|
|
'die' => 'LSTOP', |
641
|
|
|
|
|
|
|
'do' => 'DO', |
642
|
|
|
|
|
|
|
'dump' => 'UNIOP', |
643
|
|
|
|
|
|
|
'each' => 'UNIOP', |
644
|
|
|
|
|
|
|
'else' => 'ELSE', |
645
|
|
|
|
|
|
|
'elsif' => 'ELSIF', |
646
|
|
|
|
|
|
|
'endgrent' => 'FUNC0', |
647
|
|
|
|
|
|
|
'endhostent' => 'FUNC0', |
648
|
|
|
|
|
|
|
'endnetent' => 'FUNC0', |
649
|
|
|
|
|
|
|
'endprotoent' => 'FUNC0', |
650
|
|
|
|
|
|
|
'endpwent' => 'FUNC0', |
651
|
|
|
|
|
|
|
'endservent' => 'FUNC0', |
652
|
|
|
|
|
|
|
'eof' => 'UNIOP', |
653
|
|
|
|
|
|
|
'eval' => 'UNIOP', |
654
|
|
|
|
|
|
|
'exec' => 'LSTOP', |
655
|
|
|
|
|
|
|
'exists' => 'UNIOP', |
656
|
|
|
|
|
|
|
'exit' => 'UNIOP', |
657
|
|
|
|
|
|
|
'exp' => 'UNIOP', |
658
|
|
|
|
|
|
|
'fcntl' => 'LSTOP', |
659
|
|
|
|
|
|
|
'fileno' => 'UNIOP', |
660
|
|
|
|
|
|
|
'flock' => 'LSTOP', |
661
|
|
|
|
|
|
|
'for' => 'FOR', |
662
|
|
|
|
|
|
|
'foreach' => 'FOR', |
663
|
|
|
|
|
|
|
'fork' => 'FUNC0', |
664
|
|
|
|
|
|
|
'format' => 'FUNC0', |
665
|
|
|
|
|
|
|
'formline' => 'LSTOP', |
666
|
|
|
|
|
|
|
'getc' => 'UNIOP', |
667
|
|
|
|
|
|
|
'getgrent' => 'FUNC0', |
668
|
|
|
|
|
|
|
'getgrgid' => 'UNIOP', |
669
|
|
|
|
|
|
|
'getgrnam' => 'UNIOP', |
670
|
|
|
|
|
|
|
'gethostbyaddr' => 'LSTOP', |
671
|
|
|
|
|
|
|
'gethostbyname' => 'UNIOP', |
672
|
|
|
|
|
|
|
'gethostent' => 'FUNC0', |
673
|
|
|
|
|
|
|
'getlogin' => 'FUNC0', |
674
|
|
|
|
|
|
|
'getnetbyaddr' => 'LSTOP', |
675
|
|
|
|
|
|
|
'getnetbyname' => 'UNIOP', |
676
|
|
|
|
|
|
|
'getnetent' => 'FUNC0', |
677
|
|
|
|
|
|
|
'getpeername' => 'UNIOP', |
678
|
|
|
|
|
|
|
'getpgrp' => 'UNIOP', |
679
|
|
|
|
|
|
|
'getppid' => 'FUNC0', |
680
|
|
|
|
|
|
|
'getpriority' => 'LSTOP', |
681
|
|
|
|
|
|
|
'getprotobyname' => 'UNIOP', |
682
|
|
|
|
|
|
|
'getprotobynumber' => 'UNIOP', |
683
|
|
|
|
|
|
|
'getprotoent' => 'FUNC0', |
684
|
|
|
|
|
|
|
'getpwent' => 'FUNC0', |
685
|
|
|
|
|
|
|
'getpwnam' => 'UNIOP', |
686
|
|
|
|
|
|
|
'getpwuid' => 'UNIOP', |
687
|
|
|
|
|
|
|
'getservbyname' => 'LSTOP', |
688
|
|
|
|
|
|
|
'getservbyport' => 'LSTOP', |
689
|
|
|
|
|
|
|
'getservent' => 'FUNC0', |
690
|
|
|
|
|
|
|
'getsockname' => 'UNIOP', |
691
|
|
|
|
|
|
|
'getsockopt' => 'LSTOP', |
692
|
|
|
|
|
|
|
'given' => 'GIVEN', |
693
|
|
|
|
|
|
|
'glob' => 'UNIOP', |
694
|
|
|
|
|
|
|
'gmtime' => 'UNIOP', |
695
|
|
|
|
|
|
|
'goto' => 'LOOPEX', |
696
|
|
|
|
|
|
|
'grep' => 'LSTOP', |
697
|
|
|
|
|
|
|
'hex' => 'UNIOP', |
698
|
|
|
|
|
|
|
'if' => 'IF', |
699
|
|
|
|
|
|
|
'import' => 'LSTOP', # not really a keyword, but make it a LSTOP |
700
|
|
|
|
|
|
|
'index' => 'LSTOP', |
701
|
|
|
|
|
|
|
'int' => 'UNIOP', |
702
|
|
|
|
|
|
|
'ioctl' => 'LSTOP', |
703
|
|
|
|
|
|
|
'join' => 'LSTOP', |
704
|
|
|
|
|
|
|
'keys' => 'UNIOP', |
705
|
|
|
|
|
|
|
'kill' => 'LSTOP', |
706
|
|
|
|
|
|
|
'last' => 'LOOPEX', |
707
|
|
|
|
|
|
|
'lc' => 'UNIOP', |
708
|
|
|
|
|
|
|
'lcfirst' => 'UNIOP', |
709
|
|
|
|
|
|
|
'length' => 'UNIOP', |
710
|
|
|
|
|
|
|
'link' => 'LSTOP', |
711
|
|
|
|
|
|
|
'listen' => 'LSTOP', |
712
|
|
|
|
|
|
|
'local' => 'LOCAL', |
713
|
|
|
|
|
|
|
'localtime' => 'UNIOP', |
714
|
|
|
|
|
|
|
'lock' => 'UNIOP', |
715
|
|
|
|
|
|
|
'log' => 'UNIOP', |
716
|
|
|
|
|
|
|
'lstat' => 'UNIOP', |
717
|
|
|
|
|
|
|
'm' => 'QUOTEABLE -- TO BE DETERMINED', |
718
|
|
|
|
|
|
|
'map' => 'LSTOP', |
719
|
|
|
|
|
|
|
'mkdir' => 'LSTOP', |
720
|
|
|
|
|
|
|
'msgctl' => 'LSTOP', |
721
|
|
|
|
|
|
|
'msgget' => 'LSTOP', |
722
|
|
|
|
|
|
|
'msgrcv' => 'LSTOP', |
723
|
|
|
|
|
|
|
'msgsnd' => 'LSTOP', |
724
|
|
|
|
|
|
|
'my' => 'MY', |
725
|
|
|
|
|
|
|
'my' => 'MY', |
726
|
|
|
|
|
|
|
'next' => 'LOOPEX', |
727
|
|
|
|
|
|
|
'no' => 'USE', |
728
|
|
|
|
|
|
|
'oct' => 'UNIOP', |
729
|
|
|
|
|
|
|
'open' => 'LSTOP', |
730
|
|
|
|
|
|
|
'opendir' => 'LSTOP', |
731
|
|
|
|
|
|
|
'ord' => 'UNIOP', |
732
|
|
|
|
|
|
|
'our' => 'MY', |
733
|
|
|
|
|
|
|
'pack' => 'LSTOP', |
734
|
|
|
|
|
|
|
'package' => 'PACKAGE', |
735
|
|
|
|
|
|
|
'pipe' => 'LSTOP', |
736
|
|
|
|
|
|
|
'pop' => 'UNIOP', |
737
|
|
|
|
|
|
|
'pos' => 'UNIOP', |
738
|
|
|
|
|
|
|
'print' => 'LSTOP', |
739
|
|
|
|
|
|
|
'printf' => 'LSTOP', |
740
|
|
|
|
|
|
|
'prototype' => 'UNIOP', |
741
|
|
|
|
|
|
|
'push' => 'LSTOP', |
742
|
|
|
|
|
|
|
'q' => 'QUOTEABLE -- TO BE DETERMINED', |
743
|
|
|
|
|
|
|
'qq' => 'QUOTEABLE -- TO BE DETERMINED', |
744
|
|
|
|
|
|
|
'qr' => 'QUOTEABLE -- TO BE DETERMINED', |
745
|
|
|
|
|
|
|
'quotemeta' => 'UNIOP', |
746
|
|
|
|
|
|
|
'qw' => 'QUOTEABLE -- TO BE DETERMINED', |
747
|
|
|
|
|
|
|
'qx' => 'QUOTEABLE -- TO BE DETERMINED', |
748
|
|
|
|
|
|
|
'rand' => 'UNIOP', |
749
|
|
|
|
|
|
|
'read' => 'LSTOP', |
750
|
|
|
|
|
|
|
'readdir' => 'UNIOP', |
751
|
|
|
|
|
|
|
'readline' => 'UNIOP', |
752
|
|
|
|
|
|
|
'readlink' => 'UNIOP', |
753
|
|
|
|
|
|
|
'readpipe' => 'UNIOP', |
754
|
|
|
|
|
|
|
'recv' => 'LSTOP', |
755
|
|
|
|
|
|
|
'redo' => 'LOOPEX', |
756
|
|
|
|
|
|
|
'ref' => 'UNIOP', |
757
|
|
|
|
|
|
|
'rename' => 'LSTOP', |
758
|
|
|
|
|
|
|
'require' => 'REQUIRE', |
759
|
|
|
|
|
|
|
'reset' => 'UNIOP', |
760
|
|
|
|
|
|
|
'return' => 'LSTOP', |
761
|
|
|
|
|
|
|
'reverse' => 'LSTOP', |
762
|
|
|
|
|
|
|
'rewinddir' => 'UNIOP', |
763
|
|
|
|
|
|
|
'rindex' => 'LSTOP', |
764
|
|
|
|
|
|
|
'rmdir' => 'UNIOP', |
765
|
|
|
|
|
|
|
's' => 'QUOTEABLE -- TO BE DETERMINED', |
766
|
|
|
|
|
|
|
'say' => 'LSTOP', |
767
|
|
|
|
|
|
|
'scalar' => 'UNIOP', |
768
|
|
|
|
|
|
|
'seek' => 'LSTOP', |
769
|
|
|
|
|
|
|
'seekdir' => 'LSTOP', |
770
|
|
|
|
|
|
|
'select' => 'LSTOP', |
771
|
|
|
|
|
|
|
'semctl' => 'LSTOP', |
772
|
|
|
|
|
|
|
'semget' => 'LSTOP', |
773
|
|
|
|
|
|
|
'semop' => 'LSTOP', |
774
|
|
|
|
|
|
|
'send' => 'LSTOP', |
775
|
|
|
|
|
|
|
'setgrent' => 'FUNC0', |
776
|
|
|
|
|
|
|
'sethostent' => 'UNIOP', |
777
|
|
|
|
|
|
|
'setnetent' => 'UNIOP', |
778
|
|
|
|
|
|
|
'setpgrp' => 'LSTOP', |
779
|
|
|
|
|
|
|
'setpriority' => 'LSTOP', |
780
|
|
|
|
|
|
|
'setprotoent' => 'UNIOP', |
781
|
|
|
|
|
|
|
'setpwent' => 'FUNC0', |
782
|
|
|
|
|
|
|
'setservent' => 'UNIOP', |
783
|
|
|
|
|
|
|
'setsockopt' => 'LSTOP', |
784
|
|
|
|
|
|
|
'shift' => 'UNIOP', |
785
|
|
|
|
|
|
|
'shmctl' => 'LSTOP', |
786
|
|
|
|
|
|
|
'shmget' => 'LSTOP', |
787
|
|
|
|
|
|
|
'shmread' => 'LSTOP', |
788
|
|
|
|
|
|
|
'shmwrite' => 'LSTOP', |
789
|
|
|
|
|
|
|
'shutdown' => 'LSTOP', |
790
|
|
|
|
|
|
|
'sin' => 'UNIOP', |
791
|
|
|
|
|
|
|
'sleep' => 'UNIOP', |
792
|
|
|
|
|
|
|
'socket' => 'LSTOP', |
793
|
|
|
|
|
|
|
'socketpair' => 'LSTOP', |
794
|
|
|
|
|
|
|
'sort' => 'LSTOP', |
795
|
|
|
|
|
|
|
'splice' => 'LSTOP', |
796
|
|
|
|
|
|
|
'split' => 'LSTOP', |
797
|
|
|
|
|
|
|
'sprintf' => 'LSTOP', |
798
|
|
|
|
|
|
|
'sqrt' => 'UNIOP', |
799
|
|
|
|
|
|
|
'srand' => 'UNIOP', |
800
|
|
|
|
|
|
|
'stat' => 'UNIOP', |
801
|
|
|
|
|
|
|
'state' => 'MY', |
802
|
|
|
|
|
|
|
'study' => 'UNIOP', |
803
|
|
|
|
|
|
|
'sub' => 'SUB', |
804
|
|
|
|
|
|
|
'substr' => 'LSTOP', |
805
|
|
|
|
|
|
|
'symlink' => 'LSTOP', |
806
|
|
|
|
|
|
|
'syscall' => 'LSTOP', |
807
|
|
|
|
|
|
|
'sysopen' => 'LSTOP', |
808
|
|
|
|
|
|
|
'sysread' => 'LSTOP', |
809
|
|
|
|
|
|
|
'sysseek' => 'LSTOP', |
810
|
|
|
|
|
|
|
'system' => 'LSTOP', |
811
|
|
|
|
|
|
|
'syswrite' => 'LSTOP', |
812
|
|
|
|
|
|
|
'tell' => 'UNIOP', |
813
|
|
|
|
|
|
|
'telldir' => 'UNIOP', |
814
|
|
|
|
|
|
|
'tie' => 'LSTOP', |
815
|
|
|
|
|
|
|
'tied' => 'UNIOP', |
816
|
|
|
|
|
|
|
'time' => 'FUNC0', |
817
|
|
|
|
|
|
|
'times' => 'FUNC0', |
818
|
|
|
|
|
|
|
'tr' => 'QUOTEABLE -- TO BE DETERMINED', |
819
|
|
|
|
|
|
|
'truncate' => 'LSTOP', |
820
|
|
|
|
|
|
|
'uc' => 'UNIOP', |
821
|
|
|
|
|
|
|
'ucfirst' => 'UNIOP', |
822
|
|
|
|
|
|
|
'umask' => 'UNIOP', |
823
|
|
|
|
|
|
|
'undef' => 'UNIOP', |
824
|
|
|
|
|
|
|
'undef' => 'UNIOP', |
825
|
|
|
|
|
|
|
'unless' => 'UNLESS', |
826
|
|
|
|
|
|
|
'unlink' => 'LSTOP', |
827
|
|
|
|
|
|
|
'unpack' => 'LSTOP', |
828
|
|
|
|
|
|
|
'unshift' => 'LSTOP', |
829
|
|
|
|
|
|
|
'untie' => 'UNIOP', |
830
|
|
|
|
|
|
|
'until' => 'UNTIL', |
831
|
|
|
|
|
|
|
'use' => 'USE', |
832
|
|
|
|
|
|
|
'utime' => 'LSTOP', |
833
|
|
|
|
|
|
|
'values' => 'UNIOP', |
834
|
|
|
|
|
|
|
'vec' => 'LSTOP', |
835
|
|
|
|
|
|
|
'wait' => 'FUNC0', |
836
|
|
|
|
|
|
|
'waitpid' => 'LSTOP', |
837
|
|
|
|
|
|
|
'wantarray' => 'FUNC0', |
838
|
|
|
|
|
|
|
'warn' => 'LSTOP', |
839
|
|
|
|
|
|
|
'when' => 'WHEN', |
840
|
|
|
|
|
|
|
'while' => 'WHILE', |
841
|
|
|
|
|
|
|
'write' => 'UNIOP', |
842
|
|
|
|
|
|
|
'y' => 'QUOTEABLE -- TO BE DETERMINED', |
843
|
|
|
|
|
|
|
); |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
## use critic |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
sub Marpa::PP::Perl::new { |
848
|
2
|
|
|
2
|
0
|
779
|
my ( $class, $gen_closure ) = @_; |
849
|
|
|
|
|
|
|
|
850
|
2
|
|
|
|
|
7
|
my %symbol = (); |
851
|
2
|
|
|
|
|
5
|
my @rules; |
852
|
|
|
|
|
|
|
my %closure; |
853
|
0
|
|
|
|
|
0
|
my $has_ranking_action; |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
LINE: |
856
|
2
|
|
|
|
|
277
|
for my $line ( split /\n/xms, $reference_grammar ) { |
857
|
848
|
|
|
|
|
5702
|
chomp $line; |
858
|
848
|
|
|
|
|
2125
|
$line =~ s/ [#] .* \z //xms; |
859
|
848
|
|
|
|
|
1968
|
$line =~ s/ [\/][*] .* \z //xms; |
860
|
848
|
|
|
|
|
1317
|
$line =~ s/ \A \s+ //xms; |
861
|
848
|
100
|
|
|
|
2013
|
next LINE if $line eq q{}; |
862
|
446
|
50
|
|
|
|
1889
|
Carp::croak("Misformed line: $line") |
863
|
|
|
|
|
|
|
if $line !~ / [:][:][=] .* [;] \s* \z /xms; |
864
|
446
|
|
|
|
|
1714
|
my ($action_name) = ( $line =~ /\A (\w+) \s* [:] [^:] /gxms ); |
865
|
446
|
|
|
|
|
12002
|
my ( $lhs, $rhs_string ) = |
866
|
|
|
|
|
|
|
( $line =~ / \s* (\w+) \s* [:][:][=] \s* (.*) [;] \s* \z/xms ); |
867
|
446
|
|
66
|
|
|
1203
|
my @rhs = map { $symbol_name{$_} // $_ } split q{ }, $rhs_string; |
|
1072
|
|
|
|
|
6080
|
|
868
|
|
|
|
|
|
|
|
869
|
446
|
|
|
|
|
1128
|
for my $symbol ( $lhs, @rhs ) { |
870
|
1518
|
|
100
|
|
|
7014
|
$symbol{$symbol} //= 0; |
871
|
1518
|
50
|
|
|
|
4581
|
if ( $symbol =~ /\W/xms ) { |
872
|
0
|
|
|
|
|
0
|
Carp::croak("Misformed symbol: $symbol"); |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
} ## end for my $symbol ( $lhs, @rhs ) |
875
|
446
|
|
|
|
|
700
|
$symbol{$lhs}++; |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
# only create action for non-empty rules |
878
|
446
|
|
|
|
|
636
|
my @action_arg = (); |
879
|
446
|
100
|
|
|
|
924
|
if ( scalar @rhs ) { |
880
|
416
|
|
66
|
|
|
2194
|
$action_name ||= 'MyAction::rule_' . scalar @rules; |
881
|
416
|
|
|
|
|
2267
|
my ( $action, $ranking_action ) = |
882
|
|
|
|
|
|
|
$gen_closure->( $lhs, \@rhs, $action_name ); |
883
|
416
|
100
|
|
|
|
10716
|
if ( defined $action ) { |
884
|
208
|
|
|
|
|
617
|
$closure{"!$action_name"} = $action; |
885
|
208
|
|
|
|
|
462
|
push @action_arg, action => "!$action_name"; |
886
|
|
|
|
|
|
|
} |
887
|
416
|
100
|
|
|
|
1071
|
if ( defined $ranking_action ) { |
888
|
2
|
|
|
|
|
10
|
$closure{"!r!$action_name"} = $ranking_action; |
889
|
2
|
|
|
|
|
20
|
push @action_arg, ranking_action => "!r!$action_name"; |
890
|
2
|
|
|
|
|
4
|
$has_ranking_action++; |
891
|
|
|
|
|
|
|
} |
892
|
|
|
|
|
|
|
} ## end if ( scalar @rhs ) |
893
|
446
|
|
|
|
|
11625
|
push @rules, { lhs => $lhs, rhs => \@rhs, @action_arg }; |
894
|
|
|
|
|
|
|
} ## end for my $line ( split /\n/xms, $reference_grammar ) |
895
|
|
|
|
|
|
|
|
896
|
2
|
|
|
|
|
162
|
my $grammar = Marpa::PP::Grammar->new( |
897
|
|
|
|
|
|
|
{ start => 'prog', |
898
|
|
|
|
|
|
|
rules => \@rules, |
899
|
|
|
|
|
|
|
lhs_terminals => 0, |
900
|
|
|
|
|
|
|
strip => 0 |
901
|
|
|
|
|
|
|
} |
902
|
|
|
|
|
|
|
); |
903
|
|
|
|
|
|
|
|
904
|
2
|
|
|
|
|
22
|
$grammar->precompute(); |
905
|
|
|
|
|
|
|
|
906
|
2
|
|
|
|
|
511
|
return bless { |
907
|
|
|
|
|
|
|
grammar => $grammar, |
908
|
|
|
|
|
|
|
closure => \%closure, |
909
|
|
|
|
|
|
|
has_ranking_action => $has_ranking_action |
910
|
|
|
|
|
|
|
}, $class; |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Perl::new |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
my @RECCE_NAMED_ARGUMENTS = |
915
|
|
|
|
|
|
|
qw(trace_tasks trace_terminals trace_values trace_actions); |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
sub token_not_accepted { |
918
|
0
|
|
|
0
|
|
0
|
my ( $ppi_token, $token_name, $token_value, $length ) = @_; |
919
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Maxdepth = 2; |
920
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Terse = 1; |
921
|
0
|
0
|
|
|
|
0
|
say {*STDERR} $Marpa::PP::Perl::RECOGNIZER->show_progress() |
|
0
|
|
|
|
|
0
|
|
922
|
|
|
|
|
|
|
or die "say: $ERRNO"; |
923
|
0
|
|
|
|
|
0
|
my $perl_token_desc; |
924
|
0
|
0
|
|
|
|
0
|
if ( not defined $token_name ) { |
925
|
0
|
|
|
|
|
0
|
$perl_token_desc = 'Undefined Perl token was not accepted: '; |
926
|
|
|
|
|
|
|
} |
927
|
|
|
|
|
|
|
else { |
928
|
0
|
|
|
|
|
0
|
$perl_token_desc = qq{Perl token "$token_name" was not accepted: }; |
929
|
|
|
|
|
|
|
} |
930
|
0
|
0
|
0
|
|
|
0
|
if ( defined $length and $length != 1 ) { |
931
|
0
|
|
|
|
|
0
|
$perl_token_desc .= ' length=' . $length; |
932
|
|
|
|
|
|
|
} |
933
|
0
|
|
|
|
|
0
|
$perl_token_desc .= Data::Dumper::Dumper($token_value); |
934
|
0
|
|
|
|
|
0
|
Carp::croak( |
935
|
|
|
|
|
|
|
"$perl_token_desc", 'PPI token is ', |
936
|
|
|
|
|
|
|
( ref $ppi_token ), q{: }, |
937
|
|
|
|
|
|
|
$ppi_token->logical_filename(), q{:}, |
938
|
|
|
|
|
|
|
$ppi_token->logical_line_number(), q{:}, |
939
|
|
|
|
|
|
|
$ppi_token->column_number(), q{, }, |
940
|
|
|
|
|
|
|
q{content="}, $ppi_token->content(), |
941
|
|
|
|
|
|
|
q{"} |
942
|
|
|
|
|
|
|
); |
943
|
|
|
|
|
|
|
} ## end sub token_not_accepted |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
sub unknown_ppi_token { |
946
|
0
|
|
|
0
|
|
0
|
my ($ppi_token) = @_; |
947
|
0
|
|
|
|
|
0
|
die 'Failed at Token: ', Data::Dumper::Dumper($ppi_token), |
948
|
|
|
|
|
|
|
'Marpa::PP::Perl did not know how to process token', |
949
|
|
|
|
|
|
|
Marpa::PP::Perl::default_show_location($ppi_token), "\n"; |
950
|
|
|
|
|
|
|
} ## end sub unknown_ppi_token |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
sub Marpa::PP::Perl::parse { |
953
|
|
|
|
|
|
|
|
954
|
16
|
|
|
16
|
0
|
168430
|
my ( $parser, $input, $hash_arg ) = @_; |
955
|
|
|
|
|
|
|
|
956
|
16
|
|
50
|
|
|
152
|
$hash_arg //= {}; |
957
|
|
|
|
|
|
|
|
958
|
16
|
|
|
|
|
54
|
my @recce_args = (); |
959
|
16
|
|
|
|
|
39
|
HASH_ARG: while ( my ( $arg, $value ) = each %{$hash_arg} ) { |
|
16
|
|
|
|
|
112
|
|
960
|
0
|
0
|
|
|
|
0
|
if ( $arg ~~ \@RECCE_NAMED_ARGUMENTS ) { |
961
|
0
|
|
|
|
|
0
|
push @recce_args, $arg, $value; |
962
|
0
|
|
|
|
|
0
|
next HASH_ARG; |
963
|
|
|
|
|
|
|
} |
964
|
0
|
|
|
|
|
0
|
Carp::croak("Unknown hash arg: $arg"); |
965
|
|
|
|
|
|
|
} ## end while ( my ( $arg, $value ) = each %{$hash_arg} ) |
966
|
|
|
|
|
|
|
|
967
|
16
|
|
|
|
|
75
|
my $grammar = $parser->{grammar}; |
968
|
16
|
100
|
|
|
|
93
|
$parser->{has_ranking_action} |
969
|
|
|
|
|
|
|
and push @recce_args, ranking_method => 'constant'; |
970
|
|
|
|
|
|
|
|
971
|
16
|
|
|
|
|
233
|
my $recce = Marpa::PP::Recognizer->new( |
972
|
|
|
|
|
|
|
{ grammar => $grammar, |
973
|
|
|
|
|
|
|
mode => 'stream', |
974
|
|
|
|
|
|
|
closures => $parser->{closure}, |
975
|
|
|
|
|
|
|
@recce_args |
976
|
|
|
|
|
|
|
} |
977
|
|
|
|
|
|
|
); |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
# This is convenient for making the recognizer available to |
980
|
|
|
|
|
|
|
# error messages |
981
|
16
|
|
|
|
|
74
|
local $Marpa::PP::Perl::RECOGNIZER = $recce; |
982
|
|
|
|
|
|
|
|
983
|
16
|
|
|
|
|
187
|
my $document = PPI::Document->new($input); |
984
|
16
|
|
|
|
|
191067
|
$document->index_locations(); |
985
|
16
|
|
|
|
|
56788
|
my @PPI_tokens = $document->tokens(); |
986
|
16
|
|
|
|
|
4473
|
my @earleme_to_PPI_token; |
987
|
|
|
|
|
|
|
my $perl_type; |
988
|
|
|
|
|
|
|
|
989
|
16
|
|
|
|
|
68
|
local $Marpa::PP::Perl::Internal::CONTEXT = |
990
|
|
|
|
|
|
|
[ \@PPI_tokens, \@earleme_to_PPI_token ]; |
991
|
|
|
|
|
|
|
TOKEN: |
992
|
16
|
|
|
|
|
97
|
for ( |
993
|
|
|
|
|
|
|
my $PPI_token_ix = 0; |
994
|
|
|
|
|
|
|
$PPI_token_ix <= $#PPI_tokens; |
995
|
|
|
|
|
|
|
$PPI_token_ix++ |
996
|
|
|
|
|
|
|
) |
997
|
|
|
|
|
|
|
{ |
998
|
943
|
|
|
|
|
4721
|
my $current_earleme = $recce->current_earleme(); |
999
|
943
|
|
100
|
|
|
5988
|
$earleme_to_PPI_token[$current_earleme] //= $PPI_token_ix; |
1000
|
943
|
|
|
|
|
5012
|
my $token = $PPI_tokens[$PPI_token_ix]; |
1001
|
943
|
|
|
|
|
4444
|
my $PPI_type = ref $token; |
1002
|
943
|
100
|
|
|
|
4074
|
next TOKEN if $PPI_type eq 'PPI::Token::Whitespace'; |
1003
|
637
|
50
|
|
|
|
1539
|
next TOKEN if $PPI_type eq 'PPI::Token::Comment'; |
1004
|
637
|
|
|
|
|
1663
|
my $last_perl_type = $perl_type; |
1005
|
637
|
|
|
|
|
1085
|
$perl_type = undef; |
1006
|
|
|
|
|
|
|
|
1007
|
637
|
100
|
|
|
|
1965
|
if ( $PPI_type eq 'PPI::Token::Symbol' ) { |
1008
|
71
|
|
|
|
|
1181
|
my ( $sigil, $word ) = |
1009
|
|
|
|
|
|
|
( $token->{content} =~ / \A ([\$]) (\w*) \z /xms ); |
1010
|
71
|
50
|
33
|
|
|
701
|
if ( not defined $sigil or $sigil ne q{$} ) { |
1011
|
0
|
|
|
|
|
0
|
Carp::croak( 'Unknown symbol type: ', |
1012
|
|
|
|
|
|
|
Data::Dumper::Dumper($token) ); |
1013
|
0
|
|
|
|
|
0
|
next TOKEN; |
1014
|
|
|
|
|
|
|
} |
1015
|
71
|
50
|
|
|
|
475
|
defined $recce->read( 'DOLLAR', $sigil ) |
1016
|
|
|
|
|
|
|
or token_not_accepted( $token, 'DOLLAR', $sigil ); |
1017
|
71
|
50
|
|
|
|
357
|
defined $recce->read( 'WORD', $word ) |
1018
|
|
|
|
|
|
|
or token_not_accepted( $token, 'WORD', $word ); |
1019
|
71
|
|
|
|
|
521
|
next TOKEN; |
1020
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Symbol' ) |
1021
|
|
|
|
|
|
|
|
1022
|
566
|
100
|
|
|
|
1524
|
if ( $PPI_type eq 'PPI::Token::Cast' ) { |
1023
|
30
|
|
|
|
|
1276
|
my $content = $token->{content}; |
1024
|
30
|
|
|
|
|
53
|
my $token_found; |
1025
|
30
|
|
|
|
|
156
|
for my $cast ( split //xms, $content ) { |
1026
|
30
|
|
|
|
|
92
|
$perl_type = $perl_type_by_cast{$content}; |
1027
|
30
|
50
|
|
|
|
96
|
if ( not defined $perl_type ) { |
1028
|
0
|
|
|
|
|
0
|
die qq{Unknown $PPI_type: "$content":}, |
1029
|
|
|
|
|
|
|
Marpa::PP::Perl::default_show_location($token), |
1030
|
|
|
|
|
|
|
"\n"; |
1031
|
|
|
|
|
|
|
} |
1032
|
30
|
|
|
|
|
55
|
$token_found = 1; |
1033
|
30
|
50
|
|
|
|
164
|
defined $recce->read( $perl_type, $cast ) |
1034
|
|
|
|
|
|
|
or token_not_accepted( $token, $perl_type, $cast ); |
1035
|
|
|
|
|
|
|
} ## end for my $cast ( split //xms, $content ) |
1036
|
30
|
50
|
|
|
|
101
|
defined $token_found or unknown_ppi_token($token); |
1037
|
30
|
|
|
|
|
150
|
next TOKEN; |
1038
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Cast' ) |
1039
|
|
|
|
|
|
|
|
1040
|
536
|
100
|
|
|
|
1182
|
if ( $PPI_type eq 'PPI::Token::Word' ) { |
1041
|
18
|
|
|
|
|
73
|
my $content = $token->{content}; |
1042
|
18
|
|
50
|
|
|
99
|
$perl_type = $perl_type_by_word{$content} // 'WORD'; |
1043
|
18
|
50
|
|
|
|
106
|
defined $recce->read( $perl_type, $content ) |
1044
|
|
|
|
|
|
|
or token_not_accepted( $token, $perl_type, $content ); |
1045
|
18
|
|
|
|
|
105
|
next TOKEN; |
1046
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Word' ) |
1047
|
|
|
|
|
|
|
|
1048
|
518
|
100
|
|
|
|
2041
|
if ( $PPI_type eq 'PPI::Token::Operator' ) { |
1049
|
123
|
|
|
|
|
497
|
my $content = $token->{content}; |
1050
|
123
|
|
|
|
|
441
|
$perl_type = $perl_type_by_op{$content}; |
1051
|
123
|
50
|
|
|
|
304
|
if ( not defined $perl_type ) { |
1052
|
0
|
|
|
|
|
0
|
die qq{Unknown $PPI_type: "$content":}, |
1053
|
|
|
|
|
|
|
Marpa::PP::Perl::default_show_location($token), |
1054
|
|
|
|
|
|
|
"\n"; |
1055
|
|
|
|
|
|
|
} |
1056
|
123
|
100
|
|
|
|
392
|
if ( $perl_type eq 'PLUS' ) { |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
# Apply the "ruby slippers" |
1059
|
|
|
|
|
|
|
# Make the plus sign be whatever the parser |
1060
|
|
|
|
|
|
|
# wishes it was |
1061
|
1
|
|
|
|
|
5
|
my @potential_types = qw(ADDOP PLUS); |
1062
|
1
|
|
|
|
|
6
|
my $expected_tokens = $recce->terminals_expected(); |
1063
|
1
|
|
|
|
|
3
|
my $token_found; |
1064
|
1
|
|
|
|
|
3
|
TYPE: for my $type (@potential_types) { |
1065
|
2
|
100
|
|
|
|
19
|
next TYPE if not $type ~~ $expected_tokens; |
1066
|
1
|
|
|
|
|
3
|
$token_found = 1; |
1067
|
1
|
50
|
|
|
|
6
|
defined $recce->alternative( $type, $content, 1 ) |
1068
|
|
|
|
|
|
|
or token_not_accepted( $token, $type, $content, 1 ); |
1069
|
|
|
|
|
|
|
} ## end for my $type (@potential_types) |
1070
|
1
|
50
|
|
|
|
5
|
defined $token_found or unknown_ppi_token($token); |
1071
|
1
|
|
|
|
|
6
|
$recce->earleme_complete(); |
1072
|
1
|
|
|
|
|
10
|
next TOKEN; |
1073
|
|
|
|
|
|
|
} ## end if ( $perl_type eq 'PLUS' ) |
1074
|
122
|
50
|
|
|
|
300
|
if ( $perl_type eq 'MINUS' ) { |
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
# Apply the "ruby slippers" |
1077
|
|
|
|
|
|
|
# Make the plus sign be whatever the parser |
1078
|
|
|
|
|
|
|
# wishes it was |
1079
|
0
|
|
|
|
|
0
|
my $expected_tokens = $recce->terminals_expected(); |
1080
|
0
|
|
|
|
|
0
|
my @potential_types = qw(ADDOP UMINUS); |
1081
|
0
|
|
|
|
|
0
|
my $token_found; |
1082
|
0
|
|
|
|
|
0
|
TYPE: for my $type (@potential_types) { |
1083
|
0
|
0
|
|
|
|
0
|
next TYPE if not $type ~~ $expected_tokens; |
1084
|
0
|
|
|
|
|
0
|
$token_found = 1; |
1085
|
0
|
0
|
|
|
|
0
|
defined $recce->alternative( $type, $content, 1 ) |
1086
|
|
|
|
|
|
|
or token_not_accepted( $token, $type, $content, 1 ); |
1087
|
|
|
|
|
|
|
} ## end for my $type (@potential_types) |
1088
|
0
|
0
|
|
|
|
0
|
defined $token_found or unknown_ppi_token($token); |
1089
|
0
|
|
|
|
|
0
|
$recce->earleme_complete(); |
1090
|
0
|
|
|
|
|
0
|
next TOKEN; |
1091
|
|
|
|
|
|
|
} ## end if ( $perl_type eq 'MINUS' ) |
1092
|
122
|
50
|
|
|
|
652
|
defined $recce->read( $perl_type, $content ) |
1093
|
|
|
|
|
|
|
or token_not_accepted( $token, $perl_type, $content ); |
1094
|
122
|
|
|
|
|
3024
|
next TOKEN; |
1095
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Operator' ) |
1096
|
|
|
|
|
|
|
|
1097
|
395
|
100
|
|
|
|
1232
|
if ( $PPI_type eq 'PPI::Token::Structure' ) { |
1098
|
282
|
|
|
|
|
1066
|
my $content = $token->{content}; |
1099
|
282
|
|
|
|
|
971
|
$perl_type = $perl_type_by_structure{$content}; |
1100
|
282
|
|
|
|
|
1490
|
my $expected_tokens = $recce->terminals_expected(); |
1101
|
282
|
50
|
|
|
|
742
|
if ( not defined $perl_type ) { |
1102
|
0
|
|
|
|
|
0
|
die qq{Unknown $PPI_type: "$content":}, |
1103
|
|
|
|
|
|
|
Marpa::PP::Perl::default_show_location($token), |
1104
|
|
|
|
|
|
|
"\n"; |
1105
|
|
|
|
|
|
|
} |
1106
|
282
|
100
|
|
|
|
897
|
if ( $perl_type eq 'RCURLY' ) { |
1107
|
65
|
50
|
66
|
|
|
749
|
if (( not defined $last_perl_type |
|
|
|
33
|
|
|
|
|
1108
|
|
|
|
|
|
|
or $last_perl_type ne 'SEMI' |
1109
|
|
|
|
|
|
|
) |
1110
|
|
|
|
|
|
|
and 'SEMI' ~~ $expected_tokens |
1111
|
|
|
|
|
|
|
) |
1112
|
|
|
|
|
|
|
{ |
1113
|
65
|
50
|
|
|
|
403
|
defined $recce->read( 'SEMI', q{;} ) |
1114
|
|
|
|
|
|
|
or token_not_accepted( $token, 'SEMI', q{;} ); |
1115
|
|
|
|
|
|
|
} ## end if ( ( not defined $last_perl_type or ...)) |
1116
|
65
|
50
|
|
|
|
378
|
defined $recce->read( $perl_type, $content ) |
1117
|
|
|
|
|
|
|
or token_not_accepted( $token, $perl_type, $content ); |
1118
|
65
|
|
|
|
|
833
|
next TOKEN; |
1119
|
|
|
|
|
|
|
} ## end if ( $perl_type eq 'RCURLY' ) |
1120
|
217
|
100
|
|
|
|
689
|
if ( $perl_type eq 'LCURLY' ) { |
1121
|
65
|
|
|
|
|
188
|
my @potential_types = (); |
1122
|
65
|
|
|
|
|
136
|
push @potential_types, 'LCURLY'; |
1123
|
65
|
100
|
100
|
|
|
528
|
if ( not defined $last_perl_type |
1124
|
|
|
|
|
|
|
or $last_perl_type ne 'DO' ) |
1125
|
|
|
|
|
|
|
{ |
1126
|
58
|
|
|
|
|
145
|
push @potential_types, 'HASHBRACK'; |
1127
|
|
|
|
|
|
|
} |
1128
|
65
|
|
|
|
|
157
|
my $token_found; |
1129
|
65
|
|
|
|
|
154
|
TYPE: for my $type (@potential_types) { |
1130
|
123
|
100
|
|
|
|
811
|
next TYPE if not $type ~~ $expected_tokens; |
1131
|
72
|
|
|
|
|
128
|
$token_found = 1; |
1132
|
72
|
50
|
|
|
|
314
|
defined $recce->alternative( $type, $content, 1 ) |
1133
|
|
|
|
|
|
|
or token_not_accepted( $token, $type, $content, 1 ); |
1134
|
|
|
|
|
|
|
} ## end for my $type (@potential_types) |
1135
|
65
|
50
|
|
|
|
205
|
defined $token_found or unknown_ppi_token($token); |
1136
|
65
|
|
|
|
|
695
|
$recce->earleme_complete(); |
1137
|
65
|
|
|
|
|
654
|
next TOKEN; |
1138
|
|
|
|
|
|
|
} ## end if ( $perl_type eq 'LCURLY' ) |
1139
|
152
|
50
|
|
|
|
795
|
defined $recce->read( $perl_type, $content ) |
1140
|
|
|
|
|
|
|
or token_not_accepted( $token, $perl_type, $content ); |
1141
|
152
|
|
|
|
|
1549
|
next TOKEN; |
1142
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Structure' ) |
1143
|
|
|
|
|
|
|
|
1144
|
113
|
100
|
|
|
|
325
|
if ( $PPI_type eq 'PPI::Token::Number' ) { |
1145
|
59
|
|
|
|
|
168
|
my $content = $token->{content}; |
1146
|
59
|
50
|
|
|
|
376
|
defined $recce->read( 'THING', $content + 0 ) |
1147
|
|
|
|
|
|
|
or token_not_accepted( $token, 'THING', $content + 0 ); |
1148
|
59
|
|
|
|
|
385
|
next TOKEN; |
1149
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Number' ) |
1150
|
54
|
50
|
|
|
|
191
|
if ( $PPI_type eq 'PPI::Token::Quote::Single' ) { |
1151
|
54
|
|
|
|
|
261
|
my $content = $token->{content}; |
1152
|
|
|
|
|
|
|
## no critic (BuiltinFunctions::ProhibitStringyEval) |
1153
|
54
|
|
|
|
|
7166
|
my $string = eval $content; |
1154
|
|
|
|
|
|
|
## use critic |
1155
|
54
|
50
|
|
|
|
503
|
Carp::Croak("eval failed: $EVAL_ERROR") |
1156
|
|
|
|
|
|
|
if not defined $string; |
1157
|
54
|
50
|
|
|
|
568
|
defined $recce->read( 'THING', $string ) |
1158
|
|
|
|
|
|
|
or token_not_accepted( $token, 'THING', $string ); |
1159
|
54
|
|
|
|
|
660
|
next TOKEN; |
1160
|
|
|
|
|
|
|
} ## end if ( $PPI_type eq 'PPI::Token::Quote::Single' ) |
1161
|
|
|
|
|
|
|
|
1162
|
0
|
|
|
|
|
0
|
unknown_ppi_token($token); |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
} ## end for ( my $PPI_token_ix = 0; $PPI_token_ix <= $#PPI_tokens...) |
1165
|
|
|
|
|
|
|
|
1166
|
16
|
|
|
|
|
108
|
$recce->end_input(); |
1167
|
16
|
100
|
|
|
|
57
|
if (wantarray) { |
1168
|
4
|
|
|
|
|
8
|
my @values = (); |
1169
|
4
|
|
|
|
|
31
|
while ( defined( my $value_ref = $recce->value() ) ) { |
1170
|
0
|
|
|
|
|
0
|
push @values, ${$value_ref}; |
|
0
|
|
|
|
|
0
|
|
1171
|
|
|
|
|
|
|
} |
1172
|
4
|
|
|
|
|
120
|
return @values; |
1173
|
|
|
|
|
|
|
} ## end if (wantarray) |
1174
|
|
|
|
|
|
|
else { |
1175
|
12
|
|
|
|
|
119
|
my $value_ref = $recce->value(); |
1176
|
12
|
|
|
|
|
1149
|
return $value_ref; |
1177
|
|
|
|
|
|
|
} |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Perl::parse |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
# Context-sensitive callback for |
1182
|
|
|
|
|
|
|
# application-provided closures to use. |
1183
|
|
|
|
|
|
|
sub Marpa::PP::Perl::token { |
1184
|
58
|
50
|
|
58
|
0
|
654
|
Marpa::PP::exception('No Perl context for token callback') |
1185
|
|
|
|
|
|
|
if not my $context = $Marpa::PP::Perl::Internal::CONTEXT; |
1186
|
58
|
|
|
|
|
61
|
my ( $PPI_tokens, $earleme_to_token ) = @{$context}; |
|
58
|
|
|
|
|
102
|
|
1187
|
58
|
|
|
|
|
195
|
my $earleme = Marpa::PP::location(); |
1188
|
58
|
|
|
|
|
279
|
return $PPI_tokens->[ $earleme_to_token->[$earleme] ]; |
1189
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Perl::token |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
sub Marpa::PP::Perl::default_show_location { |
1192
|
0
|
|
|
0
|
0
|
|
my ($token) = @_; |
1193
|
0
|
|
|
|
|
|
my $file_name = $token->logical_filename(); |
1194
|
0
|
0
|
|
|
|
|
my $file_description = $file_name ? qq{ file "$file_name"} : q{}; |
1195
|
|
|
|
|
|
|
return |
1196
|
0
|
|
|
|
|
|
"$file_description at line " |
1197
|
|
|
|
|
|
|
. $token->logical_line_number() |
1198
|
|
|
|
|
|
|
. q{, column } |
1199
|
|
|
|
|
|
|
. $token->column_number(); |
1200
|
|
|
|
|
|
|
} ## end sub Marpa::PP::Perl::default_show_location |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
1; |