Mercurial > hg > isophonics-drupal-site
comparison vendor/nikic/php-parser/grammar/php7.y @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 5fb285c0d0e3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 %pure_parser | |
2 %expect 2 | |
3 | |
4 %tokens | |
5 | |
6 %% | |
7 | |
8 start: | |
9 top_statement_list { $$ = $this->handleNamespaces($1); } | |
10 ; | |
11 | |
12 top_statement_list_ex: | |
13 top_statement_list_ex top_statement { pushNormalizing($1, $2); } | |
14 | /* empty */ { init(); } | |
15 ; | |
16 | |
17 top_statement_list: | |
18 top_statement_list_ex | |
19 { makeNop($nop, $this->lookaheadStartAttributes); | |
20 if ($nop !== null) { $1[] = $nop; } $$ = $1; } | |
21 ; | |
22 | |
23 reserved_non_modifiers: | |
24 T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND | |
25 | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | |
26 | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | |
27 | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO | |
28 | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | |
29 | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS | |
30 | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | |
31 ; | |
32 | |
33 semi_reserved: | |
34 reserved_non_modifiers | |
35 | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | |
36 ; | |
37 | |
38 identifier: | |
39 T_STRING { $$ = $1; } | |
40 | semi_reserved { $$ = $1; } | |
41 ; | |
42 | |
43 namespace_name_parts: | |
44 T_STRING { init($1); } | |
45 | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } | |
46 ; | |
47 | |
48 namespace_name: | |
49 namespace_name_parts { $$ = Name[$1]; } | |
50 ; | |
51 | |
52 semi: | |
53 ';' { /* nothing */ } | |
54 | error { /* nothing */ } | |
55 ; | |
56 | |
57 no_comma: | |
58 /* empty */ { /* nothing */ } | |
59 | ',' { $this->emitError(new Error('A trailing comma is not allowed here', attributes())); } | |
60 ; | |
61 | |
62 optional_comma: | |
63 /* empty */ | |
64 | ',' | |
65 | |
66 top_statement: | |
67 statement { $$ = $1; } | |
68 | function_declaration_statement { $$ = $1; } | |
69 | class_declaration_statement { $$ = $1; } | |
70 | T_HALT_COMPILER | |
71 { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } | |
72 | T_NAMESPACE namespace_name semi | |
73 { $$ = Stmt\Namespace_[$2, null]; | |
74 $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); | |
75 $this->checkNamespace($$); } | |
76 | T_NAMESPACE namespace_name '{' top_statement_list '}' | |
77 { $$ = Stmt\Namespace_[$2, $4]; | |
78 $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); | |
79 $this->checkNamespace($$); } | |
80 | T_NAMESPACE '{' top_statement_list '}' | |
81 { $$ = Stmt\Namespace_[null, $3]; | |
82 $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); | |
83 $this->checkNamespace($$); } | |
84 | T_USE use_declarations semi { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } | |
85 | T_USE use_type use_declarations semi { $$ = Stmt\Use_[$3, $2]; } | |
86 | group_use_declaration semi { $$ = $1; } | |
87 | T_CONST constant_declaration_list semi { $$ = Stmt\Const_[$2]; } | |
88 ; | |
89 | |
90 use_type: | |
91 T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } | |
92 | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } | |
93 ; | |
94 | |
95 /* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ | |
96 group_use_declaration: | |
97 T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' | |
98 { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } | |
99 | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' | |
100 { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } | |
101 | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' | |
102 { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } | |
103 | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' | |
104 { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } | |
105 ; | |
106 | |
107 unprefixed_use_declarations: | |
108 non_empty_unprefixed_use_declarations optional_comma { $$ = $1; } | |
109 ; | |
110 | |
111 non_empty_unprefixed_use_declarations: | |
112 non_empty_unprefixed_use_declarations ',' unprefixed_use_declaration | |
113 { push($1, $3); } | |
114 | unprefixed_use_declaration { init($1); } | |
115 ; | |
116 | |
117 use_declarations: | |
118 non_empty_use_declarations no_comma { $$ = $1; } | |
119 ; | |
120 | |
121 non_empty_use_declarations: | |
122 non_empty_use_declarations ',' use_declaration { push($1, $3); } | |
123 | use_declaration { init($1); } | |
124 ; | |
125 | |
126 inline_use_declarations: | |
127 non_empty_inline_use_declarations optional_comma { $$ = $1; } | |
128 ; | |
129 | |
130 non_empty_inline_use_declarations: | |
131 non_empty_inline_use_declarations ',' inline_use_declaration | |
132 { push($1, $3); } | |
133 | inline_use_declaration { init($1); } | |
134 ; | |
135 | |
136 unprefixed_use_declaration: | |
137 namespace_name | |
138 { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } | |
139 | namespace_name T_AS T_STRING | |
140 { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } | |
141 ; | |
142 | |
143 use_declaration: | |
144 unprefixed_use_declaration { $$ = $1; } | |
145 | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } | |
146 ; | |
147 | |
148 inline_use_declaration: | |
149 unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } | |
150 | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } | |
151 ; | |
152 | |
153 constant_declaration_list: | |
154 non_empty_constant_declaration_list no_comma { $$ = $1; } | |
155 ; | |
156 | |
157 non_empty_constant_declaration_list: | |
158 non_empty_constant_declaration_list ',' constant_declaration | |
159 { push($1, $3); } | |
160 | constant_declaration { init($1); } | |
161 ; | |
162 | |
163 constant_declaration: | |
164 T_STRING '=' expr { $$ = Node\Const_[$1, $3]; } | |
165 ; | |
166 | |
167 class_const_list: | |
168 non_empty_class_const_list no_comma { $$ = $1; } | |
169 ; | |
170 | |
171 non_empty_class_const_list: | |
172 non_empty_class_const_list ',' class_const { push($1, $3); } | |
173 | class_const { init($1); } | |
174 ; | |
175 | |
176 class_const: | |
177 identifier '=' expr { $$ = Node\Const_[$1, $3]; } | |
178 ; | |
179 | |
180 inner_statement_list_ex: | |
181 inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } | |
182 | /* empty */ { init(); } | |
183 ; | |
184 | |
185 inner_statement_list: | |
186 inner_statement_list_ex | |
187 { makeNop($nop, $this->lookaheadStartAttributes); | |
188 if ($nop !== null) { $1[] = $nop; } $$ = $1; } | |
189 ; | |
190 | |
191 inner_statement: | |
192 statement { $$ = $1; } | |
193 | function_declaration_statement { $$ = $1; } | |
194 | class_declaration_statement { $$ = $1; } | |
195 | T_HALT_COMPILER | |
196 { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } | |
197 ; | |
198 | |
199 non_empty_statement: | |
200 '{' inner_statement_list '}' | |
201 { | |
202 if ($2) { | |
203 $$ = $2; prependLeadingComments($$); | |
204 } else { | |
205 makeNop($$, $this->startAttributeStack[#1]); | |
206 if (null === $$) { $$ = array(); } | |
207 } | |
208 } | |
209 | T_IF '(' expr ')' statement elseif_list else_single | |
210 { $$ = Stmt\If_[$3, ['stmts' => toArray($5), 'elseifs' => $6, 'else' => $7]]; } | |
211 | T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' | |
212 { $$ = Stmt\If_[$3, ['stmts' => $6, 'elseifs' => $7, 'else' => $8]]; } | |
213 | T_WHILE '(' expr ')' while_statement { $$ = Stmt\While_[$3, $5]; } | |
214 | T_DO statement T_WHILE '(' expr ')' ';' { $$ = Stmt\Do_ [$5, toArray($2)]; } | |
215 | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement | |
216 { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } | |
217 | T_SWITCH '(' expr ')' switch_case_list { $$ = Stmt\Switch_[$3, $5]; } | |
218 | T_BREAK optional_expr semi { $$ = Stmt\Break_[$2]; } | |
219 | T_CONTINUE optional_expr semi { $$ = Stmt\Continue_[$2]; } | |
220 | T_RETURN optional_expr semi { $$ = Stmt\Return_[$2]; } | |
221 | T_GLOBAL global_var_list semi { $$ = Stmt\Global_[$2]; } | |
222 | T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; } | |
223 | T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; } | |
224 | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } | |
225 | expr semi { $$ = $1; } | |
226 | T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; } | |
227 | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement | |
228 { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } | |
229 | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement | |
230 { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } | |
231 | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } | |
232 | T_TRY '{' inner_statement_list '}' catches optional_finally | |
233 { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } | |
234 | T_THROW expr semi { $$ = Stmt\Throw_[$2]; } | |
235 | T_GOTO T_STRING semi { $$ = Stmt\Goto_[$2]; } | |
236 | T_STRING ':' { $$ = Stmt\Label[$1]; } | |
237 | error { $$ = array(); /* means: no statement */ } | |
238 ; | |
239 | |
240 statement: | |
241 non_empty_statement { $$ = $1; } | |
242 | ';' | |
243 { makeNop($$, $this->startAttributeStack[#1]); | |
244 if ($$ === null) $$ = array(); /* means: no statement */ } | |
245 ; | |
246 | |
247 catches: | |
248 /* empty */ { init(); } | |
249 | catches catch { push($1, $2); } | |
250 ; | |
251 | |
252 name_union: | |
253 name { init($1); } | |
254 | name_union '|' name { push($1, $3); } | |
255 ; | |
256 | |
257 catch: | |
258 T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}' | |
259 { $$ = Stmt\Catch_[$3, parseVar($4), $7]; } | |
260 ; | |
261 | |
262 optional_finally: | |
263 /* empty */ { $$ = null; } | |
264 | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } | |
265 ; | |
266 | |
267 variables_list: | |
268 non_empty_variables_list no_comma { $$ = $1; } | |
269 ; | |
270 | |
271 non_empty_variables_list: | |
272 variable { init($1); } | |
273 | non_empty_variables_list ',' variable { push($1, $3); } | |
274 ; | |
275 | |
276 optional_ref: | |
277 /* empty */ { $$ = false; } | |
278 | '&' { $$ = true; } | |
279 ; | |
280 | |
281 optional_ellipsis: | |
282 /* empty */ { $$ = false; } | |
283 | T_ELLIPSIS { $$ = true; } | |
284 ; | |
285 | |
286 function_declaration_statement: | |
287 T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' | |
288 { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } | |
289 ; | |
290 | |
291 class_declaration_statement: | |
292 class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' | |
293 { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; | |
294 $this->checkClass($$, #2); } | |
295 | T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' | |
296 { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; | |
297 $this->checkInterface($$, #2); } | |
298 | T_TRAIT T_STRING '{' class_statement_list '}' | |
299 { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } | |
300 ; | |
301 | |
302 class_entry_type: | |
303 T_CLASS { $$ = 0; } | |
304 | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | |
305 | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } | |
306 ; | |
307 | |
308 extends_from: | |
309 /* empty */ { $$ = null; } | |
310 | T_EXTENDS class_name { $$ = $2; } | |
311 ; | |
312 | |
313 interface_extends_list: | |
314 /* empty */ { $$ = array(); } | |
315 | T_EXTENDS class_name_list { $$ = $2; } | |
316 ; | |
317 | |
318 implements_list: | |
319 /* empty */ { $$ = array(); } | |
320 | T_IMPLEMENTS class_name_list { $$ = $2; } | |
321 ; | |
322 | |
323 class_name_list: | |
324 non_empty_class_name_list no_comma { $$ = $1; } | |
325 ; | |
326 | |
327 non_empty_class_name_list: | |
328 class_name { init($1); } | |
329 | non_empty_class_name_list ',' class_name { push($1, $3); } | |
330 ; | |
331 | |
332 for_statement: | |
333 statement { $$ = toArray($1); } | |
334 | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } | |
335 ; | |
336 | |
337 foreach_statement: | |
338 statement { $$ = toArray($1); } | |
339 | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } | |
340 ; | |
341 | |
342 declare_statement: | |
343 non_empty_statement { $$ = toArray($1); } | |
344 | ';' { $$ = null; } | |
345 | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } | |
346 ; | |
347 | |
348 declare_list: | |
349 non_empty_declare_list no_comma { $$ = $1; } | |
350 ; | |
351 | |
352 non_empty_declare_list: | |
353 declare_list_element { init($1); } | |
354 | non_empty_declare_list ',' declare_list_element { push($1, $3); } | |
355 ; | |
356 | |
357 declare_list_element: | |
358 T_STRING '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } | |
359 ; | |
360 | |
361 switch_case_list: | |
362 '{' case_list '}' { $$ = $2; } | |
363 | '{' ';' case_list '}' { $$ = $3; } | |
364 | ':' case_list T_ENDSWITCH ';' { $$ = $2; } | |
365 | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } | |
366 ; | |
367 | |
368 case_list: | |
369 /* empty */ { init(); } | |
370 | case_list case { push($1, $2); } | |
371 ; | |
372 | |
373 case: | |
374 T_CASE expr case_separator inner_statement_list { $$ = Stmt\Case_[$2, $4]; } | |
375 | T_DEFAULT case_separator inner_statement_list { $$ = Stmt\Case_[null, $3]; } | |
376 ; | |
377 | |
378 case_separator: | |
379 ':' | |
380 | ';' | |
381 ; | |
382 | |
383 while_statement: | |
384 statement { $$ = toArray($1); } | |
385 | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } | |
386 ; | |
387 | |
388 elseif_list: | |
389 /* empty */ { init(); } | |
390 | elseif_list elseif { push($1, $2); } | |
391 ; | |
392 | |
393 elseif: | |
394 T_ELSEIF '(' expr ')' statement { $$ = Stmt\ElseIf_[$3, toArray($5)]; } | |
395 ; | |
396 | |
397 new_elseif_list: | |
398 /* empty */ { init(); } | |
399 | new_elseif_list new_elseif { push($1, $2); } | |
400 ; | |
401 | |
402 new_elseif: | |
403 T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; } | |
404 ; | |
405 | |
406 else_single: | |
407 /* empty */ { $$ = null; } | |
408 | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } | |
409 ; | |
410 | |
411 new_else_single: | |
412 /* empty */ { $$ = null; } | |
413 | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } | |
414 ; | |
415 | |
416 foreach_variable: | |
417 variable { $$ = array($1, false); } | |
418 | '&' variable { $$ = array($2, true); } | |
419 | list_expr { $$ = array($1, false); } | |
420 | array_short_syntax { $$ = array($1, false); } | |
421 ; | |
422 | |
423 parameter_list: | |
424 non_empty_parameter_list no_comma { $$ = $1; } | |
425 | /* empty */ { $$ = array(); } | |
426 ; | |
427 | |
428 non_empty_parameter_list: | |
429 parameter { init($1); } | |
430 | non_empty_parameter_list ',' parameter { push($1, $3); } | |
431 ; | |
432 | |
433 parameter: | |
434 optional_param_type optional_ref optional_ellipsis T_VARIABLE | |
435 { $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); } | |
436 | optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr | |
437 { $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); } | |
438 ; | |
439 | |
440 type_expr: | |
441 type { $$ = $1; } | |
442 | '?' type { $$ = Node\NullableType[$2]; } | |
443 ; | |
444 | |
445 type: | |
446 name { $$ = $this->handleBuiltinTypes($1); } | |
447 | T_ARRAY { $$ = 'array'; } | |
448 | T_CALLABLE { $$ = 'callable'; } | |
449 ; | |
450 | |
451 optional_param_type: | |
452 /* empty */ { $$ = null; } | |
453 | type_expr { $$ = $1; } | |
454 ; | |
455 | |
456 optional_return_type: | |
457 /* empty */ { $$ = null; } | |
458 | ':' type_expr { $$ = $2; } | |
459 ; | |
460 | |
461 argument_list: | |
462 '(' ')' { $$ = array(); } | |
463 | '(' non_empty_argument_list no_comma ')' { $$ = $2; } | |
464 ; | |
465 | |
466 non_empty_argument_list: | |
467 argument { init($1); } | |
468 | non_empty_argument_list ',' argument { push($1, $3); } | |
469 ; | |
470 | |
471 argument: | |
472 expr { $$ = Node\Arg[$1, false, false]; } | |
473 | '&' variable { $$ = Node\Arg[$2, true, false]; } | |
474 | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } | |
475 ; | |
476 | |
477 global_var_list: | |
478 non_empty_global_var_list no_comma { $$ = $1; } | |
479 ; | |
480 | |
481 non_empty_global_var_list: | |
482 non_empty_global_var_list ',' global_var { push($1, $3); } | |
483 | global_var { init($1); } | |
484 ; | |
485 | |
486 global_var: | |
487 simple_variable { $$ = Expr\Variable[$1]; } | |
488 ; | |
489 | |
490 static_var_list: | |
491 non_empty_static_var_list no_comma { $$ = $1; } | |
492 ; | |
493 | |
494 non_empty_static_var_list: | |
495 non_empty_static_var_list ',' static_var { push($1, $3); } | |
496 | static_var { init($1); } | |
497 ; | |
498 | |
499 static_var: | |
500 T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } | |
501 | T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; } | |
502 ; | |
503 | |
504 class_statement_list: | |
505 class_statement_list class_statement { push($1, $2); } | |
506 | /* empty */ { init(); } | |
507 ; | |
508 | |
509 class_statement: | |
510 variable_modifiers property_declaration_list ';' | |
511 { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } | |
512 | method_modifiers T_CONST class_const_list ';' | |
513 { $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); } | |
514 | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body | |
515 { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; | |
516 $this->checkClassMethod($$, #1); } | |
517 | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } | |
518 ; | |
519 | |
520 trait_adaptations: | |
521 ';' { $$ = array(); } | |
522 | '{' trait_adaptation_list '}' { $$ = $2; } | |
523 ; | |
524 | |
525 trait_adaptation_list: | |
526 /* empty */ { init(); } | |
527 | trait_adaptation_list trait_adaptation { push($1, $2); } | |
528 ; | |
529 | |
530 trait_adaptation: | |
531 trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' | |
532 { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } | |
533 | trait_method_reference T_AS member_modifier identifier ';' | |
534 { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } | |
535 | trait_method_reference T_AS member_modifier ';' | |
536 { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } | |
537 | trait_method_reference T_AS T_STRING ';' | |
538 { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } | |
539 | trait_method_reference T_AS reserved_non_modifiers ';' | |
540 { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } | |
541 ; | |
542 | |
543 trait_method_reference_fully_qualified: | |
544 name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); } | |
545 ; | |
546 trait_method_reference: | |
547 trait_method_reference_fully_qualified { $$ = $1; } | |
548 | identifier { $$ = array(null, $1); } | |
549 ; | |
550 | |
551 method_body: | |
552 ';' /* abstract method */ { $$ = null; } | |
553 | '{' inner_statement_list '}' { $$ = $2; } | |
554 ; | |
555 | |
556 variable_modifiers: | |
557 non_empty_member_modifiers { $$ = $1; } | |
558 | T_VAR { $$ = 0; } | |
559 ; | |
560 | |
561 method_modifiers: | |
562 /* empty */ { $$ = 0; } | |
563 | non_empty_member_modifiers { $$ = $1; } | |
564 ; | |
565 | |
566 non_empty_member_modifiers: | |
567 member_modifier { $$ = $1; } | |
568 | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } | |
569 ; | |
570 | |
571 member_modifier: | |
572 T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } | |
573 | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } | |
574 | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } | |
575 | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } | |
576 | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | |
577 | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } | |
578 ; | |
579 | |
580 property_declaration_list: | |
581 non_empty_property_declaration_list no_comma { $$ = $1; } | |
582 ; | |
583 | |
584 non_empty_property_declaration_list: | |
585 property_declaration { init($1); } | |
586 | non_empty_property_declaration_list ',' property_declaration | |
587 { push($1, $3); } | |
588 ; | |
589 | |
590 property_declaration: | |
591 T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } | |
592 | T_VARIABLE '=' expr { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } | |
593 ; | |
594 | |
595 expr_list: | |
596 non_empty_expr_list no_comma { $$ = $1; } | |
597 ; | |
598 | |
599 non_empty_expr_list: | |
600 non_empty_expr_list ',' expr { push($1, $3); } | |
601 | expr { init($1); } | |
602 ; | |
603 | |
604 for_expr: | |
605 /* empty */ { $$ = array(); } | |
606 | expr_list { $$ = $1; } | |
607 ; | |
608 | |
609 expr: | |
610 variable { $$ = $1; } | |
611 | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } | |
612 | array_short_syntax '=' expr { $$ = Expr\Assign[$1, $3]; } | |
613 | variable '=' expr { $$ = Expr\Assign[$1, $3]; } | |
614 | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } | |
615 | new_expr { $$ = $1; } | |
616 | T_CLONE expr { $$ = Expr\Clone_[$2]; } | |
617 | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } | |
618 | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } | |
619 | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } | |
620 | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } | |
621 | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } | |
622 | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } | |
623 | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } | |
624 | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } | |
625 | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } | |
626 | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } | |
627 | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } | |
628 | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } | |
629 | variable T_INC { $$ = Expr\PostInc[$1]; } | |
630 | T_INC variable { $$ = Expr\PreInc [$2]; } | |
631 | variable T_DEC { $$ = Expr\PostDec[$1]; } | |
632 | T_DEC variable { $$ = Expr\PreDec [$2]; } | |
633 | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } | |
634 | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } | |
635 | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } | |
636 | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } | |
637 | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } | |
638 | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } | |
639 | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } | |
640 | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } | |
641 | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } | |
642 | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } | |
643 | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } | |
644 | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } | |
645 | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } | |
646 | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } | |
647 | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } | |
648 | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } | |
649 | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } | |
650 | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } | |
651 | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } | |
652 | '!' expr { $$ = Expr\BooleanNot[$2]; } | |
653 | '~' expr { $$ = Expr\BitwiseNot[$2]; } | |
654 | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } | |
655 | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } | |
656 | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } | |
657 | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } | |
658 | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } | |
659 | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } | |
660 | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } | |
661 | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } | |
662 | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } | |
663 | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } | |
664 | '(' expr ')' { $$ = $2; } | |
665 | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } | |
666 | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } | |
667 | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } | |
668 | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } | |
669 | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } | |
670 | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } | |
671 | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } | |
672 | T_EVAL '(' expr ')' { $$ = Expr\Eval_[$3]; } | |
673 | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } | |
674 | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } | |
675 | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } | |
676 | T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; } | |
677 | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } | |
678 | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } | |
679 | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } | |
680 | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } | |
681 | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } | |
682 | T_EXIT exit_expr | |
683 { $attrs = attributes(); | |
684 $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; | |
685 $$ = new Expr\Exit_($2, $attrs); } | |
686 | '@' expr { $$ = Expr\ErrorSuppress[$2]; } | |
687 | scalar { $$ = $1; } | |
688 | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } | |
689 | T_PRINT expr { $$ = Expr\Print_[$2]; } | |
690 | T_YIELD { $$ = Expr\Yield_[null, null]; } | |
691 | T_YIELD expr { $$ = Expr\Yield_[$2, null]; } | |
692 | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } | |
693 | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } | |
694 | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type | |
695 '{' inner_statement_list '}' | |
696 { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } | |
697 | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type | |
698 '{' inner_statement_list '}' | |
699 { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } | |
700 ; | |
701 | |
702 anonymous_class: | |
703 T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' | |
704 { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); | |
705 $this->checkClass($$[0], -1); } | |
706 | |
707 new_expr: | |
708 T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } | |
709 | T_NEW anonymous_class | |
710 { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } | |
711 ; | |
712 | |
713 lexical_vars: | |
714 /* empty */ { $$ = array(); } | |
715 | T_USE '(' lexical_var_list ')' { $$ = $3; } | |
716 ; | |
717 | |
718 lexical_var_list: | |
719 non_empty_lexical_var_list no_comma { $$ = $1; } | |
720 ; | |
721 | |
722 non_empty_lexical_var_list: | |
723 lexical_var { init($1); } | |
724 | non_empty_lexical_var_list ',' lexical_var { push($1, $3); } | |
725 ; | |
726 | |
727 lexical_var: | |
728 optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } | |
729 ; | |
730 | |
731 function_call: | |
732 name argument_list { $$ = Expr\FuncCall[$1, $2]; } | |
733 | callable_expr argument_list { $$ = Expr\FuncCall[$1, $2]; } | |
734 | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM member_name argument_list | |
735 { $$ = Expr\StaticCall[$1, $3, $4]; } | |
736 ; | |
737 | |
738 class_name: | |
739 T_STATIC { $$ = Name[$1]; } | |
740 | name { $$ = $1; } | |
741 ; | |
742 | |
743 name: | |
744 namespace_name_parts { $$ = Name[$1]; } | |
745 | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } | |
746 | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } | |
747 ; | |
748 | |
749 class_name_reference: | |
750 class_name { $$ = $1; } | |
751 | new_variable { $$ = $1; } | |
752 | error { $$ = Expr\Error[]; $this->errorState = 2; } | |
753 ; | |
754 | |
755 class_name_or_var: | |
756 class_name { $$ = $1; } | |
757 | dereferencable { $$ = $1; } | |
758 ; | |
759 | |
760 exit_expr: | |
761 /* empty */ { $$ = null; } | |
762 | '(' optional_expr ')' { $$ = $2; } | |
763 ; | |
764 | |
765 backticks_expr: | |
766 /* empty */ { $$ = array(); } | |
767 | T_ENCAPSED_AND_WHITESPACE | |
768 { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`')]); } | |
769 | encaps_list { parseEncapsed($1, '`', true); $$ = $1; } | |
770 ; | |
771 | |
772 ctor_arguments: | |
773 /* empty */ { $$ = array(); } | |
774 | argument_list { $$ = $1; } | |
775 ; | |
776 | |
777 constant: | |
778 name { $$ = Expr\ConstFetch[$1]; } | |
779 | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier | |
780 { $$ = Expr\ClassConstFetch[$1, $3]; } | |
781 /* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be | |
782 an unfinished static property fetch or unfinished scoped call. */ | |
783 | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error | |
784 { $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; } | |
785 ; | |
786 | |
787 array_short_syntax: | |
788 '[' array_pair_list ']' | |
789 { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; | |
790 $$ = new Expr\Array_($2, $attrs); } | |
791 ; | |
792 | |
793 dereferencable_scalar: | |
794 T_ARRAY '(' array_pair_list ')' | |
795 { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; | |
796 $$ = new Expr\Array_($3, $attrs); } | |
797 | array_short_syntax { $$ = $1; } | |
798 | T_CONSTANT_ENCAPSED_STRING | |
799 { $attrs = attributes(); $attrs['kind'] = strKind($1); | |
800 $$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); } | |
801 ; | |
802 | |
803 scalar: | |
804 T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } | |
805 | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } | |
806 | T_LINE { $$ = Scalar\MagicConst\Line[]; } | |
807 | T_FILE { $$ = Scalar\MagicConst\File[]; } | |
808 | T_DIR { $$ = Scalar\MagicConst\Dir[]; } | |
809 | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } | |
810 | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } | |
811 | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } | |
812 | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } | |
813 | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } | |
814 | dereferencable_scalar { $$ = $1; } | |
815 | constant { $$ = $1; } | |
816 | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC | |
817 { $attrs = attributes(); setDocStringAttrs($attrs, $1); | |
818 $$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2), $attrs); } | |
819 | T_START_HEREDOC T_END_HEREDOC | |
820 { $attrs = attributes(); setDocStringAttrs($attrs, $1); | |
821 $$ = new Scalar\String_('', $attrs); } | |
822 | '"' encaps_list '"' | |
823 { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; | |
824 parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } | |
825 | T_START_HEREDOC encaps_list T_END_HEREDOC | |
826 { $attrs = attributes(); setDocStringAttrs($attrs, $1); | |
827 parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); } | |
828 ; | |
829 | |
830 optional_expr: | |
831 /* empty */ { $$ = null; } | |
832 | expr { $$ = $1; } | |
833 ; | |
834 | |
835 dereferencable: | |
836 variable { $$ = $1; } | |
837 | '(' expr ')' { $$ = $2; } | |
838 | dereferencable_scalar { $$ = $1; } | |
839 ; | |
840 | |
841 callable_expr: | |
842 callable_variable { $$ = $1; } | |
843 | '(' expr ')' { $$ = $2; } | |
844 | dereferencable_scalar { $$ = $1; } | |
845 ; | |
846 | |
847 callable_variable: | |
848 simple_variable { $$ = Expr\Variable[$1]; } | |
849 | dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
850 | constant '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
851 | dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
852 | function_call { $$ = $1; } | |
853 | dereferencable T_OBJECT_OPERATOR property_name argument_list | |
854 { $$ = Expr\MethodCall[$1, $3, $4]; } | |
855 ; | |
856 | |
857 variable: | |
858 callable_variable { $$ = $1; } | |
859 | static_member { $$ = $1; } | |
860 | dereferencable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } | |
861 ; | |
862 | |
863 simple_variable: | |
864 T_VARIABLE { $$ = parseVar($1); } | |
865 | '$' '{' expr '}' { $$ = $3; } | |
866 | '$' simple_variable { $$ = Expr\Variable[$2]; } | |
867 | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } | |
868 ; | |
869 | |
870 static_member: | |
871 class_name_or_var T_PAAMAYIM_NEKUDOTAYIM simple_variable | |
872 { $$ = Expr\StaticPropertyFetch[$1, $3]; } | |
873 ; | |
874 | |
875 new_variable: | |
876 simple_variable { $$ = Expr\Variable[$1]; } | |
877 | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
878 | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
879 | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } | |
880 | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } | |
881 | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } | |
882 ; | |
883 | |
884 member_name: | |
885 identifier { $$ = $1; } | |
886 | '{' expr '}' { $$ = $2; } | |
887 | simple_variable { $$ = Expr\Variable[$1]; } | |
888 ; | |
889 | |
890 property_name: | |
891 T_STRING { $$ = $1; } | |
892 | '{' expr '}' { $$ = $2; } | |
893 | simple_variable { $$ = Expr\Variable[$1]; } | |
894 | error { $$ = Expr\Error[]; $this->errorState = 2; } | |
895 ; | |
896 | |
897 list_expr: | |
898 T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } | |
899 ; | |
900 | |
901 list_expr_elements: | |
902 list_expr_elements ',' list_expr_element { push($1, $3); } | |
903 | list_expr_element { init($1); } | |
904 ; | |
905 | |
906 list_expr_element: | |
907 variable { $$ = Expr\ArrayItem[$1, null, false]; } | |
908 | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } | |
909 | expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; } | |
910 | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } | |
911 | /* empty */ { $$ = null; } | |
912 ; | |
913 | |
914 array_pair_list: | |
915 inner_array_pair_list | |
916 { $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); } | |
917 ; | |
918 | |
919 inner_array_pair_list: | |
920 inner_array_pair_list ',' array_pair { push($1, $3); } | |
921 | array_pair { init($1); } | |
922 ; | |
923 | |
924 array_pair: | |
925 expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } | |
926 | expr { $$ = Expr\ArrayItem[$1, null, false]; } | |
927 | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } | |
928 | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } | |
929 | /* empty */ { $$ = null; } | |
930 ; | |
931 | |
932 encaps_list: | |
933 encaps_list encaps_var { push($1, $2); } | |
934 | encaps_list encaps_string_part { push($1, $2); } | |
935 | encaps_var { init($1); } | |
936 | encaps_string_part encaps_var { init($1, $2); } | |
937 ; | |
938 | |
939 encaps_string_part: | |
940 T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } | |
941 ; | |
942 | |
943 encaps_base_var: | |
944 T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } | |
945 ; | |
946 | |
947 encaps_var: | |
948 encaps_base_var { $$ = $1; } | |
949 | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | |
950 | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } | |
951 | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } | |
952 | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } | |
953 | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' | |
954 { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } | |
955 | T_CURLY_OPEN variable '}' { $$ = $2; } | |
956 ; | |
957 | |
958 encaps_var_offset: | |
959 T_STRING { $$ = Scalar\String_[$1]; } | |
960 | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | |
961 | '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); } | |
962 | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } | |
963 ; | |
964 | |
965 %% |