v0.3.4 - Handle commas in argument lists
[hiphop-php.git] / hphp / parser / hphp.y
bloba709a7b4106d33ed327322d66f054f1c4028bbae
1 %{
3 /* By default this grammar is set up to be used by HPHP's compile parser.
4 * However, it can be used to make parsers for different purposes by
5 * making a Parser implementation with the same interface as
6 * HPHP::Compiler::Parser in a header file specified by
7 * PARSER_DEFINITIONS_HEADER, and specifying an alternate namespace with
8 * HPHP_PARSER_NS.
9 */
11 // macros for bison
12 #define YYSTYPE HPHP::HPHP_PARSER_NS::Token
13 #define YYSTYPE_IS_TRIVIAL false
14 #define YYLTYPE HPHP::Location
15 #define YYLTYPE_IS_TRIVIAL true
16 #define YYERROR_VERBOSE
17 #define YYINITDEPTH 500
18 #define YYLEX_PARAM _p
20 #ifdef PARSER_DEFINITIONS_HEADER
21 #include PARSER_DEFINITIONS_HEADER
22 #else
23 #include "hphp/compiler/parser/parser.h"
24 #endif
26 #include <folly/Conv.h>
27 #include <folly/String.h>
29 #include "hphp/util/logger.h"
31 #define line0 r.line0
32 #define char0 r.char0
33 #define line1 r.line1
34 #define char1 r.char1
36 #ifdef yyerror
37 #undef yyerror
38 #endif
39 #define yyerror(loc,p,msg) p->parseFatal(loc,msg)
41 #ifdef YYLLOC_DEFAULT
42 # undef YYLLOC_DEFAULT
43 #endif
44 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
45 #define YYLLOC_DEFAULT(Current, Rhs, N) \
46 do \
47 if (N) { \
48 (Current).first(YYRHSLOC (Rhs, 1)); \
49 (Current).last (YYRHSLOC (Rhs, N)); \
50 } else { \
51 (Current).line0 = (Current).line1 = YYRHSLOC (Rhs, 0).line1;\
52 (Current).char0 = (Current).char1 = YYRHSLOC (Rhs, 0).char1;\
53 } \
54 while (0); \
55 _p->setRuleLocation(&Current);
57 #define YYCOPY(To, From, Count) \
58 do { \
59 YYSIZE_T yyi; \
60 for (yyi = 0; yyi < (Count); yyi++) { \
61 (To)[yyi] = (From)[yyi]; \
62 } \
63 if (From != From ## a) { \
64 YYSTACK_FREE (From); \
65 } \
66 } \
67 while (0)
69 #define YYCOPY_RESET(To, From, Count) \
70 do \
71 { \
72 YYSIZE_T yyi; \
73 for (yyi = 0; yyi < (Count); yyi++) { \
74 (To)[yyi] = (From)[yyi]; \
75 (From)[yyi].reset(); \
76 } \
77 if (From != From ## a) { \
78 YYSTACK_FREE (From); \
79 } \
80 } \
81 while (0)
83 #define YYTOKEN_RESET(From, Count) \
84 do \
85 { \
86 YYSIZE_T yyi; \
87 for (yyi = 0; yyi < (Count); yyi++) { \
88 (From)[yyi].reset(); \
89 } \
90 if (From != From ## a) { \
91 YYSTACK_FREE (From); \
92 } \
93 } \
94 while (0)
96 # define YYSTACK_RELOCATE_RESET(Stack_alloc, Stack) \
97 do \
98 { \
99 YYSIZE_T yynewbytes; \
100 YYCOPY_RESET (&yyptr->Stack_alloc, Stack, yysize); \
101 Stack = &yyptr->Stack_alloc; \
102 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
103 yyptr += yynewbytes / sizeof (*yyptr); \
105 while (0)
107 #define YYSTACK_CLEANUP \
108 YYTOKEN_RESET (yyvs, yystacksize); \
109 if (yyvs != yyvsa) { \
110 YYSTACK_FREE (yyvs); \
112 if (yyls != yylsa) { \
113 YYSTACK_FREE (yyls); \
117 // macros for rules
118 #define BEXP(...) _p->onBinaryOpExp(__VA_ARGS__);
119 #define UEXP(...) _p->onUnaryOpExp(__VA_ARGS__);
121 using namespace HPHP::HPHP_PARSER_NS;
123 typedef HPHP::ClosureType ClosureType;
125 ///////////////////////////////////////////////////////////////////////////////
126 // helpers
128 static void scalar_num(Parser *_p, Token &out, const char *num) {
129 Token t;
130 t.setText(num);
131 _p->onScalar(out, T_LNUMBER, t);
134 static void scalar_num(Parser *_p, Token &out, int num) {
135 Token t;
136 t.setText(folly::to<std::string>(num));
137 _p->onScalar(out, T_LNUMBER, t);
140 static void scalar_null(Parser *_p, Token &out) {
141 Token tnull; tnull.setText("null");
142 _p->onConstantValue(out, tnull);
145 static void scalar_file(Parser *_p, Token &out) {
146 Token file; file.setText("__FILE__");
147 _p->onScalar(out, T_FILE, file);
150 static void scalar_line(Parser *_p, Token &out) {
151 Token line; line.setText("__LINE__");
152 _p->onScalar(out, T_LINE, line);
155 ///////////////////////////////////////////////////////////////////////////////
157 static void constant_ae(Parser *_p, Token &out, Token &value) {
158 const std::string& valueStr = value.text();
159 if (valueStr.size() < 3 || valueStr.size() > 5 ||
160 (strcasecmp("true", valueStr.c_str()) != 0 &&
161 strcasecmp("false", valueStr.c_str()) != 0 &&
162 strcasecmp("null", valueStr.c_str()) != 0 &&
163 strcasecmp("inf", valueStr.c_str()) != 0 &&
164 strcasecmp("nan", valueStr.c_str()) != 0)) {
165 HPHP_PARSER_ERROR("User-defined constants are not allowed in user "
166 "attribute expressions", _p);
168 _p->onConstantValue(out, value);
171 ///////////////////////////////////////////////////////////////////////////////
174 * XHP functions: They are defined here, so different parsers don't have to
175 * handle XHP rules at all.
178 static void xhp_tag(Parser *_p, Token &out, Token &label, Token &body) {
179 if (!body.text().empty() && body.text() != label.text()) {
180 HPHP_PARSER_ERROR("XHP: mismatched tag: '%s' not the same as '%s'",
181 _p, body.text().c_str(), label.text().c_str());
184 label.xhpLabel();
185 Token name; _p->onName(name, label, Parser::StringName);
186 _p->onNewObject(out, name, body);
189 static void xhp_attribute(Parser *_p, Token &out, Token &type, Token &label,
190 Token &def, Token &req) {
192 * The bool, int, float, and string typenames are not given any special
193 * treatment by the parser and are treated the same as regular class names
194 * (which initially gets marked as type code 5). However, XHP wants to use
195 * different type codes for bool, int, float, and string, so we need to fix
196 * up the type code here to make XHP happy.
198 if (type.num() == 5) {
199 auto* str = type.text().c_str();
200 if (_p->scanner().isHHSyntaxEnabled()) {
201 switch (type.text().size()) {
202 case 6:
203 if (!strcasecmp(str, "HH\\int")) {
204 type.reset(); type.setNum(3);
206 break;
207 case 7:
208 if (!strcasecmp(str, "HH\\bool")) {
209 type.reset(); type.setNum(2);
211 break;
212 case 8:
213 if (!strcasecmp(str, "HH\\float")) {
214 type.reset(); type.setNum(8);
215 } else if (!strcasecmp(str, "HH\\mixed")) {
216 type.reset(); type.setNum(6);
218 break;
219 case 9:
220 if (!strcasecmp(str, "HH\\string")) {
221 type.reset(); type.setNum(1);
223 break;
224 default:
225 break;
227 } else {
228 switch (type.text().size()) {
229 case 3:
230 if (!strcasecmp(str, "int")) {
231 type.reset(); type.setNum(3);
233 break;
234 case 4:
235 if (!strcasecmp(str, "bool")) {
236 type.reset(); type.setNum(2);
237 } else if (!strcasecmp(str, "real")) {
238 type.reset(); type.setNum(8);
240 break;
241 case 5:
242 if (!strcasecmp(str, "float")) {
243 type.reset(); type.setNum(8);
244 } else if (!strcasecmp(str, "mixed")) {
245 type.reset(); type.setNum(6);
247 break;
248 case 6:
249 if (!strcasecmp(str, "string")) {
250 type.reset(); type.setNum(1);
251 } else if (!strcasecmp(str, "double")) {
252 type.reset(); type.setNum(8);
254 break;
255 case 7:
256 if (!strcasecmp(str, "integer")) {
257 type.reset(); type.setNum(3);
258 } else if (!strcasecmp(str, "boolean")) {
259 type.reset(); type.setNum(2);
261 break;
262 default:
263 break;
268 Token num; scalar_num(_p, num, type.num());
269 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
271 Token arr2;
272 switch (type.num()) {
273 case 5: /* class */ {
274 Token cls; _p->onScalar(cls, T_CONSTANT_ENCAPSED_STRING, type);
275 _p->onArrayPair(arr2, &arr1, 0, cls, 0);
276 break;
278 case 7: /* enum */ {
279 Token arr; _p->onArray(arr, type);
280 _p->onArrayPair(arr2, &arr1, 0, arr, 0);
281 break;
283 default: {
284 Token tnull; scalar_null(_p, tnull);
285 _p->onArrayPair(arr2, &arr1, 0, tnull, 0);
286 break;
290 Token arr3; _p->onArrayPair(arr3, &arr2, 0, def, 0);
291 Token arr4; _p->onArrayPair(arr4, &arr3, 0, req, 0);
292 _p->onArray(out, arr4);
293 out.setText(label);
296 static void xhp_attribute_list(Parser *_p, Token &out, Token *list,
297 Token &decl) {
298 if (decl.num() == 0) {
299 decl.xhpLabel();
300 if (list) {
301 out = *list;
302 out.setText(list->text() + ":" + decl.text()); // avoiding vector<string>
303 } else {
304 out.setText(decl);
306 } else {
307 Token name; _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, decl);
308 _p->onArrayPair(out, list, &name, decl, 0);
309 if (list) {
310 out.setText(list->text());
311 } else {
312 out.setText("");
317 static void xhp_attribute_stmt(Parser *_p, Token &out, Token &attributes) {
318 Token modifiers;
319 Token fname; fname.setText("__xhpAttributeDeclaration");
321 Token m;
322 Token m1; m1.setNum(T_PROTECTED); _p->onMemberModifier(m, NULL, m1);
323 Token m2; m2.setNum(T_STATIC); _p->onMemberModifier(modifiers, &m, m2);
325 _p->pushFuncLocation();
326 _p->onMethodStart(fname, modifiers);
328 std::vector<std::string> classes;
329 folly::split(':', attributes.text(), classes, true);
330 Token arrAttributes; _p->onArray(arrAttributes, attributes);
332 Token dummy;
334 Token stmts0;
336 _p->onStatementListStart(stmts0);
338 Token stmts1;
340 // static $_ = -1;
341 Token one; scalar_num(_p, one, "1");
342 Token mone; UEXP(mone, one, '-', 1);
343 Token var; var.set(T_VARIABLE, "_");
344 Token decl; _p->onStaticVariable(decl, 0, var, &mone);
345 Token sdecl; _p->onStatic(sdecl, decl);
346 _p->addStatement(stmts1, stmts0, sdecl);
348 Token stmts2;
350 // if ($_ === -1) {
351 // $_ = array_merge(parent::__xhpAttributeDeclaration(),
352 // attributes);
353 // }
354 Token parent; parent.set(T_STRING, "parent");
355 Token cls; _p->onName(cls, parent, Parser::StringName);
356 Token fname; fname.setText("__xhpAttributeDeclaration");
357 Token param1; _p->onCall(param1, 0, fname, dummy, &cls);
358 Token params1; _p->onCallParam(params1, NULL, param1, false, false);
360 for (unsigned int i = 0; i < classes.size(); i++) {
361 Token parent; parent.set(T_STRING, classes[i]);
362 Token cls; _p->onName(cls, parent, Parser::StringName);
363 Token fname; fname.setText("__xhpAttributeDeclaration");
364 Token param; _p->onCall(param, 0, fname, dummy, &cls);
366 Token params; _p->onCallParam(params, &params1, param, false, false);
367 params1 = params;
370 Token params2; _p->onCallParam(params2, &params1, arrAttributes,
371 false, false);
373 Token name; name.set(T_STRING, "array_merge");
374 Token call; _p->onCall(call, 0, name, params2, NULL);
375 Token tvar; tvar.set(T_VARIABLE, "_");
376 Token var; _p->onSimpleVariable(var, tvar);
377 Token assign; _p->onAssign(assign, var, call, 0);
378 Token exp; _p->onExpStatement(exp, assign);
379 Token block; _p->onBlock(block, exp);
381 Token tvar2; tvar2.set(T_VARIABLE, "_");
382 Token var2; _p->onSimpleVariable(var2, tvar2);
383 Token one; scalar_num(_p, one, "1");
384 Token mone; UEXP(mone, one, '-', 1);
385 Token cond; BEXP(cond, var2, mone, T_IS_IDENTICAL);
386 Token dummy1, dummy2;
387 Token sif; _p->onIf(sif, cond, block, dummy1, dummy2);
388 _p->addStatement(stmts2, stmts1, sif);
390 Token stmts3;
392 // return $_;
393 Token tvar; tvar.set(T_VARIABLE, "_");
394 Token var; _p->onSimpleVariable(var, tvar);
395 Token ret; _p->onReturn(ret, &var);
396 _p->addStatement(stmts3, stmts2, ret);
398 Token stmt;
400 _p->finishStatement(stmt, stmts3);
401 stmt = 1;
404 Token params, ret, ref; ref = 0;
405 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
409 static void xhp_collect_attributes(Parser *_p, Token &out, Token &stmts) {
410 Token *attr = _p->xhpGetAttributes();
411 if (attr) {
412 Token stmt;
413 xhp_attribute_stmt(_p, stmt, *attr);
414 _p->onClassStatement(out, stmts, stmt);
415 } else {
416 out = stmts;
420 static void xhp_category_stmt(Parser *_p, Token &out, Token &categories) {
421 Token fname; fname.setText("__xhpCategoryDeclaration");
422 Token m1; m1.setNum(T_PROTECTED);
423 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
424 _p->pushFuncLocation();
425 _p->onMethodStart(fname, modifiers);
427 Token stmts0;
429 _p->onStatementListStart(stmts0);
431 Token stmts1;
433 // static $_ = categories;
434 Token arr; _p->onArray(arr, categories);
435 Token var; var.set(T_VARIABLE, "_");
436 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
437 Token sdecl; _p->onStatic(sdecl, decl);
438 _p->addStatement(stmts1, stmts0, sdecl);
440 Token stmts2;
442 // return $_;
443 Token tvar; tvar.set(T_VARIABLE, "_");
444 Token var; _p->onSimpleVariable(var, tvar);
445 Token ret; _p->onReturn(ret, &var);
446 _p->addStatement(stmts2, stmts1, ret);
448 Token stmt;
450 _p->finishStatement(stmt, stmts2);
451 stmt = 1;
454 Token params, ret, ref; ref = 0;
455 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
459 static void xhp_children_decl_tag(Parser *_p, Token &arr, Token &tag) {
460 Token num; scalar_num(_p, num, tag.num());
461 Token arr1; _p->onArrayPair(arr1, &arr, 0, num, 0);
463 Token name;
464 if (tag.num() == 3 || tag.num() == 4) {
465 _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, tag);
466 } else if (tag.num() >= 0) {
467 scalar_null(_p, name);
468 } else {
469 HPHP_PARSER_ERROR("XHP: unknown children declaration", _p);
471 Token arr2; _p->onArrayPair(arr2, &arr1, 0, name, 0);
472 arr = arr2;
475 static void xhp_children_decl(Parser *_p, Token &out, Token &op1, int op,
476 Token *op2) {
477 Token num; scalar_num(_p, num, op);
478 Token arr; _p->onArrayPair(arr, 0, 0, num, 0);
480 if (op2) {
481 Token arr1; _p->onArrayPair(arr1, &arr, 0, op1, 0);
482 Token arr2; _p->onArrayPair(arr2, &arr1, 0, *op2, 0);
483 _p->onArray(out, arr2);
484 } else {
485 xhp_children_decl_tag(_p, arr, op1);
486 _p->onArray(out, arr);
490 static void xhp_children_paren(Parser *_p, Token &out, Token exp, int op) {
491 Token num; scalar_num(_p, num, op);
492 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
494 Token num5; scalar_num(_p, num5, 5);
495 Token arr2; _p->onArrayPair(arr2, &arr1, 0, num5, 0);
497 Token arr3; _p->onArrayPair(arr3, &arr2, 0, exp, 0);
498 _p->onArray(out, arr3);
501 static void xhp_children_stmt(Parser *_p, Token &out, Token &children) {
502 Token fname; fname.setText("__xhpChildrenDeclaration");
503 Token m1; m1.setNum(T_PROTECTED);
504 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
505 _p->pushFuncLocation();
506 _p->onMethodStart(fname, modifiers);
508 Token stmts0;
510 _p->onStatementListStart(stmts0);
512 Token stmts1;
514 // static $_ = children;
515 Token arr;
516 if (children.num() == 2) {
517 arr = children;
518 } else if (children.num() >= 0) {
519 scalar_num(_p, arr, children.num());
520 } else {
521 HPHP_PARSER_ERROR("XHP: XHP unknown children declaration", _p);
523 Token var; var.set(T_VARIABLE, "_");
524 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
525 Token sdecl; _p->onStatic(sdecl, decl);
526 _p->addStatement(stmts1, stmts0, sdecl);
528 Token stmts2;
530 // return $_;
531 Token tvar; tvar.set(T_VARIABLE, "_");
532 Token var; _p->onSimpleVariable(var, tvar);
533 Token ret; _p->onReturn(ret, &var);
534 _p->addStatement(stmts2, stmts1, ret);
536 Token stmt;
538 _p->finishStatement(stmt, stmts2);
539 stmt = 1;
542 Token params, ret, ref; ref = 0;
543 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
547 static void only_in_hh_syntax(Parser *_p) {
548 if (!_p->scanner().isHHSyntaxEnabled()) {
549 HPHP_PARSER_ERROR(
550 "Syntax only allowed in Hack files (<?hh) or with -v "
551 "Eval.EnableHipHopSyntax=true",
552 _p);
556 static void validate_hh_variadic_variant(Parser* _p,
557 Token& userAttrs, Token& typehint,
558 Token* mod) {
559 if (!userAttrs.text().empty() || !typehint.text().empty() ||
560 (mod && !mod->text().empty())) {
561 HPHP_PARSER_ERROR("Variadic '...' should be followed by a '$variable'", _p);
563 only_in_hh_syntax(_p);
566 // Shapes may not have leading integers in key names, considered as a
567 // parse time error. This is because at runtime they are currently
568 // hphp arrays, which will treat leading integer keys as numbers.
569 static void validate_shape_keyname(Token& tok, Parser* _p) {
570 if (tok.text().empty()) {
571 HPHP_PARSER_ERROR("Shape key names may not be empty", _p);
573 if (isdigit(tok.text()[0])) {
574 HPHP_PARSER_ERROR("Shape key names may not start with integers", _p);
578 ///////////////////////////////////////////////////////////////////////////////
580 static int yylex(YYSTYPE* token, HPHP::Location* loc, Parser* _p) {
581 return _p->scan(token, loc);
585 %expect 4
586 %define api.pure
587 %lex-param {HPHP::HPHP_PARSER_NS::Parser *_p}
588 %parse-param {HPHP::HPHP_PARSER_NS::Parser *_p}
590 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
591 %right T_LAMBDA_ARROW
592 %left ','
593 %nonassoc "..."
594 %left T_LOGICAL_OR
595 %left T_LOGICAL_XOR
596 %left T_LOGICAL_AND
597 %right T_PRINT
598 %left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL
599 %right T_AWAIT T_YIELD
600 %right T_YIELD_FROM
601 %left T_PIPE
602 %left '?' ':'
603 %right T_COALESCE
604 %left T_BOOLEAN_OR
605 %left T_BOOLEAN_AND
606 %left '|'
607 %left '^'
608 %left '&'
609 %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
610 %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL T_SPACESHIP
611 %left T_SL T_SR
612 %left '+' '-' '.'
613 %left '*' '/' '%'
614 %right '!'
615 %nonassoc T_INSTANCEOF
616 %right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
617 %right T_POW
618 %right '['
620 %nonassoc T_NEW T_CLONE
621 %token T_EXIT
622 %token T_IF
623 %left T_ELSEIF
624 %left T_ELSE
625 %left T_ENDIF
626 %token T_LNUMBER /* long */
627 %token T_DNUMBER /* double */
628 %token T_ONUMBER /* overflowed decimal, might get parsed as long or double */
629 %token T_STRING
630 %token T_STRING_VARNAME
631 %token T_VARIABLE
632 %token T_PIPE_VAR
633 %token T_NUM_STRING
634 %token T_INLINE_HTML
635 %token T_HASHBANG
636 %token T_CHARACTER
637 %token T_BAD_CHARACTER
638 %token T_ENCAPSED_AND_WHITESPACE
639 %token T_CONSTANT_ENCAPSED_STRING
640 %token T_ECHO
641 %token T_DO
642 %token T_WHILE
643 %token T_ENDWHILE
644 %token T_FOR
645 %token T_ENDFOR
646 %token T_FOREACH
647 %token T_ENDFOREACH
648 %token T_DECLARE
649 %token T_ENDDECLARE
650 %token T_AS
651 %token T_SUPER
652 %token T_SWITCH
653 %token T_ENDSWITCH
654 %token T_CASE
655 %token T_DEFAULT
656 %token T_BREAK
657 %token T_GOTO
658 %token T_CONTINUE
659 %token T_FUNCTION
660 %token T_CONST
661 %token T_RETURN
662 %token T_TRY
663 %token T_CATCH
664 %token T_THROW
665 %token T_USE
666 %token T_GLOBAL
667 %right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC
668 %token T_VAR
669 %token T_UNSET
670 %token T_ISSET
671 %token T_EMPTY
672 %token T_HALT_COMPILER
673 %token T_CLASS
674 %token T_INTERFACE
675 %token T_EXTENDS
676 %token T_IMPLEMENTS
677 %token T_OBJECT_OPERATOR
678 %token T_NULLSAFE_OBJECT_OPERATOR
679 %token T_DOUBLE_ARROW
680 %token T_LIST
681 %token T_ARRAY
682 %token T_DICT
683 %token T_VEC
684 %token T_KEYSET
685 %token T_CALLABLE
686 %token T_CLASS_C
687 %token T_METHOD_C
688 %token T_FUNC_C
689 %token T_LINE
690 %token T_FILE
691 %token T_COMMENT
692 %token T_DOC_COMMENT
693 %token T_OPEN_TAG
694 %token T_OPEN_TAG_WITH_ECHO
695 %token T_CLOSE_TAG
696 %token T_WHITESPACE
697 %token T_START_HEREDOC
698 %token T_END_HEREDOC
699 %token T_DOLLAR_OPEN_CURLY_BRACES
700 %token T_CURLY_OPEN
701 %token T_DOUBLE_COLON
702 %token T_NAMESPACE
703 %token T_NS_C
704 %token T_DIR
705 %token T_NS_SEPARATOR
707 %token T_XHP_LABEL
708 %token T_XHP_TEXT
709 %token T_XHP_ATTRIBUTE
710 %token T_XHP_CATEGORY
711 %token T_XHP_CATEGORY_LABEL
712 %token T_XHP_CHILDREN
713 %token T_ENUM
714 %token T_XHP_REQUIRED
716 %token T_TRAIT
717 %token T_ELLIPSIS "..."
718 %token T_COALESCE "??"
719 %token T_INSTEADOF
720 %token T_TRAIT_C
722 %token T_HH_ERROR
723 %token T_FINALLY
725 %token T_XHP_TAG_LT
726 %token T_XHP_TAG_GT
727 %token T_TYPELIST_LT
728 %token T_TYPELIST_GT
729 %token T_UNRESOLVED_LT
731 %token T_COLLECTION
732 %token T_SHAPE
733 %token T_TYPE
734 %token T_UNRESOLVED_TYPE
735 %token T_NEWTYPE
736 %token T_UNRESOLVED_NEWTYPE
738 %token T_COMPILER_HALT_OFFSET
739 %token T_ASYNC
741 %token T_LAMBDA_OP
742 %token T_LAMBDA_CP
743 %token T_UNRESOLVED_OP
744 %token T_WHERE
748 start:
749 { _p->onNewLabelScope(true);
750 _p->initParseTree();}
751 top_statement_list
752 { _p->popLabelInfo();
753 _p->finiParseTree();
754 _p->onCompleteLabelScope(true);}
757 top_statement_list:
758 top_statement_list
759 top_statement { _p->addTopStatement($2);}
760 | { }
762 top_statement:
763 statement { _p->nns($1.num(), $1.text()); $$ = $1;}
764 | function_declaration_statement { _p->nns(); $$ = $1;}
765 | class_declaration_statement { _p->nns(); $$ = $1;}
766 | enum_declaration_statement { _p->nns(); $$ = $1;}
767 | trait_declaration_statement { _p->nns(); $$ = $1;}
768 | hh_type_alias_statement { $$ = $1; }
769 | T_HALT_COMPILER '(' ')' ';' { _p->onHaltCompiler();
770 _p->finiParseTree();
771 YYACCEPT;}
772 | T_NAMESPACE namespace_name ';' { _p->onNamespaceStart($2.text(), true);
773 $$.reset();}
774 | T_NAMESPACE namespace_name '{' { _p->onNamespaceStart($2.text());}
775 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $5;}
776 | T_NAMESPACE '{' { _p->onNamespaceStart("");}
777 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $4;}
778 | T_USE use_declarations ';' { _p->onUse($2, &Parser::useClass);
779 _p->nns(T_USE); $$.reset();}
780 | T_USE T_FUNCTION
781 use_declarations ';' { _p->onUse($3, &Parser::useFunction);
782 _p->nns(T_USE); $$.reset();}
783 | T_USE T_CONST
784 use_declarations ';' { _p->onUse($3, &Parser::useConst);
785 _p->nns(T_USE); $$.reset();}
786 | T_USE group_use_prefix
787 '{' mixed_use_declarations '}' ';' { _p->onGroupUse($2.text(), $4,
788 nullptr);
789 _p->nns(T_USE); $$.reset();}
790 | T_USE T_FUNCTION group_use_prefix
791 '{' use_declarations '}' ';' { _p->onGroupUse($3.text(), $5,
792 &Parser::useFunction);
793 _p->nns(T_USE); $$.reset();}
794 | T_USE T_CONST group_use_prefix
795 '{' use_declarations '}' ';' { _p->onGroupUse($3.text(), $5,
796 &Parser::useConst);
797 _p->nns(T_USE); $$.reset();}
798 | constant_declaration ';' { _p->nns();
799 _p->finishStatement($$, $1); $$ = 1;}
802 ident_no_semireserved:
803 T_STRING { $$ = $1;}
804 | T_SUPER { $$ = $1;}
805 | T_WHERE { $$ = $1;}
806 | T_XHP_ATTRIBUTE { $$ = $1;}
807 | T_XHP_CATEGORY { $$ = $1;}
808 | T_XHP_CHILDREN { $$ = $1;}
809 | T_XHP_REQUIRED { $$ = $1;}
810 | T_ENUM { $$ = $1;}
811 | T_DICT { $$ = $1;}
812 | T_VEC { $$ = $1;}
813 | T_KEYSET { $$ = $1;}
816 ident_for_class_const:
817 ident_no_semireserved
818 | T_CALLABLE
819 | T_TRAIT
820 | T_EXTENDS
821 | T_IMPLEMENTS
822 | T_STATIC
823 | T_ABSTRACT
824 | T_FINAL
825 | T_PRIVATE
826 | T_PROTECTED
827 | T_PUBLIC
828 | T_CONST
829 | T_ENDDECLARE
830 | T_ENDFOR
831 | T_ENDFOREACH
832 | T_ENDIF
833 | T_ENDWHILE
834 | T_LOGICAL_AND
835 | T_GLOBAL
836 | T_GOTO
837 | T_INSTANCEOF
838 | T_INSTEADOF
839 | T_INTERFACE
840 | T_NAMESPACE
841 | T_NEW
842 | T_LOGICAL_OR
843 | T_LOGICAL_XOR
844 | T_TRY
845 | T_USE
846 | T_VAR
847 | T_EXIT
848 | T_LIST
849 | T_CLONE
850 | T_INCLUDE
851 | T_INCLUDE_ONCE
852 | T_THROW
853 | T_ARRAY
854 | T_PRINT
855 | T_ECHO
856 | T_REQUIRE
857 | T_REQUIRE_ONCE
858 | T_RETURN
859 | T_ELSE
860 | T_ELSEIF
861 | T_DEFAULT
862 | T_BREAK
863 | T_CONTINUE
864 | T_SWITCH
865 | T_YIELD
866 | T_YIELD_FROM
867 | T_FUNCTION
868 | T_IF
869 | T_ENDSWITCH
870 | T_FINALLY
871 | T_FOR
872 | T_FOREACH
873 | T_DECLARE
874 | T_CASE
875 | T_DO
876 | T_WHILE
877 | T_AS
878 | T_CATCH
879 | T_EMPTY
880 /* no T_DIE ? */
881 /** The following must be made semi-reserved since they were keywords in HHVM
882 * but not PHP. */
883 | T_UNSET
886 ident:
887 ident_for_class_const
888 | T_CLASS
891 group_use_prefix:
892 namespace_name T_NS_SEPARATOR { $$ = $1;}
893 | T_NS_SEPARATOR
894 namespace_name T_NS_SEPARATOR { $$ = $2;}
897 non_empty_use_declarations:
898 non_empty_use_declarations ','
899 use_declaration { _p->addStatement($$,$1,$3);}
900 | use_declaration { $$.reset();
901 _p->addStatement($$,$$,$1);}
904 use_declarations:
905 non_empty_use_declarations
906 hh_possible_comma { $$ = $1;}
909 use_declaration:
910 namespace_name { _p->onUseDeclaration($$, $1.text(),"");}
911 | T_NS_SEPARATOR namespace_name { _p->onUseDeclaration($$, $2.text(),"");}
912 | namespace_name
913 T_AS ident_no_semireserved { _p->onUseDeclaration($$, $1.text(),$3.text());}
914 | T_NS_SEPARATOR namespace_name
915 T_AS ident_no_semireserved { _p->onUseDeclaration($$, $2.text(),$4.text());}
918 non_empty_mixed_use_declarations:
919 non_empty_mixed_use_declarations ','
920 mixed_use_declaration { _p->addStatement($$,$1,$3);}
921 | mixed_use_declaration { $$.reset();
922 _p->addStatement($$,$$,$1);}
925 mixed_use_declarations:
926 non_empty_mixed_use_declarations
927 hh_possible_comma { $$ = $1;}
930 mixed_use_declaration:
931 use_declaration { _p->onMixedUseDeclaration($$, $1,
932 &Parser::useClass);}
933 | T_FUNCTION use_declaration { _p->onMixedUseDeclaration($$, $2,
934 &Parser::useFunction);}
935 | T_CONST use_declaration { _p->onMixedUseDeclaration($$, $2,
936 &Parser::useConst);}
939 namespace_name:
940 ident_no_semireserved { $$ = $1;}
941 | namespace_name T_NS_SEPARATOR
942 ident_no_semireserved { $$ = $1 + $2 + $3; $$ = $1.num() | 2;}
944 namespace_string:
945 namespace_name { $$ = $1; $$ = $$.num() | 1;}
946 | T_NAMESPACE T_NS_SEPARATOR
947 namespace_name { $$.set($3.num() | 2, _p->nsDecl($3.text()));}
948 | T_NS_SEPARATOR namespace_name { $$ = $2; $$ = $$.num() | 2;}
951 namespace_string_typeargs:
952 namespace_string
953 hh_typeargs_opt { if ($1.num() & 1) {
954 $1.setText(_p->resolve($1.text(),0));
956 $$ = $1;}
958 class_namespace_string_typeargs:
959 namespace_string
960 hh_typeargs_opt { if ($1.num() & 1) {
961 $1.setText(_p->resolve($1.text(),1));
963 _p->onTypeAnnotation($$, $1, $2);}
965 constant_declaration:
966 constant_declaration ','
967 hh_name_with_type
968 '=' static_expr { $3.setText(_p->nsDecl($3.text()));
969 _p->onConst($$,$3,$5);}
970 | T_CONST hh_name_with_type '='
971 static_expr { $2.setText(_p->nsDecl($2.text()));
972 _p->onConst($$,$2,$4);}
975 inner_statement_list:
976 inner_statement_list
977 inner_statement { _p->addStatement($$,$1,$2);}
978 | { _p->onStatementListStart($$);}
980 inner_statement:
981 statement { $$ = $1;}
982 | function_declaration_statement { $$ = $1;}
983 | class_declaration_statement { $$ = $1;}
984 | trait_declaration_statement { $$ = $1;}
986 statement:
987 '{' inner_statement_list '}' { _p->onBlock($$, $2);}
988 | T_IF parenthesis_expr
989 statement
990 elseif_list
991 else_single { _p->onIf($$,$2,$3,$4,$5);}
992 | T_IF parenthesis_expr ':'
993 inner_statement_list
994 new_elseif_list
995 new_else_single
996 T_ENDIF ';' { _p->onIf($$,$2,$4,$5,$6);}
997 | T_WHILE parenthesis_expr { _p->onNewLabelScope(false);
998 _p->pushLabelScope();}
999 while_statement { _p->popLabelScope();
1000 _p->onWhile($$,$2,$4);
1001 _p->onCompleteLabelScope(false);}
1003 | T_DO { _p->onNewLabelScope(false);
1004 _p->pushLabelScope();}
1005 statement T_WHILE parenthesis_expr
1006 ';' { _p->popLabelScope();
1007 _p->onDo($$,$3,$5);
1008 _p->onCompleteLabelScope(false);}
1009 | T_FOR '(' for_expr ';'
1010 for_expr ';' for_expr ')' { _p->onNewLabelScope(false);
1011 _p->pushLabelScope();}
1012 for_statement { _p->popLabelScope();
1013 _p->onFor($$,$3,$5,$7,$10);
1014 _p->onCompleteLabelScope(false);}
1015 | T_SWITCH parenthesis_expr { _p->onNewLabelScope(false);
1016 _p->pushLabelScope();}
1017 switch_case_list { _p->popLabelScope();
1018 _p->onSwitch($$,$2,$4);
1019 _p->onCompleteLabelScope(false);}
1020 | T_BREAK ';' { _p->onBreakContinue($$, true, NULL);}
1021 | T_BREAK expr ';' { _p->onBreakContinue($$, true, &$2);}
1022 | T_CONTINUE ';' { _p->onBreakContinue($$, false, NULL);}
1023 | T_CONTINUE expr ';' { _p->onBreakContinue($$, false, &$2);}
1024 | T_RETURN ';' { _p->onReturn($$, NULL);}
1025 | T_RETURN expr ';' { _p->onReturn($$, &$2);}
1026 | T_YIELD T_BREAK ';' { _p->onYieldBreak($$);}
1027 | T_GLOBAL global_var_list ';' { _p->onGlobal($$, $2);}
1028 | T_STATIC static_var_list ';' { _p->onStatic($$, $2);}
1029 | T_ECHO expr_list ';' { _p->onEcho($$, $2, 0);}
1030 | T_OPEN_TAG_WITH_ECHO expr_list ';' { _p->onEcho($$, $2, 0);}
1031 | T_UNSET '(' variable_list ')' ';' { _p->onUnset($$, $3);}
1032 | ';' { $$.reset(); $$ = ';';}
1033 | T_INLINE_HTML { _p->onEcho($$, $1, 1);}
1034 | T_HASHBANG { _p->onHashBang($$, $1);
1035 $$ = T_HASHBANG;}
1036 | T_FOREACH '(' expr
1037 T_AS foreach_variable
1038 foreach_optional_arg ')' { _p->onNewLabelScope(false);
1039 _p->pushLabelScope();}
1040 foreach_statement { _p->popLabelScope();
1041 _p->onForEach($$,$3,$5,$6,$9, false);
1042 _p->onCompleteLabelScope(false);}
1043 | T_FOREACH '(' expr
1044 T_AWAIT T_AS foreach_variable
1045 foreach_optional_arg ')' { _p->onNewLabelScope(false);
1046 _p->pushLabelScope();}
1047 foreach_statement { _p->popLabelScope();
1048 _p->onForEach($$,$3,$6,$7,$10, true);
1049 _p->onCompleteLabelScope(false);}
1050 | T_DECLARE '(' declare_list ')'
1051 declare_statement { _p->onDeclare($3, $5);
1052 $$ = $3;
1053 $$ = T_DECLARE;}
1054 | T_TRY
1055 try_statement_list
1056 T_CATCH '('
1057 fully_qualified_class_name
1058 T_VARIABLE ')' '{'
1059 inner_statement_list '}'
1060 additional_catches { _p->onCompleteLabelScope(false);}
1061 optional_finally { _p->onTry($$,$2,$5,$6,$9,$11,$13);}
1062 | T_TRY
1063 try_statement_list
1064 T_FINALLY { _p->onCompleteLabelScope(false);}
1065 finally_statement_list { _p->onTry($$, $2, $5);}
1066 | T_THROW expr ';' { _p->onThrow($$, $2);}
1067 | T_GOTO ident_no_semireserved ';' { _p->onGoto($$, $2, true);
1068 _p->addGoto($2.text(),
1069 _p->getRange(),
1070 &$$);}
1071 | expr ';' { _p->onExpStatement($$, $1);}
1072 | yield_expr ';' { _p->onExpStatement($$, $1);}
1073 | yield_assign_expr ';' { _p->onExpStatement($$, $1);}
1074 | yield_list_assign_expr ';' { _p->onExpStatement($$, $1);}
1075 | yield_from_expr ';' { _p->onExpStatement($$, $1);}
1076 | yield_from_assign_expr ';' { _p->onExpStatement($$, $1);}
1077 | T_RETURN yield_from_expr ';' { _p->onReturn($$, &$2);}
1078 | await_expr ';' { _p->onExpStatement($$, $1);}
1079 | await_assign_expr ';' { _p->onExpStatement($$, $1);}
1080 | T_RETURN await_expr ';' { _p->onReturn($$, &$2); }
1081 | await_list_assign_expr ';' { _p->onExpStatement($$, $1);}
1082 | ident_no_semireserved ':' { _p->onLabel($$, $1);
1083 _p->addLabel($1.text(),
1084 _p->getRange(),
1085 &$$);
1086 _p->onScopeLabel($$, $1);}
1089 try_statement_list:
1090 '{' { _p->onNewLabelScope(false);}
1091 inner_statement_list '}' { $$ = $3;}
1094 additional_catches:
1095 additional_catches
1096 T_CATCH '('
1097 fully_qualified_class_name
1098 T_VARIABLE ')'
1100 inner_statement_list '}' { _p->onCatch($$, $1, $4, $5, $8);}
1101 | { $$.reset();}
1104 finally_statement_list:
1105 '{' { _p->onNewLabelScope(false);
1106 _p->pushLabelScope();}
1107 inner_statement_list '}' { _p->popLabelScope();
1108 _p->onFinally($$, $3);
1109 _p->onCompleteLabelScope(false);}
1112 optional_finally:
1113 T_FINALLY finally_statement_list { $$ = $2;}
1114 | { $$.reset();}
1117 is_reference:
1118 '&' { $$ = 1;}
1119 | { $$.reset();}
1122 function_loc:
1123 T_FUNCTION { _p->pushFuncLocation(); }
1126 function_declaration_statement:
1127 function_loc
1128 is_reference
1129 hh_name_no_semireserved_with_typevar { $3.setText(_p->nsDecl($3.text()));
1130 _p->onNewLabelScope(true);
1131 _p->onFunctionStart($3);
1132 _p->pushLabelInfo();}
1133 '(' parameter_list ')'
1134 opt_return_type
1135 function_body { _p->onFunction($$,nullptr,$8,$2,$3,$6,$9,nullptr);
1136 _p->popLabelInfo();
1137 _p->popTypeScope();
1138 _p->onCompleteLabelScope(true);}
1139 | non_empty_member_modifiers
1140 function_loc
1141 is_reference
1142 hh_name_no_semireserved_with_typevar { $4.setText(_p->nsDecl($4.text()));
1143 _p->onNewLabelScope(true);
1144 _p->onFunctionStart($4);
1145 _p->pushLabelInfo();}
1146 '(' parameter_list ')'
1147 opt_return_type
1148 function_body { _p->onFunction($$,&$1,$9,$3,$4,$7,$10,nullptr);
1149 _p->popLabelInfo();
1150 _p->popTypeScope();
1151 _p->onCompleteLabelScope(true);}
1152 | non_empty_user_attributes
1153 method_modifiers function_loc
1154 is_reference
1155 hh_name_no_semireserved_with_typevar { $5.setText(_p->nsDecl($5.text()));
1156 _p->onNewLabelScope(true);
1157 _p->onFunctionStart($5);
1158 _p->pushLabelInfo();}
1159 '(' parameter_list ')'
1160 opt_return_type
1161 function_body { _p->onFunction($$,&$2,$10,$4,$5,$8,$11,&$1);
1162 _p->popLabelInfo();
1163 _p->popTypeScope();
1164 _p->onCompleteLabelScope(true);}
1167 enum_declaration_statement:
1168 T_ENUM
1169 ident_no_semireserved { $2.setText(_p->nsClassDecl($2.text()));
1170 _p->onClassStart(T_ENUM,$2);}
1171 ':' hh_type
1172 hh_opt_constraint
1173 '{' enum_statement_list '}' { _p->onEnum($$,$2,$5,$8,0); }
1175 | non_empty_user_attributes
1176 T_ENUM
1177 ident_no_semireserved { $3.setText(_p->nsClassDecl($3.text()));
1178 _p->onClassStart(T_ENUM,$3);}
1179 ':' hh_type
1180 hh_opt_constraint
1181 '{' enum_statement_list '}' { _p->onEnum($$,$3,$6,$9,&$1); }
1185 class_declaration_statement:
1186 class_entry_type
1187 class_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1188 _p->onClassStart($1.num(),$2);}
1189 extends_from implements_list '{'
1190 class_statement_list '}' { Token stmts;
1191 if (_p->peekClass()) {
1192 xhp_collect_attributes(_p,stmts,$7);
1193 } else {
1194 stmts = $7;
1196 _p->onClass($$,$1.num(),$2,$4,$5,
1197 stmts,0,nullptr);
1198 if (_p->peekClass()) {
1199 _p->xhpResetAttributes();
1201 _p->popClass();
1202 _p->popTypeScope();}
1203 | non_empty_user_attributes
1204 class_entry_type
1205 class_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1206 _p->onClassStart($2.num(),$3);}
1207 extends_from implements_list '{'
1208 class_statement_list '}' { Token stmts;
1209 if (_p->peekClass()) {
1210 xhp_collect_attributes(_p,stmts,$8);
1211 } else {
1212 stmts = $8;
1214 _p->onClass($$,$2.num(),$3,$5,$6,
1215 stmts,&$1,nullptr);
1216 if (_p->peekClass()) {
1217 _p->xhpResetAttributes();
1219 _p->popClass();
1220 _p->popTypeScope();}
1221 | T_INTERFACE
1222 interface_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1223 _p->onClassStart(T_INTERFACE,$2);}
1224 interface_extends_list '{'
1225 class_statement_list '}' { _p->onInterface($$,$2,$4,$6,0);
1226 _p->popClass();
1227 _p->popTypeScope();}
1228 | non_empty_user_attributes
1229 T_INTERFACE
1230 interface_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1231 _p->onClassStart(T_INTERFACE,$3);}
1232 interface_extends_list '{'
1233 class_statement_list '}' { _p->onInterface($$,$3,$5,$7,&$1);
1234 _p->popClass();
1235 _p->popTypeScope();}
1238 class_expression:
1239 T_CLASS { _p->onClassExpressionStart(); }
1240 ctor_arguments
1241 extends_from implements_list '{'
1242 class_statement_list '}' { _p->onClassExpression($$, $3, $4, $5, $7); }
1244 trait_declaration_statement:
1245 T_TRAIT
1246 trait_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1247 _p->onClassStart(T_TRAIT, $2);}
1248 implements_list
1249 '{' class_statement_list '}' { Token t_ext;
1250 t_ext.reset();
1251 _p->onClass($$,T_TRAIT,$2,t_ext,$4,
1252 $6, 0, nullptr);
1253 _p->popClass();
1254 _p->popTypeScope();}
1255 | non_empty_user_attributes
1256 T_TRAIT
1257 trait_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1258 _p->onClassStart(T_TRAIT, $3);}
1259 implements_list
1260 '{' class_statement_list '}' { Token t_ext;
1261 t_ext.reset();
1262 _p->onClass($$,T_TRAIT,$3,t_ext,$5,
1263 $7, &$1, nullptr);
1264 _p->popClass();
1265 _p->popTypeScope();}
1267 class_decl_name:
1268 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1269 | T_XHP_LABEL { $1.xhpLabel(); _p->pushTypeScope();
1270 _p->pushClass(true); $$ = $1;}
1272 interface_decl_name:
1273 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1275 trait_decl_name:
1276 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1278 class_entry_type:
1279 T_CLASS { $$ = T_CLASS;}
1280 | T_ABSTRACT T_CLASS { $$ = T_ABSTRACT; }
1281 | T_ABSTRACT T_FINAL T_CLASS { only_in_hh_syntax(_p);
1282 /* hacky, but transforming to a single token is quite convenient */
1283 $$ = T_STATIC; }
1284 | T_FINAL T_ABSTRACT T_CLASS { only_in_hh_syntax(_p); $$ = T_STATIC; }
1285 | T_FINAL T_CLASS { $$ = T_FINAL;}
1287 extends_from:
1288 T_EXTENDS
1289 fully_qualified_class_name { $$ = $2;}
1290 | { $$.reset();}
1292 implements_list:
1293 T_IMPLEMENTS interface_list { $$ = $2;}
1294 | { $$.reset();}
1296 interface_extends_list:
1297 T_EXTENDS interface_list { $$ = $2;}
1298 | { $$.reset();}
1300 interface_list:
1301 fully_qualified_class_name { _p->onInterfaceName($$, NULL, $1);}
1302 | interface_list ','
1303 fully_qualified_class_name { _p->onInterfaceName($$, &$1, $3);}
1305 trait_list:
1306 fully_qualified_class_name { _p->onTraitName($$, NULL, $1);}
1307 | trait_list ','
1308 fully_qualified_class_name { _p->onTraitName($$, &$1, $3);}
1311 foreach_optional_arg:
1312 T_DOUBLE_ARROW foreach_variable { $$ = $2;}
1313 | { $$.reset();}
1315 foreach_variable:
1316 variable { $$ = $1; $$ = 0;}
1317 | '&' variable { $$ = $2; $$ = 1;}
1318 | T_LIST '(' assignment_list ')' { _p->onListAssignment($$, $3, NULL);}
1321 for_statement:
1322 statement { $$ = $1;}
1323 | ':' inner_statement_list
1324 T_ENDFOR ';' { $$ = $2;}
1326 foreach_statement:
1327 statement { $$ = $1;}
1328 | ':' inner_statement_list
1329 T_ENDFOREACH ';' { $$ = $2;}
1331 while_statement:
1332 statement { $$ = $1;}
1333 | ':' inner_statement_list
1334 T_ENDWHILE ';' { $$ = $2;}
1336 declare_statement:
1337 statement { _p->onBlock($$, $1);}
1338 | ':' inner_statement_list
1339 T_ENDDECLARE ';' { _p->onBlock($$, $2);}
1342 declare_list:
1343 ident_no_semireserved '=' static_expr {_p->onDeclareList($$, $1, $3);}
1344 | declare_list ','
1345 ident_no_semireserved '=' static_expr {_p->onDeclareList($1, $3, $5);
1346 $$ = $1;}
1349 switch_case_list:
1350 '{' case_list '}' { $$ = $2;}
1351 | '{' ';' case_list '}' { $$ = $3;}
1352 | ':' case_list T_ENDSWITCH ';' { $$ = $2;}
1353 | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3;}
1355 case_list:
1356 case_list T_CASE expr
1357 case_separator
1358 inner_statement_list { _p->onCase($$,$1,&$3,$5);}
1359 | case_list T_DEFAULT case_separator
1360 inner_statement_list { _p->onCase($$,$1,NULL,$4);}
1361 | { $$.reset();}
1363 case_separator:
1364 ':' { $$.reset();}
1365 | ';' { $$.reset();}
1368 elseif_list:
1369 elseif_list T_ELSEIF parenthesis_expr
1370 statement { _p->onElseIf($$,$1,$3,$4);}
1371 | { $$.reset();}
1373 new_elseif_list:
1374 new_elseif_list T_ELSEIF
1375 parenthesis_expr ':'
1376 inner_statement_list { _p->onElseIf($$,$1,$3,$5);}
1377 | { $$.reset();}
1379 else_single:
1380 T_ELSE statement { $$ = $2;}
1381 | { $$.reset();}
1383 new_else_single:
1384 T_ELSE ':' inner_statement_list { $$ = $3;}
1385 | { $$.reset();}
1388 method_parameter_list:
1389 non_empty_method_parameter_list ','
1390 optional_user_attributes
1391 parameter_modifiers
1392 hh_type_opt "..." T_VARIABLE
1393 { _p->onVariadicParam($$,&$1,$5,$7,false,
1394 &$3,&$4); }
1395 | non_empty_method_parameter_list ','
1396 optional_user_attributes
1397 parameter_modifiers
1398 hh_type_opt '&' "..." T_VARIABLE
1399 { _p->onVariadicParam($$,&$1,$5,$8,true,
1400 &$3,&$4); }
1401 | non_empty_method_parameter_list ','
1402 optional_user_attributes
1403 parameter_modifiers
1404 hh_type_opt "..."
1405 { validate_hh_variadic_variant(
1406 _p, $3, $5, &$4);
1407 $$ = $1; }
1408 | non_empty_method_parameter_list
1409 hh_possible_comma { $$ = $1;}
1410 | optional_user_attributes
1411 parameter_modifiers
1412 hh_type_opt "..." T_VARIABLE
1413 { _p->onVariadicParam($$,NULL,$3,$5,false,
1414 &$1,&$2); }
1415 | optional_user_attributes
1416 parameter_modifiers
1417 hh_type_opt '&' "..." T_VARIABLE
1418 { _p->onVariadicParam($$,NULL,$3,$6,true,
1419 &$1,&$2); }
1420 | optional_user_attributes
1421 parameter_modifiers
1422 hh_type_opt "..."
1423 { validate_hh_variadic_variant(
1424 _p, $1, $3, &$2);
1425 $$.reset(); }
1426 | { $$.reset(); }
1429 non_empty_method_parameter_list:
1430 optional_user_attributes
1431 parameter_modifiers
1432 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$3,$4,0,
1433 NULL,&$1,&$2);}
1434 | optional_user_attributes
1435 parameter_modifiers
1436 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$3,$5,1,
1437 NULL,&$1,&$2);}
1438 | optional_user_attributes
1439 parameter_modifiers
1440 hh_type_opt '&' T_VARIABLE
1441 '=' expr { _p->onParam($$,NULL,$3,$5,1,
1442 &$7,&$1,&$2);}
1443 | optional_user_attributes
1444 parameter_modifiers
1445 hh_type_opt T_VARIABLE
1446 '=' expr { _p->onParam($$,NULL,$3,$4,0,
1447 &$6,&$1,&$2);}
1448 | non_empty_method_parameter_list ','
1449 optional_user_attributes
1450 parameter_modifiers
1451 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$5,$6,0,
1452 NULL,&$3,&$4);}
1453 | non_empty_method_parameter_list ','
1454 optional_user_attributes
1455 parameter_modifiers
1456 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$5,$7,1,
1457 NULL,&$3,&$4);}
1458 | non_empty_method_parameter_list ','
1459 optional_user_attributes
1460 parameter_modifiers
1461 hh_type_opt '&' T_VARIABLE
1462 '=' expr { _p->onParam($$,&$1,$5,$7,1,
1463 &$9,&$3,&$4);}
1464 | non_empty_method_parameter_list ','
1465 optional_user_attributes
1466 parameter_modifiers
1467 hh_type_opt T_VARIABLE
1468 '=' expr { _p->onParam($$,&$1,$5,$6,0,
1469 &$8,&$3,&$4);}
1472 parameter_list:
1473 non_empty_parameter_list ','
1474 optional_user_attributes
1475 hh_type_opt "..." T_VARIABLE
1476 { _p->onVariadicParam($$,&$1,$4,$6,
1477 false,&$3,NULL); }
1478 | non_empty_parameter_list ','
1479 optional_user_attributes
1480 hh_type_opt '&' "..." T_VARIABLE
1481 { _p->onVariadicParam($$,&$1,$4,$7,
1482 true,&$3,NULL); }
1483 | non_empty_parameter_list ','
1484 optional_user_attributes
1485 hh_type_opt "..."
1486 { validate_hh_variadic_variant(
1487 _p, $3, $4, NULL);
1488 $$ = $1; }
1489 | non_empty_parameter_list
1490 hh_possible_comma { $$ = $1;}
1491 | optional_user_attributes
1492 hh_type_opt "..." T_VARIABLE
1493 { _p->onVariadicParam($$,NULL,$2,$4,
1494 false,&$1,NULL); }
1495 | optional_user_attributes
1496 hh_type_opt '&' "..." T_VARIABLE
1497 { _p->onVariadicParam($$,NULL,$2,$5,
1498 true,&$1,NULL); }
1499 | optional_user_attributes
1500 hh_type_opt "..."
1501 { validate_hh_variadic_variant(
1502 _p, $1, $2, NULL);
1503 $$.reset(); }
1504 | { $$.reset();}
1507 non_empty_parameter_list:
1508 optional_user_attributes
1509 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$2,$3,false,
1510 NULL,&$1,NULL); }
1511 | optional_user_attributes
1512 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$2,$4,true,
1513 NULL,&$1,NULL); }
1514 | optional_user_attributes
1515 hh_type_opt '&' T_VARIABLE
1516 '=' expr { _p->onParam($$,NULL,$2,$4,true,
1517 &$6,&$1,NULL); }
1518 | optional_user_attributes
1519 hh_type_opt T_VARIABLE
1520 '=' expr { _p->onParam($$,NULL,$2,$3,false,
1521 &$5,&$1,NULL); }
1522 | non_empty_parameter_list ','
1523 optional_user_attributes
1524 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$4,$5,false,
1525 NULL,&$3,NULL); }
1526 | non_empty_parameter_list ','
1527 optional_user_attributes
1528 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$4,$6,true,
1529 NULL,&$3,NULL); }
1530 | non_empty_parameter_list ','
1531 optional_user_attributes
1532 hh_type_opt '&' T_VARIABLE
1533 '=' expr { _p->onParam($$,&$1,$4,$6,true,
1534 &$8,&$3,NULL); }
1535 | non_empty_parameter_list ','
1536 optional_user_attributes
1537 hh_type_opt T_VARIABLE
1538 '=' expr { _p->onParam($$,&$1,$4,$5,false,
1539 &$7,&$3,NULL); }
1542 function_call_parameter_list:
1543 non_empty_fcall_parameter_list
1544 hh_possible_comma { $$ = $1;}
1545 | { $$.reset();}
1547 non_empty_fcall_parameter_list:
1548 expr { _p->onCallParam($$,NULL,$1,false,false);}
1549 | '&' variable { _p->onCallParam($$,NULL,$2,true,false);}
1550 | "..." expr { _p->onCallParam($$,NULL,$2,false,true);}
1551 | non_empty_fcall_parameter_list
1552 ',' expr { _p->onCallParam($$,&$1,$3,false, false);}
1553 | non_empty_fcall_parameter_list
1554 ',' "..." expr { _p->onCallParam($$,&$1,$4,false,true);}
1555 | non_empty_fcall_parameter_list
1556 ',' '&' variable { _p->onCallParam($$,&$1,$4,true, false);}
1559 global_var_list:
1560 global_var_list ',' global_var { _p->onGlobalVar($$, &$1, $3);}
1561 | global_var { _p->onGlobalVar($$, NULL, $1);}
1563 global_var:
1564 T_VARIABLE { $$ = $1;}
1565 | '$' variable { $$ = $2; $$ = 1;}
1566 | '$' '{' expr '}' { $$ = $3; $$ = 1;}
1569 static_var_list:
1570 static_var_list ',' T_VARIABLE { _p->onStaticVariable($$,&$1,$3,0);}
1571 | static_var_list ',' T_VARIABLE
1572 '=' static_expr { _p->onStaticVariable($$,&$1,$3,&$5);}
1573 | T_VARIABLE { _p->onStaticVariable($$,0,$1,0);}
1574 | T_VARIABLE '=' static_expr { _p->onStaticVariable($$,0,$1,&$3);}
1577 enum_statement_list:
1578 enum_statement_list
1579 enum_statement { _p->onClassStatement($$, $1, $2);}
1580 | { $$.reset();}
1582 enum_statement:
1583 enum_constant_declaration ';' { _p->onClassVariableStart
1584 ($$,NULL,$1,NULL);}
1586 enum_constant_declaration:
1587 hh_constname_with_type '='
1588 static_expr { _p->onClassConstant($$,0,$1,$3);}
1592 class_statement_list:
1593 class_statement_list
1594 class_statement { _p->onClassStatement($$, $1, $2);}
1595 | { $$.reset();}
1597 class_statement:
1598 variable_modifiers { _p->onClassVariableModifer($1);}
1599 class_variable_declaration ';' { _p->onClassVariableStart
1600 ($$,&$1,$3,NULL);}
1601 | non_empty_member_modifiers
1602 hh_type { _p->onClassVariableModifer($1);}
1603 class_variable_declaration ';' { _p->onClassVariableStart
1604 ($$,&$1,$4,&$2);}
1605 | class_constant_declaration ';' { _p->onClassVariableStart
1606 ($$,NULL,$1,NULL);}
1607 | class_abstract_constant_declaration ';'
1608 { _p->onClassVariableStart
1609 ($$,NULL,$1,NULL, true);}
1610 | class_type_constant_declaration ';' { $$ = $1; }
1611 | method_modifiers function_loc
1612 is_reference hh_name_with_typevar '('
1613 { _p->onNewLabelScope(true);
1614 _p->onMethodStart($4, $1);
1615 _p->pushLabelInfo();}
1616 method_parameter_list ')'
1617 opt_return_type
1618 opt_type_constraint_where_clause
1619 method_body
1620 { _p->onMethod($$,$1,$9,$3,$4,$7,$11,nullptr);
1621 _p->popLabelInfo();
1622 _p->popTypeScope();
1623 _p->onCompleteLabelScope(true);}
1624 | non_empty_user_attributes
1625 method_modifiers function_loc
1626 is_reference
1627 hh_name_no_semireserved_with_typevar '('
1628 { _p->onNewLabelScope(true);
1629 _p->onMethodStart($5, $2);
1630 _p->pushLabelInfo();}
1631 method_parameter_list ')'
1632 opt_return_type
1633 opt_type_constraint_where_clause
1634 method_body
1635 { _p->onMethod($$,$2,$10,$4,$5,$8,$12,&$1);
1636 _p->popLabelInfo();
1637 _p->popTypeScope();
1638 _p->onCompleteLabelScope(true);}
1639 | T_XHP_ATTRIBUTE
1640 xhp_attribute_stmt ';' { _p->xhpSetAttributes($2);}
1641 | T_XHP_CATEGORY
1642 xhp_category_stmt ';' { xhp_category_stmt(_p,$$,$2);}
1643 | T_XHP_CHILDREN
1644 xhp_children_stmt ';' { xhp_children_stmt(_p,$$,$2);}
1645 | T_REQUIRE T_EXTENDS fully_qualified_class_name ';'
1646 { _p->onClassRequire($$, $3, true); }
1647 | T_REQUIRE T_IMPLEMENTS fully_qualified_class_name ';'
1648 { _p->onClassRequire($$, $3, false); }
1649 | T_USE trait_list ';' { Token t; t.reset();
1650 _p->onTraitUse($$,$2,t); }
1651 | T_USE trait_list '{'
1652 trait_rules '}' { _p->onTraitUse($$,$2,$4); }
1654 trait_rules:
1655 trait_rules trait_precedence_rule { _p->onTraitRule($$,$1,$2); }
1656 | trait_rules trait_alias_rule { _p->onTraitRule($$,$1,$2); }
1657 | /* empty */ { $$.reset(); }
1659 trait_precedence_rule:
1660 class_namespace_string_typeargs
1661 T_DOUBLE_COLON
1662 ident_no_semireserved
1663 T_INSTEADOF trait_list ';' { _p->onTraitPrecRule($$,$1,$3,$5);}
1665 trait_alias_rule:
1666 trait_alias_rule_method T_AS
1667 method_modifiers ident_no_semireserved ';'
1668 { _p->onTraitAliasRuleModify($$,$1,$3,
1669 $4);}
1670 | trait_alias_rule_method T_AS
1671 non_empty_member_modifiers ';' { Token t; t.reset();
1672 _p->onTraitAliasRuleModify($$,$1,$3,
1673 t);}
1675 trait_alias_rule_method:
1676 class_namespace_string_typeargs
1677 T_DOUBLE_COLON
1678 ident_no_semireserved { _p->onTraitAliasRuleStart($$,$1,$3);}
1679 | ident_no_semireserved { Token t; t.reset();
1680 _p->onTraitAliasRuleStart($$,t,$1);}
1683 xhp_attribute_stmt:
1684 xhp_attribute_decl { xhp_attribute_list(_p,$$,
1685 _p->xhpGetAttributes(),$1);}
1686 | xhp_attribute_stmt ','
1687 xhp_attribute_decl { xhp_attribute_list(_p,$$, &$1,$3);}
1690 xhp_attribute_decl:
1691 xhp_nullable_attribute_decl_type
1692 xhp_label_ws
1693 xhp_attribute_default
1694 xhp_attribute_is_required { xhp_attribute(_p,$$,$1,$2,$3,$4);
1695 $$ = 1;}
1696 | T_XHP_LABEL { $$ = $1; $$ = 0;}
1699 xhp_nullable_attribute_decl_type:
1700 '?' xhp_attribute_decl_type { $$ = $2;}
1701 | xhp_attribute_decl_type
1704 xhp_attribute_decl_type:
1705 T_ARRAY { $$ = 4;}
1706 | T_ARRAY T_TYPELIST_LT hh_type
1707 possible_comma T_TYPELIST_GT { $$ = 4;}
1708 | T_ARRAY T_TYPELIST_LT hh_type ','
1709 hh_type T_TYPELIST_GT { $$ = 4;}
1710 | fully_qualified_class_name { /* This case handles all types other
1711 than "array", "var" and "enum".
1712 For now we just use type code 5;
1713 later xhp_attribute() will fix up
1714 the type code as appropriate. */
1715 $$ = 5; $$.setText($1);}
1716 | T_VAR { $$ = 6;}
1717 | T_ENUM '{'
1718 xhp_attribute_enum '}' { $$ = $3; $$ = 7;}
1719 | T_CALLABLE { $$ = 9; }
1722 non_empty_xhp_attribute_enum:
1723 common_scalar { _p->onArrayPair($$, 0,0,$1,0);}
1724 | non_empty_xhp_attribute_enum ','
1725 common_scalar { _p->onArrayPair($$,&$1,0,$3,0);}
1728 xhp_attribute_enum:
1729 non_empty_xhp_attribute_enum
1730 possible_comma { $$ = $1;}
1732 xhp_attribute_default:
1733 '=' static_expr { $$ = $2;}
1734 | { scalar_null(_p, $$);}
1737 xhp_attribute_is_required:
1738 '@' T_XHP_REQUIRED { scalar_num(_p, $$, "1");}
1739 | { scalar_num(_p, $$, "0");}
1742 xhp_category_stmt:
1743 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1744 _p->onArrayPair($$,0,&$1,t,0);}
1745 | xhp_category_stmt ','
1746 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1747 _p->onArrayPair($$,&$1,&$3,t,0);}
1750 xhp_category_decl:
1751 T_XHP_CATEGORY_LABEL { _p->onScalar($$,
1752 T_CONSTANT_ENCAPSED_STRING, $1);}
1755 xhp_children_stmt:
1756 xhp_children_paren_expr { $$ = $1; $$ = 2;}
1757 | ident_no_semireserved { $$ = -1;
1758 if ($1.same("any")) $$ = 1;}
1759 | T_EMPTY { $$ = 0;}
1762 xhp_children_paren_expr:
1763 '(' xhp_children_decl_expr ')' { xhp_children_paren(_p, $$, $2, 0);}
1764 | '(' xhp_children_decl_expr ')' '*' { xhp_children_paren(_p, $$, $2, 1);}
1765 | '(' xhp_children_decl_expr ')' '?' { xhp_children_paren(_p, $$, $2, 2);}
1766 | '(' xhp_children_decl_expr ')' '+' { xhp_children_paren(_p, $$, $2, 3);}
1769 xhp_children_decl_expr:
1770 xhp_children_paren_expr { $$ = $1;}
1771 | xhp_children_decl_tag { xhp_children_decl(_p,$$,$1,0, 0);}
1772 | xhp_children_decl_tag '*' { xhp_children_decl(_p,$$,$1,1, 0);}
1773 | xhp_children_decl_tag '?' { xhp_children_decl(_p,$$,$1,2, 0);}
1774 | xhp_children_decl_tag '+' { xhp_children_decl(_p,$$,$1,3, 0);}
1775 | xhp_children_decl_expr ','
1776 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,4,&$3);}
1777 | xhp_children_decl_expr '|'
1778 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,5,&$3);}
1781 xhp_children_decl_tag:
1782 ident_no_semireserved { $$ = -1;
1783 if ($1.same("any")) $$ = 1; else
1784 if ($1.same("pcdata")) $$ = 2;}
1785 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1; $$ = 3;}
1786 | T_XHP_CATEGORY_LABEL { $1.xhpLabel(0); $$ = $1; $$ = 4;}
1789 function_body:
1790 ';' { $$.reset();}
1791 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1794 method_body:
1795 ';' { $$.reset();}
1796 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1798 variable_modifiers:
1799 non_empty_member_modifiers { $$ = $1;}
1800 | T_VAR { $$.reset();}
1802 method_modifiers:
1803 non_empty_member_modifiers { $$ = $1;}
1804 | { $$.reset();}
1806 non_empty_member_modifiers:
1807 member_modifier { _p->onMemberModifier($$,NULL,$1);}
1808 | non_empty_member_modifiers
1809 member_modifier { _p->onMemberModifier($$,&$1,$2);}
1811 member_modifier:
1812 T_PUBLIC { $$ = T_PUBLIC;}
1813 | T_PROTECTED { $$ = T_PROTECTED;}
1814 | T_PRIVATE { $$ = T_PRIVATE;}
1815 | T_STATIC { $$ = T_STATIC;}
1816 | T_ABSTRACT { $$ = T_ABSTRACT;}
1817 | T_FINAL { $$ = T_FINAL;}
1818 | T_ASYNC { $$ = T_ASYNC;}
1821 parameter_modifiers:
1822 parameter_modifier { $$ = $1;}
1823 | { $$.reset();}
1825 parameter_modifier:
1826 T_PUBLIC { $$ = T_PUBLIC;}
1827 | T_PROTECTED { $$ = T_PROTECTED;}
1828 | T_PRIVATE { $$ = T_PRIVATE;}
1830 class_variable_declaration:
1831 class_variable_declaration ','
1832 T_VARIABLE { _p->onClassVariable($$,&$1,$3,0);}
1833 | class_variable_declaration ','
1834 T_VARIABLE '=' static_expr { _p->onClassVariable($$,&$1,$3,&$5);}
1835 | T_VARIABLE { _p->onClassVariable($$,0,$1,0);}
1836 | T_VARIABLE '=' static_expr { _p->onClassVariable($$,0,$1,&$3);}
1838 class_constant_declaration:
1839 class_constant_declaration ','
1840 hh_constname_with_type '=' static_expr { _p->onClassConstant($$,&$1,$3,$5);}
1841 | T_CONST hh_constname_with_type '='
1842 static_expr { _p->onClassConstant($$,0,$2,$4);}
1844 class_abstract_constant_declaration:
1845 class_abstract_constant_declaration ','
1846 hh_constname_with_type { _p->onClassAbstractConstant($$,&$1,$3);}
1847 | T_ABSTRACT T_CONST hh_constname_with_type
1848 { _p->onClassAbstractConstant($$,NULL,$3);}
1850 class_type_constant_declaration:
1851 T_ABSTRACT class_type_constant
1852 hh_opt_constraint { Token t;
1853 _p->onClassTypeConstant($$, $2, t);
1854 _p->popTypeScope(); }
1855 | class_type_constant
1856 hh_opt_constraint '=' hh_type { _p->onClassTypeConstant($$, $1, $4);
1857 _p->popTypeScope(); }
1858 class_type_constant:
1859 T_CONST T_TYPE
1860 hh_name_no_semireserved_with_typevar { $$ = $3; }
1863 expr_with_parens:
1864 '(' expr_with_parens ')' { $$ = $2;}
1865 | T_NEW class_name_reference
1866 ctor_arguments { _p->onNewObject($$, $2, $3);}
1867 | T_NEW class_expression { $$ = $2;}
1868 | T_CLONE expr { UEXP($$,$2,T_CLONE,1);}
1869 | xhp_tag { $$ = $1;}
1870 | collection_literal { $$ = $1;}
1872 parenthesis_expr:
1873 '(' expr ')' { $$ = $2;}
1876 expr_list:
1877 expr_list ',' expr { _p->onExprListElem($$, &$1, $3);}
1878 | expr { _p->onExprListElem($$, NULL, $1);}
1881 for_expr:
1882 expr_list { $$ = $1;}
1883 | { $$.reset();}
1886 yield_expr:
1887 T_YIELD { _p->onYield($$, NULL);}
1888 | T_YIELD expr { _p->onYield($$, &$2);}
1889 | T_YIELD expr T_DOUBLE_ARROW expr { _p->onYieldPair($$, &$2, &$4);}
1890 | '(' yield_expr ')' { $$ = $2; }
1893 yield_assign_expr:
1894 variable '=' yield_expr { _p->onAssign($$, $1, $3, 0, true);}
1897 yield_list_assign_expr:
1898 T_LIST '(' assignment_list ')'
1899 '=' yield_expr { _p->onListAssignment($$, $3, &$6, true);}
1902 yield_from_expr:
1903 T_YIELD_FROM expr { _p->onYieldFrom($$,&$2);}
1906 yield_from_assign_expr:
1907 variable '=' yield_from_expr { _p->onAssign($$, $1, $3, 0, true);}
1910 await_expr:
1911 T_AWAIT expr { _p->onAwait($$, $2); }
1914 await_assign_expr:
1915 variable '=' await_expr { _p->onAssign($$, $1, $3, 0, true);}
1918 await_list_assign_expr:
1919 T_LIST '(' assignment_list ')'
1920 '=' await_expr { _p->onListAssignment($$, $3, &$6, true);}
1923 expr:
1924 expr_no_variable { $$ = $1;}
1925 | variable { $$ = $1;}
1926 | expr_with_parens { $$ = $1;}
1927 | lambda_or_closure { $$ = $1;}
1928 | lambda_or_closure_with_parens { $$ = $1;}
1931 expr_no_variable:
1932 T_LIST '(' assignment_list ')'
1933 '=' expr { _p->onListAssignment($$, $3, &$6);}
1934 | variable '=' expr { _p->onAssign($$, $1, $3, 0);}
1935 | variable '=' '&' variable { _p->onAssign($$, $1, $4, 1);}
1936 | variable '=' '&' T_NEW
1937 class_name_reference
1938 ctor_arguments { _p->onAssignNew($$,$1,$5,$6);}
1939 | variable T_PLUS_EQUAL expr { BEXP($$,$1,$3,T_PLUS_EQUAL);}
1940 | variable T_MINUS_EQUAL expr { BEXP($$,$1,$3,T_MINUS_EQUAL);}
1941 | variable T_MUL_EQUAL expr { BEXP($$,$1,$3,T_MUL_EQUAL);}
1942 | variable T_DIV_EQUAL expr { BEXP($$,$1,$3,T_DIV_EQUAL);}
1943 | variable T_CONCAT_EQUAL expr { BEXP($$,$1,$3,T_CONCAT_EQUAL);}
1944 | variable T_MOD_EQUAL expr { BEXP($$,$1,$3,T_MOD_EQUAL);}
1945 | variable T_AND_EQUAL expr { BEXP($$,$1,$3,T_AND_EQUAL);}
1946 | variable T_OR_EQUAL expr { BEXP($$,$1,$3,T_OR_EQUAL);}
1947 | variable T_XOR_EQUAL expr { BEXP($$,$1,$3,T_XOR_EQUAL);}
1948 | variable T_SL_EQUAL expr { BEXP($$,$1,$3,T_SL_EQUAL);}
1949 | variable T_SR_EQUAL expr { BEXP($$,$1,$3,T_SR_EQUAL);}
1950 | variable T_POW_EQUAL expr { BEXP($$,$1,$3,T_POW_EQUAL);}
1951 | variable T_INC { UEXP($$,$1,T_INC,0);}
1952 | T_INC variable { UEXP($$,$2,T_INC,1);}
1953 | variable T_DEC { UEXP($$,$1,T_DEC,0);}
1954 | T_DEC variable { UEXP($$,$2,T_DEC,1);}
1955 | expr T_BOOLEAN_OR expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
1956 | expr T_BOOLEAN_AND expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
1957 | expr T_LOGICAL_OR expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
1958 | expr T_LOGICAL_AND expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
1959 | expr T_LOGICAL_XOR expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
1960 | expr '|' expr { BEXP($$,$1,$3,'|');}
1961 | expr '&' expr { BEXP($$,$1,$3,'&');}
1962 | expr '^' expr { BEXP($$,$1,$3,'^');}
1963 | expr '.' expr { BEXP($$,$1,$3,'.');}
1964 | expr '+' expr { BEXP($$,$1,$3,'+');}
1965 | expr '-' expr { BEXP($$,$1,$3,'-');}
1966 | expr '*' expr { BEXP($$,$1,$3,'*');}
1967 | expr '/' expr { BEXP($$,$1,$3,'/');}
1968 | expr T_POW expr { BEXP($$,$1,$3,T_POW);}
1969 | expr '%' expr { BEXP($$,$1,$3,'%');}
1970 | expr T_PIPE expr { BEXP($$,$1,$3,T_PIPE);}
1971 | expr T_SL expr { BEXP($$,$1,$3,T_SL);}
1972 | expr T_SR expr { BEXP($$,$1,$3,T_SR);}
1973 | '+' expr %prec T_INC { UEXP($$,$2,'+',1);}
1974 | '-' expr %prec T_INC { UEXP($$,$2,'-',1);}
1975 | '!' expr { UEXP($$,$2,'!',1);}
1976 | '~' expr { UEXP($$,$2,'~',1);}
1977 | expr T_IS_IDENTICAL expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
1978 | expr T_IS_NOT_IDENTICAL expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
1979 | expr T_IS_EQUAL expr { BEXP($$,$1,$3,T_IS_EQUAL);}
1980 | expr T_IS_NOT_EQUAL expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
1981 | expr '<' expr { BEXP($$,$1,$3,'<');}
1982 | expr T_IS_SMALLER_OR_EQUAL expr { BEXP($$,$1,$3,
1983 T_IS_SMALLER_OR_EQUAL);}
1984 | expr '>' expr { BEXP($$,$1,$3,'>');}
1985 | expr T_IS_GREATER_OR_EQUAL expr { BEXP($$,$1,$3,
1986 T_IS_GREATER_OR_EQUAL);}
1987 | expr T_SPACESHIP expr { BEXP($$,$1,$3,T_SPACESHIP);}
1988 | expr T_INSTANCEOF
1989 class_name_reference { BEXP($$,$1,$3,T_INSTANCEOF);}
1990 | '(' expr_no_variable ')' { $$ = $2;}
1991 | expr '?' expr ':' expr { _p->onQOp($$, $1, &$3, $5);}
1992 | expr '?' ':' expr { _p->onQOp($$, $1, 0, $4);}
1993 | expr T_COALESCE expr { _p->onNullCoalesce($$, $1, $3);}
1994 | internal_functions { $$ = $1;}
1995 | T_INT_CAST expr { UEXP($$,$2,T_INT_CAST,1);}
1996 | T_DOUBLE_CAST expr { UEXP($$,$2,T_DOUBLE_CAST,1);}
1997 | T_STRING_CAST expr { UEXP($$,$2,T_STRING_CAST,1);}
1998 | T_ARRAY_CAST expr { UEXP($$,$2,T_ARRAY_CAST,1);}
1999 | T_OBJECT_CAST expr { UEXP($$,$2,T_OBJECT_CAST,1);}
2000 | T_BOOL_CAST expr { UEXP($$,$2,T_BOOL_CAST,1);}
2001 | T_UNSET_CAST expr { UEXP($$,$2,T_UNSET_CAST,1);}
2002 | T_EXIT exit_expr { UEXP($$,$2,T_EXIT,1);}
2003 | '@' expr { UEXP($$,$2,'@',1);}
2004 | scalar { $$ = $1; }
2005 | array_literal { $$ = $1; }
2006 | dict_literal { $$ = $1; }
2007 | vec_literal { $$ = $1; }
2008 | keyset_literal { $$ = $1; }
2009 | shape_literal { $$ = $1; }
2010 | '`' backticks_expr '`' { _p->onEncapsList($$,'`',$2);}
2011 | T_PRINT expr { UEXP($$,$2,T_PRINT,1);}
2012 | dim_expr { $$ = $1;}
2015 lambda_use_vars:
2016 T_USE '('
2017 lexical_var_list
2018 hh_possible_comma
2019 ')' { $$ = $3;}
2020 | { $$.reset();}
2023 closure_expression:
2024 function_loc
2025 is_reference '(' { Token t;
2026 _p->onNewLabelScope(true);
2027 _p->onClosureStart(t);
2028 _p->pushLabelInfo(); }
2029 parameter_list ')'
2030 opt_return_type lambda_use_vars opt_return_type
2031 '{' inner_statement_list '}' { _p->finishStatement($11, $11); $11 = 1;
2032 $$ = _p->onClosure(
2033 ClosureType::Long, nullptr,
2034 $2,$5,$8,$11,$7,&$9);
2035 _p->popLabelInfo();
2036 _p->onCompleteLabelScope(true);}
2037 | non_empty_member_modifiers
2038 function_loc
2039 is_reference '(' { Token t;
2040 _p->onNewLabelScope(true);
2041 _p->onClosureStart(t);
2042 _p->pushLabelInfo(); }
2043 parameter_list ')'
2044 opt_return_type lambda_use_vars opt_return_type
2045 '{' inner_statement_list '}' { _p->finishStatement($12, $12); $12 = 1;
2046 $$ = _p->onClosure(
2047 ClosureType::Long, &$1,
2048 $3,$6,$9,$12,$8,&$10);
2049 _p->popLabelInfo();
2050 _p->onCompleteLabelScope(true);}
2053 lambda_expression:
2054 T_ASYNC
2055 T_VARIABLE { _p->pushFuncLocation();
2056 Token t;
2057 _p->onNewLabelScope(true);
2058 _p->onClosureStart(t);
2059 _p->pushLabelInfo();
2060 Token u;
2061 _p->onParam($2,NULL,u,$2,0,
2062 NULL,NULL,NULL);}
2063 lambda_body { Token v; Token w; Token x;
2064 $1 = T_ASYNC;
2065 _p->onMemberModifier($1, nullptr, $1);
2066 _p->finishStatement($4, $4); $4 = 1;
2067 $$ = _p->onClosure(ClosureType::Short,
2068 &$1,
2069 v,$2,w,$4,x);
2070 _p->popLabelInfo();
2071 _p->onCompleteLabelScope(true);}
2072 | T_ASYNC
2073 T_LAMBDA_OP { _p->pushFuncLocation();
2074 Token t;
2075 _p->onNewLabelScope(true);
2076 _p->onClosureStart(t);
2077 _p->pushLabelInfo();}
2078 parameter_list
2079 T_LAMBDA_CP
2080 opt_return_type
2081 lambda_body { Token u; Token v;
2082 $1 = T_ASYNC;
2083 _p->onMemberModifier($1, nullptr, $1);
2084 _p->finishStatement($7, $7); $7 = 1;
2085 $$ = _p->onClosure(ClosureType::Short,
2086 &$1,
2087 u,$4,v,$7,$6);
2088 _p->popLabelInfo();
2089 _p->onCompleteLabelScope(true);}
2090 | T_ASYNC
2091 '{' { _p->pushFuncLocation();
2092 Token t;
2093 _p->onNewLabelScope(true);
2094 _p->onClosureStart(t);
2095 _p->pushLabelInfo();}
2096 inner_statement_list
2097 '}' { Token u; Token v; Token w; Token x;
2098 Token y;
2099 $1 = T_ASYNC;
2100 _p->onMemberModifier($1, nullptr, $1);
2101 _p->finishStatement($4, $4); $4 = 1;
2102 $$ = _p->onClosure(ClosureType::Short,
2103 &$1,
2104 u,v,w,$4,x);
2105 _p->popLabelInfo();
2106 _p->onCompleteLabelScope(true);
2107 _p->onCall($$,1,$$,y,NULL);}
2108 | T_VARIABLE { _p->pushFuncLocation();
2109 Token t;
2110 _p->onNewLabelScope(true);
2111 _p->onClosureStart(t);
2112 _p->pushLabelInfo();
2113 Token u;
2114 _p->onParam($1,NULL,u,$1,0,
2115 NULL,NULL,NULL);}
2116 lambda_body { Token v; Token w; Token x;
2117 _p->finishStatement($3, $3); $3 = 1;
2118 $$ = _p->onClosure(ClosureType::Short,
2119 nullptr,
2120 v,$1,w,$3,x);
2121 _p->popLabelInfo();
2122 _p->onCompleteLabelScope(true);}
2123 | T_LAMBDA_OP { _p->pushFuncLocation();
2124 Token t;
2125 _p->onNewLabelScope(true);
2126 _p->onClosureStart(t);
2127 _p->pushLabelInfo();}
2128 parameter_list
2129 T_LAMBDA_CP
2130 opt_return_type
2131 lambda_body { Token u; Token v;
2132 _p->finishStatement($6, $6); $6 = 1;
2133 $$ = _p->onClosure(ClosureType::Short,
2134 nullptr,
2135 u,$3,v,$6,$5);
2136 _p->popLabelInfo();
2137 _p->onCompleteLabelScope(true);}
2140 lambda_body:
2141 T_LAMBDA_ARROW expr { $$ = _p->onExprForLambda($2);}
2142 | T_LAMBDA_ARROW await_expr { $$ = _p->onExprForLambda($2);}
2143 | T_LAMBDA_ARROW
2144 '{' inner_statement_list '}' { $$ = $3; }
2147 shape_keyname:
2148 T_CONSTANT_ENCAPSED_STRING { validate_shape_keyname($1, _p);
2149 _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $1); }
2150 | class_constant { $$ = $1; }
2153 non_empty_shape_pair_list:
2154 non_empty_shape_pair_list ','
2155 shape_keyname
2156 T_DOUBLE_ARROW
2157 expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
2158 | shape_keyname
2159 T_DOUBLE_ARROW
2160 expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2163 non_empty_static_shape_pair_list:
2164 non_empty_static_shape_pair_list ','
2165 shape_keyname
2166 T_DOUBLE_ARROW
2167 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
2168 | shape_keyname
2169 T_DOUBLE_ARROW
2170 static_expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2173 shape_pair_list:
2174 non_empty_shape_pair_list
2175 possible_comma { $$ = $1; }
2176 | { $$.reset(); }
2179 static_shape_pair_list:
2180 non_empty_static_shape_pair_list
2181 possible_comma { $$ = $1; }
2182 | { $$.reset(); }
2185 shape_literal:
2186 T_SHAPE '(' shape_pair_list ')' { _p->onArray($$, $3, T_ARRAY);}
2189 array_literal:
2190 T_ARRAY '(' array_pair_list ')' { _p->onArray($$,$3,T_ARRAY);}
2191 | '[' array_pair_list ']' { _p->onArray($$,$2,T_ARRAY);}
2194 dict_pair_list:
2195 non_empty_dict_pair_list
2196 possible_comma { $$ = $1;}
2197 | { $$.reset();}
2200 non_empty_dict_pair_list:
2201 non_empty_dict_pair_list
2202 ',' expr T_DOUBLE_ARROW expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2203 | expr T_DOUBLE_ARROW expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2204 | non_empty_dict_pair_list
2205 ',' expr T_DOUBLE_ARROW
2206 '&' variable { _p->onArrayPair($$,&$1,&$3,$6,1);}
2207 | expr T_DOUBLE_ARROW '&' variable { _p->onArrayPair($$, 0,&$1,$4,1);}
2210 static_dict_pair_list:
2211 non_empty_static_dict_pair_list
2212 possible_comma { $$ = $1;}
2213 | { $$.reset();}
2216 non_empty_static_dict_pair_list:
2217 non_empty_static_dict_pair_list
2218 ',' static_expr T_DOUBLE_ARROW
2219 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2220 | static_expr T_DOUBLE_ARROW
2221 static_expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2224 static_dict_pair_list_ae:
2225 non_empty_static_dict_pair_list_ae
2226 possible_comma { $$ = $1;}
2227 | { $$.reset();}
2230 non_empty_static_dict_pair_list_ae:
2231 non_empty_static_dict_pair_list_ae
2232 ',' static_scalar_ae T_DOUBLE_ARROW
2233 static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0);}
2234 | static_scalar_ae T_DOUBLE_ARROW
2235 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0);}
2238 dict_literal:
2239 T_DICT '[' dict_pair_list ']' { _p->onDict($$, $3); }
2242 static_dict_literal:
2243 T_DICT '[' static_dict_pair_list ']' { _p->onDict($$, $3); }
2246 static_dict_literal_ae:
2247 T_DICT '[' static_dict_pair_list_ae ']' { _p->onDict($$, $3); }
2250 vec_literal:
2251 T_VEC '[' vec_ks_expr_list ']' { _p->onVec($$, $3); }
2254 static_vec_literal:
2255 T_VEC '[' static_vec_ks_expr_list ']' { _p->onVec($$, $3); }
2258 static_vec_literal_ae:
2259 T_VEC '[' static_vec_ks_expr_list_ae ']' { _p->onVec($$, $3); }
2262 keyset_literal:
2263 T_KEYSET '[' vec_ks_expr_list ']' { _p->onKeyset($$, $3); }
2266 static_keyset_literal:
2267 T_KEYSET '[' static_vec_ks_expr_list ']' { _p->onKeyset($$, $3); }
2270 static_keyset_literal_ae:
2271 T_KEYSET '[' static_vec_ks_expr_list_ae ']' { _p->onKeyset($$, $3); }
2274 vec_ks_expr_list:
2275 expr_list
2276 possible_comma { $$ = $1;}
2277 | { $$.reset();}
2280 static_vec_ks_expr_list:
2281 static_expr_list
2282 possible_comma { $$ = $1;}
2283 | { $$.reset();}
2286 static_vec_ks_expr_list_ae:
2287 static_scalar_ae_list
2288 possible_comma { $$ = $1;}
2289 | { $$.reset();}
2292 collection_literal:
2293 fully_qualified_class_name
2294 '{' collection_init '}' { Token t;
2295 _p->onName(t,$1,Parser::StringName);
2296 BEXP($$,t,$3,T_COLLECTION);}
2299 static_collection_literal:
2300 fully_qualified_class_name
2301 '{' static_collection_init '}' { Token t;
2302 _p->onName(t,$1,Parser::StringName);
2303 BEXP($$,t,$3,T_COLLECTION);}
2306 dim_expr:
2307 dim_expr
2308 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2309 | dim_expr_base
2310 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2313 dim_expr_base:
2314 array_literal { $$ = $1;}
2315 | dict_literal { $$ = $1;}
2316 | vec_literal { $$ = $1;}
2317 | keyset_literal { $$ = $1;}
2318 | class_constant { $$ = $1;}
2319 | lambda_or_closure_with_parens { $$ = $1;}
2320 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2321 T_CONSTANT_ENCAPSED_STRING, $1); }
2322 | '(' expr_no_variable ')' { $$ = $2;}
2323 | T_STRING { $$ = $1;}
2326 lexical_var_list:
2327 lexical_var_list ',' T_VARIABLE { _p->onClosureParam($$,&$1,$3,0);}
2328 | lexical_var_list ',' '&'T_VARIABLE { _p->onClosureParam($$,&$1,$4,1);}
2329 | T_VARIABLE { _p->onClosureParam($$, 0,$1,0);}
2330 | '&' T_VARIABLE { _p->onClosureParam($$, 0,$2,1);}
2333 xhp_tag:
2334 T_XHP_TAG_LT
2335 T_XHP_LABEL
2336 xhp_tag_body
2337 T_XHP_TAG_GT { xhp_tag(_p,$$,$2,$3);}
2339 xhp_tag_body:
2340 xhp_attributes '/' { Token t1; _p->onArray(t1,$1);
2341 Token t2; _p->onArray(t2,$2);
2342 Token file; scalar_file(_p, file);
2343 Token line; scalar_line(_p, line);
2344 _p->onCallParam($1,NULL,t1,0,0);
2345 _p->onCallParam($$, &$1,t2,0,0);
2346 _p->onCallParam($1, &$1,file,0,0);
2347 _p->onCallParam($1, &$1,line,0,0);
2348 $$.setText("");}
2349 | xhp_attributes T_XHP_TAG_GT
2350 xhp_children T_XHP_TAG_LT '/'
2351 xhp_opt_end_label { Token file; scalar_file(_p, file);
2352 Token line; scalar_line(_p, line);
2353 _p->onArray($4,$1);
2354 _p->onArray($5,$3);
2355 _p->onCallParam($2,NULL,$4,0,0);
2356 _p->onCallParam($$, &$2,$5,0,0);
2357 _p->onCallParam($2, &$2,file,0,0);
2358 _p->onCallParam($2, &$2,line,0,0);
2359 $$.setText($6.text());}
2361 xhp_opt_end_label:
2362 { $$.reset(); $$.setText("");}
2363 | T_XHP_LABEL { $$.reset(); $$.setText($1);}
2365 xhp_attributes:
2366 xhp_attributes
2367 xhp_attribute_name '='
2368 xhp_attribute_value { _p->onArrayPair($$,&$1,&$2,$4,0);}
2369 | { $$.reset();}
2371 xhp_children:
2372 xhp_children xhp_child { _p->onArrayPair($$,&$1,0,$2,0);}
2373 | { $$.reset();}
2375 xhp_attribute_name:
2376 T_XHP_LABEL { _p->onScalar($$,
2377 T_CONSTANT_ENCAPSED_STRING, $1);}
2379 xhp_attribute_value:
2380 T_XHP_TEXT { $1.xhpDecode();
2381 _p->onScalar($$,
2382 T_CONSTANT_ENCAPSED_STRING, $1);}
2383 | '{' expr '}' { $$ = $2;}
2385 xhp_child:
2386 T_XHP_TEXT { $$.reset();
2387 if ($1.htmlTrim()) {
2388 $1.xhpDecode();
2389 _p->onScalar($$,
2390 T_CONSTANT_ENCAPSED_STRING, $1);
2393 | '{' expr '}' { $$ = $2; }
2394 | xhp_tag { $$ = $1; }
2397 xhp_label_ws:
2398 xhp_bareword { $$ = $1;}
2399 | xhp_label_ws ':'
2400 xhp_bareword { $$ = $1 + ":" + $3;}
2401 | xhp_label_ws '-'
2402 xhp_bareword { $$ = $1 + "-" + $3;}
2405 xhp_bareword:
2406 ident_no_semireserved { $$ = $1;}
2407 | T_EXIT { $$ = $1;}
2408 | T_FUNCTION { $$ = $1;}
2409 | T_CONST { $$ = $1;}
2410 | T_RETURN { $$ = $1;}
2411 | T_YIELD { $$ = $1;}
2412 | T_YIELD_FROM { $$ = $1;}
2413 | T_AWAIT { $$ = $1;}
2414 | T_TRY { $$ = $1;}
2415 | T_CATCH { $$ = $1;}
2416 | T_FINALLY { $$ = $1;}
2417 | T_THROW { $$ = $1;}
2418 | T_IF { $$ = $1;}
2419 | T_ELSEIF { $$ = $1;}
2420 | T_ENDIF { $$ = $1;}
2421 | T_ELSE { $$ = $1;}
2422 | T_WHILE { $$ = $1;}
2423 | T_ENDWHILE { $$ = $1;}
2424 | T_DO { $$ = $1;}
2425 | T_FOR { $$ = $1;}
2426 | T_ENDFOR { $$ = $1;}
2427 | T_FOREACH { $$ = $1;}
2428 | T_ENDFOREACH { $$ = $1;}
2429 | T_DECLARE { $$ = $1;}
2430 | T_ENDDECLARE { $$ = $1;}
2431 | T_INSTANCEOF { $$ = $1;}
2432 | T_AS { $$ = $1;}
2433 | T_SWITCH { $$ = $1;}
2434 | T_ENDSWITCH { $$ = $1;}
2435 | T_CASE { $$ = $1;}
2436 | T_DEFAULT { $$ = $1;}
2437 | T_BREAK { $$ = $1;}
2438 | T_CONTINUE { $$ = $1;}
2439 | T_GOTO { $$ = $1;}
2440 | T_ECHO { $$ = $1;}
2441 | T_PRINT { $$ = $1;}
2442 | T_CLASS { $$ = $1;}
2443 | T_INTERFACE { $$ = $1;}
2444 | T_EXTENDS { $$ = $1;}
2445 | T_IMPLEMENTS { $$ = $1;}
2446 | T_NEW { $$ = $1;}
2447 | T_CLONE { $$ = $1;}
2448 | T_VAR { $$ = $1;}
2449 | T_EVAL { $$ = $1;}
2450 | T_INCLUDE { $$ = $1;}
2451 | T_INCLUDE_ONCE { $$ = $1;}
2452 | T_REQUIRE { $$ = $1;}
2453 | T_REQUIRE_ONCE { $$ = $1;}
2454 | T_NAMESPACE { $$ = $1;}
2455 | T_USE { $$ = $1;}
2456 | T_GLOBAL { $$ = $1;}
2457 | T_ISSET { $$ = $1;}
2458 | T_EMPTY { $$ = $1;}
2459 | T_HALT_COMPILER { $$ = $1;}
2460 | T_STATIC { $$ = $1;}
2461 | T_ABSTRACT { $$ = $1;}
2462 | T_FINAL { $$ = $1;}
2463 | T_PRIVATE { $$ = $1;}
2464 | T_PROTECTED { $$ = $1;}
2465 | T_PUBLIC { $$ = $1;}
2466 | T_ASYNC { $$ = $1;}
2467 | T_UNSET { $$ = $1;}
2468 | T_LIST { $$ = $1;}
2469 | T_ARRAY { $$ = $1;}
2470 | T_LOGICAL_OR { $$ = $1;}
2471 | T_LOGICAL_AND { $$ = $1;}
2472 | T_LOGICAL_XOR { $$ = $1;}
2473 | T_CLASS_C { $$ = $1;}
2474 | T_FUNC_C { $$ = $1;}
2475 | T_METHOD_C { $$ = $1;}
2476 | T_LINE { $$ = $1;}
2477 | T_FILE { $$ = $1;}
2478 | T_DIR { $$ = $1;}
2479 | T_NS_C { $$ = $1;}
2480 | T_COMPILER_HALT_OFFSET { $$ = $1;}
2481 | T_TRAIT { $$ = $1;}
2482 | T_TRAIT_C { $$ = $1;}
2483 | T_INSTEADOF { $$ = $1;}
2484 | T_TYPE { $$ = $1;}
2485 | T_NEWTYPE { $$ = $1;}
2486 | T_SHAPE { $$ = $1;}
2489 simple_function_call:
2490 namespace_string_typeargs '('
2491 function_call_parameter_list ')' { _p->onCall($$,0,$1,$3,NULL);}
2494 fully_qualified_class_name:
2495 class_namespace_string_typeargs { $$ = $1;}
2496 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1;}
2499 static_class_name_base:
2500 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2501 | common_scalar { _p->onName($$,$1,Parser::StringName);}
2502 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2503 | reference_variable { _p->onName($$,$1,
2504 Parser::StaticClassExprName);}
2505 | '(' expr_no_variable ')' { _p->onName($$,$2,
2506 Parser::StaticClassExprName);}
2508 static_class_name_no_calls:
2509 static_class_name_base { $$ = $1; }
2510 | static_class_name_no_calls
2511 T_DOUBLE_COLON
2512 /* !PHP5_ONLY */
2513 variable_no_objects
2514 /* !END */
2515 /* !PHP7_ONLY */
2516 compound_variable
2517 /* !END */
2518 { _p->onStaticMember($$,$1,$3);}
2520 static_class_name:
2521 static_class_name_base { $$ = $1; }
2522 | class_method_call { _p->onName($$,$1,
2523 Parser::StaticClassExprName);}
2524 | static_class_name
2525 T_DOUBLE_COLON
2526 /* !PHP5_ONLY */
2527 variable_no_objects
2528 /* !END */
2529 /* !PHP7_ONLY */
2530 compound_variable
2531 /* !END */
2532 { _p->onStaticMember($$,$1,$3);}
2535 class_name_reference:
2536 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2537 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2538 | variable_no_calls { _p->onName($$,$1,Parser::ExprName);}
2541 exit_expr:
2542 '(' ')' { $$.reset();}
2543 | parenthesis_expr { $$ = $1;}
2544 | { $$.reset();}
2547 backticks_expr:
2548 /* empty */ { $$.reset();}
2549 | T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, NULL, $1, 0);}
2550 | encaps_list { $$ = $1;}
2552 ctor_arguments:
2554 function_call_parameter_list ')' { $$ = $2;}
2555 | { $$.reset();}
2558 common_scalar:
2559 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2560 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2561 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2562 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2563 T_CONSTANT_ENCAPSED_STRING, $1);}
2564 | T_LINE { _p->onScalar($$, T_LINE, $1);}
2565 | T_FILE { _p->onScalar($$, T_FILE, $1);}
2566 | T_DIR { _p->onScalar($$, T_DIR, $1);}
2567 | T_CLASS_C { _p->onScalar($$, T_CLASS_C, $1);}
2568 | T_TRAIT_C { _p->onScalar($$, T_TRAIT_C, $1);}
2569 | T_METHOD_C { _p->onScalar($$, T_METHOD_C, $1);}
2570 | T_FUNC_C { _p->onScalar($$, T_FUNC_C, $1);}
2571 | T_NS_C { _p->onScalar($$, T_NS_C, $1);}
2572 | T_COMPILER_HALT_OFFSET { _p->onScalar($$, T_COMPILER_HALT_OFFSET, $1);}
2573 | T_START_HEREDOC
2574 T_ENCAPSED_AND_WHITESPACE
2575 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2576 | T_START_HEREDOC
2577 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2580 static_expr:
2581 common_scalar { $$ = $1;}
2582 | namespace_string { _p->onConstantValue($$, $1);}
2583 | T_ARRAY '('
2584 static_array_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2585 | '[' static_array_pair_list ']' { _p->onArray($$,$2,T_ARRAY); }
2586 | T_SHAPE '('
2587 static_shape_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2588 | static_dict_literal { $$ = $1;}
2589 | static_vec_literal { $$ = $1;}
2590 | static_keyset_literal { $$ = $1;}
2591 | static_class_constant { $$ = $1;}
2592 | static_collection_literal { $$ = $1;}
2593 | '(' static_expr ')' { $$ = $2;}
2594 | static_expr T_BOOLEAN_OR
2595 static_expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
2596 | static_expr T_BOOLEAN_AND
2597 static_expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
2598 | static_expr T_LOGICAL_OR
2599 static_expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
2600 | static_expr T_LOGICAL_AND
2601 static_expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
2602 | static_expr T_LOGICAL_XOR
2603 static_expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
2604 | static_expr '|' static_expr { BEXP($$,$1,$3,'|');}
2605 | static_expr '&' static_expr { BEXP($$,$1,$3,'&');}
2606 | static_expr '^' static_expr { BEXP($$,$1,$3,'^');}
2607 | static_expr '.' static_expr { BEXP($$,$1,$3,'.');}
2608 | static_expr '+' static_expr { BEXP($$,$1,$3,'+');}
2609 | static_expr '-' static_expr { BEXP($$,$1,$3,'-');}
2610 | static_expr '*' static_expr { BEXP($$,$1,$3,'*');}
2611 | static_expr '/' static_expr { BEXP($$,$1,$3,'/');}
2612 | static_expr '%' static_expr { BEXP($$,$1,$3,'%');}
2613 | static_expr T_SL static_expr { BEXP($$,$1,$3,T_SL);}
2614 | static_expr T_SR static_expr { BEXP($$,$1,$3,T_SR);}
2615 | static_expr T_POW static_expr { BEXP($$,$1,$3,T_POW);}
2616 | '!' static_expr { UEXP($$,$2,'!',1);}
2617 | '~' static_expr { UEXP($$,$2,'~',1);}
2618 | '+' static_expr { UEXP($$,$2,'+',1);}
2619 | '-' static_expr { UEXP($$,$2,'-',1);}
2620 | static_expr T_IS_IDENTICAL
2621 static_expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
2622 | static_expr T_IS_NOT_IDENTICAL
2623 static_expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
2624 | static_expr T_IS_EQUAL
2625 static_expr { BEXP($$,$1,$3,T_IS_EQUAL);}
2626 | static_expr T_IS_NOT_EQUAL
2627 static_expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
2628 | static_expr '<' static_expr { BEXP($$,$1,$3,'<');}
2629 | static_expr T_IS_SMALLER_OR_EQUAL
2630 static_expr { BEXP($$,$1,$3,
2631 T_IS_SMALLER_OR_EQUAL);}
2632 | static_expr '>' static_expr { BEXP($$,$1,$3,'>');}
2633 | static_expr
2634 T_IS_GREATER_OR_EQUAL
2635 static_expr { BEXP($$,$1,$3,
2636 T_IS_GREATER_OR_EQUAL);}
2637 | static_expr
2638 T_SPACESHIP
2639 static_expr { BEXP($$,$1,$3,T_SPACESHIP);}
2641 | static_expr '?' static_expr ':'
2642 static_expr { _p->onQOp($$, $1, &$3, $5);}
2643 | static_expr '?' ':' static_expr { _p->onQOp($$, $1, 0, $4);}
2646 static_expr_list:
2647 static_expr_list ',' static_expr { _p->onExprListElem($$, &$1, $3);}
2648 | static_expr { _p->onExprListElem($$, NULL, $1);}
2651 static_class_class_constant:
2652 fully_qualified_class_name
2653 T_DOUBLE_COLON
2654 T_CLASS { _p->onClassClass($$, $1, $3, 1);}
2657 static_class_constant:
2658 fully_qualified_class_name
2659 T_DOUBLE_COLON
2660 ident_for_class_const { _p->onClassConst($$, $1, $3, 1);}
2661 | static_class_class_constant { $$ = $1;}
2664 scalar:
2665 namespace_string { _p->onConstantValue($$, $1);}
2666 | T_STRING_VARNAME { _p->onConstantValue($$, $1);}
2667 | class_constant { $$ = $1;}
2668 | common_scalar { $$ = $1;}
2669 | '"' encaps_list '"' { _p->onEncapsList($$,'"',$2);}
2670 | '\'' encaps_list '\'' { _p->onEncapsList($$,'\'',$2);}
2671 | T_START_HEREDOC encaps_list
2672 T_END_HEREDOC { _p->onEncapsList($$,T_START_HEREDOC,
2673 $2);}
2675 static_array_pair_list:
2676 non_empty_static_array_pair_list
2677 possible_comma { $$ = $1;}
2678 | { $$.reset();}
2681 possible_comma:
2682 ',' { $$.reset();}
2683 | { $$.reset();}
2685 hh_possible_comma:
2686 ',' { only_in_hh_syntax(_p); $$.reset();}
2687 | { $$.reset();}
2690 non_empty_static_array_pair_list:
2691 non_empty_static_array_pair_list
2692 ',' static_expr T_DOUBLE_ARROW
2693 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2694 | non_empty_static_array_pair_list
2695 ',' static_expr { _p->onArrayPair($$,&$1, 0,$3,0);}
2696 | static_expr T_DOUBLE_ARROW
2697 static_expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2698 | static_expr { _p->onArrayPair($$, 0, 0,$1,0);}
2701 common_scalar_ae:
2702 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2703 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2704 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2705 | T_START_HEREDOC
2706 T_ENCAPSED_AND_WHITESPACE
2707 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2708 | T_START_HEREDOC
2709 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2711 static_numeric_scalar_ae:
2712 T_LNUMBER { _p->onScalar($$,T_LNUMBER,$1);}
2713 | T_DNUMBER { _p->onScalar($$,T_DNUMBER,$1);}
2714 | T_ONUMBER { _p->onScalar($$,T_ONUMBER,$1);}
2715 | ident_no_semireserved { constant_ae(_p,$$,$1);}
2718 static_string_expr_ae:
2719 T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2720 T_CONSTANT_ENCAPSED_STRING,$1);}
2721 | T_CONSTANT_ENCAPSED_STRING '.' static_string_expr_ae
2722 { _p->onScalar($$,
2723 T_CONSTANT_ENCAPSED_STRING,
2724 $1 + $3);}
2727 static_scalar_ae:
2728 common_scalar_ae
2729 | static_string_expr_ae { $$ = $1;}
2730 | static_class_class_constant { $$ = $1;}
2731 | fully_qualified_class_name
2732 T_DOUBLE_COLON
2733 T_STRING { HPHP_PARSER_ERROR("User-defined "
2734 "constants are not allowed in "
2735 "user attribute expressions", _p);}
2736 | ident_no_semireserved { constant_ae(_p,$$,$1);}
2737 | '+' static_numeric_scalar_ae { UEXP($$,$2,'+',1);}
2738 | '-' static_numeric_scalar_ae { UEXP($$,$2,'-',1);}
2739 | T_ARRAY '('
2740 static_array_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY);}
2741 | '[' static_array_pair_list_ae ']' { _p->onArray($$,$2,T_ARRAY);}
2742 | T_SHAPE '('
2743 static_shape_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY); }
2744 | static_dict_literal_ae { $$ = $1;}
2745 | static_vec_literal_ae { $$ = $1;}
2746 | static_keyset_literal_ae { $$ = $1;}
2749 static_scalar_ae_list:
2750 static_scalar_ae_list ','
2751 static_scalar_ae { _p->onExprListElem($$, &$1, $3);}
2752 | static_scalar_ae { _p->onExprListElem($$, NULL, $1);}
2755 static_array_pair_list_ae:
2756 non_empty_static_array_pair_list_ae
2757 possible_comma { $$ = $1;}
2758 | { $$.reset();}
2760 non_empty_static_array_pair_list_ae:
2761 non_empty_static_array_pair_list_ae
2762 ',' static_scalar_ae T_DOUBLE_ARROW
2763 static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0);}
2764 | non_empty_static_array_pair_list_ae
2765 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2766 | static_scalar_ae T_DOUBLE_ARROW
2767 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0);}
2768 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2770 non_empty_static_scalar_list_ae:
2771 non_empty_static_scalar_list_ae
2772 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2773 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2776 static_shape_pair_list_ae:
2777 non_empty_static_shape_pair_list_ae
2778 possible_comma { $$ = $1; }
2779 | { $$.reset(); }
2781 non_empty_static_shape_pair_list_ae:
2782 non_empty_static_shape_pair_list_ae
2783 ',' shape_keyname
2784 T_DOUBLE_ARROW static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0); }
2785 | shape_keyname
2786 T_DOUBLE_ARROW
2787 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0); }
2790 static_scalar_list_ae:
2791 non_empty_static_scalar_list_ae
2792 possible_comma { $$ = $1;}
2793 | { $$.reset();}
2795 attribute_static_scalar_list:
2796 '(' static_scalar_list_ae ')' { _p->onArray($$,$2,T_ARRAY);}
2797 | { Token t; t.reset();
2798 _p->onArray($$,t,T_ARRAY);}
2801 non_empty_user_attribute_list:
2802 non_empty_user_attribute_list
2803 ',' ident_no_semireserved
2804 attribute_static_scalar_list { _p->onUserAttribute($$,&$1,$3,$4);}
2805 | ident_no_semireserved
2806 attribute_static_scalar_list { _p->onUserAttribute($$, 0,$1,$2);}
2808 user_attribute_list:
2809 { only_in_hh_syntax(_p);}
2810 non_empty_user_attribute_list
2811 possible_comma { $$ = $2;}
2813 non_empty_user_attributes:
2814 T_SL user_attribute_list T_SR { $$ = $2;}
2816 optional_user_attributes:
2817 non_empty_user_attributes { $$ = $1;}
2818 | { $$.reset();}
2821 object_operator:
2822 T_OBJECT_OPERATOR { $$ = $1; $$ = 0;}
2823 | T_NULLSAFE_OBJECT_OPERATOR { $$ = $1; $$ = 1;}
2826 object_property_name_no_variables:
2827 ident_no_semireserved { $$ = $1; $$ = HPHP::ObjPropNormal;}
2828 | T_XHP_LABEL { $$ = $1; $$ = HPHP::ObjPropXhpAttr;}
2829 | '{' expr '}' { $$ = $2; $$ = HPHP::ObjPropNormal;}
2832 object_property_name:
2833 object_property_name_no_variables { $$ = $1;}
2834 /* !PHP5_ONLY */
2835 | variable_no_objects { $$ = $1; $$ = HPHP::ObjPropNormal;}
2836 /* !END */
2837 /* !PHP7_ONLY */
2838 | compound_variable { $$ = $1; $$ = HPHP::ObjPropNormal;}
2839 /* !END */
2842 object_method_name_no_variables:
2843 ident_no_semireserved { $$ = $1;}
2844 | '{' expr '}' { $$ = $2;}
2847 object_method_name:
2848 object_method_name_no_variables { $$ = $1;}
2849 /* !PHP5_ONLY */
2850 | variable_no_objects { $$ = $1;}
2851 /* !END */
2852 /* !PHP7_ONLY */
2853 | compound_variable { $$ = $1;}
2854 /* !END */
2857 array_access:
2858 '[' dim_offset ']' { $$ = $2;}
2859 | '{' expr '}' { $$ = $2;}
2862 dimmable_variable_access:
2863 dimmable_variable array_access { _p->onRefDim($$, $1, $2);}
2864 | '(' expr_with_parens ')'
2865 array_access { _p->onRefDim($$, $2, $4);}
2868 dimmable_variable_no_calls_access:
2869 dimmable_variable_no_calls
2870 array_access { _p->onRefDim($$, $1, $2);}
2871 | '(' expr_with_parens ')'
2872 array_access { _p->onRefDim($$, $2, $4);}
2875 object_property_access_on_expr:
2876 '(' expr_with_parens ')'
2877 object_operator
2878 object_property_name { _p->onObjectProperty(
2881 !$4.num()
2882 ? HPHP::PropAccessType::Normal
2883 : HPHP::PropAccessType::NullSafe,
2887 | '(' expr_no_variable ')'
2888 object_operator
2889 object_property_name { _p->onObjectProperty(
2892 !$4.num()
2893 ? HPHP::PropAccessType::Normal
2894 : HPHP::PropAccessType::NullSafe,
2900 object_property_access_on_expr_no_variables:
2901 '(' expr_with_parens ')'
2902 object_operator
2903 object_property_name_no_variables
2904 { _p->onObjectProperty(
2907 !$4.num()
2908 ? HPHP::PropAccessType::Normal
2909 : HPHP::PropAccessType::NullSafe,
2913 | '(' expr_no_variable ')'
2914 object_operator
2915 object_property_name_no_variables
2916 { _p->onObjectProperty(
2919 !$4.num()
2920 ? HPHP::PropAccessType::Normal
2921 : HPHP::PropAccessType::NullSafe,
2927 variable:
2928 variable_no_objects { $$ = $1;}
2929 | simple_function_call { $$ = $1;}
2930 | object_method_call { $$ = $1;}
2931 | class_method_call { $$ = $1;}
2932 | dimmable_variable_access { $$ = $1;}
2933 | object_property_access_on_expr { $$ = $1;}
2934 | variable object_operator
2935 object_property_name { _p->onObjectProperty(
2938 !$2.num()
2939 ? HPHP::PropAccessType::Normal
2940 : HPHP::PropAccessType::NullSafe,
2944 | static_class_name
2945 T_DOUBLE_COLON
2946 /* !PHP5_ONLY */
2947 variable_no_objects
2948 /* !END */
2949 /* !PHP7_ONLY */
2950 compound_variable
2951 /* !END */
2952 { _p->onStaticMember($$,$1,$3);}
2953 | callable_variable '('
2954 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2955 | lambda_or_closure_with_parens '('
2956 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2957 | '(' variable ')' { $$ = $2;}
2960 dimmable_variable:
2961 simple_function_call { $$ = $1;}
2962 | object_method_call { $$ = $1;}
2963 | class_method_call { $$ = $1;}
2964 | dimmable_variable_access { $$ = $1;}
2965 | variable object_operator
2966 /* !PHP5_ONLY */
2967 object_property_name_no_variables
2968 /* !END */
2969 /* !PHP7_ONLY */
2970 object_property_name
2971 /* !END */
2972 { _p->onObjectProperty(
2975 !$2.num()
2976 ? HPHP::PropAccessType::Normal
2977 : HPHP::PropAccessType::NullSafe,
2981 | object_property_access_on_expr_no_variables { $$ = $1;}
2982 | callable_variable '('
2983 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2984 | '(' variable ')' { $$ = $2;}
2985 /* !PHP7_ONLY */
2986 | static_class_name
2987 T_DOUBLE_COLON
2988 compound_variable { _p->onStaticMember($$,$1,$3);}
2989 /* !END */
2992 callable_variable:
2993 variable_no_objects { $$ = $1;}
2994 | dimmable_variable_access { $$ = $1;}
2995 | simple_function_call { $$ = $1;}
2996 | array_literal { $$ = $1;}
2997 | common_scalar { $$ = $1;}
2998 | '(' variable ')' { $$ = $2;}
2999 | '(' expr_no_variable ')' { $$ = $2;}
3000 | lambda_or_closure_with_parens '('
3001 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
3002 | callable_variable '('
3003 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
3006 lambda_or_closure_with_parens:
3007 '(' lambda_or_closure ')' { $$ = $2;}
3010 lambda_or_closure:
3011 closure_expression { $$ = $1;}
3012 | lambda_expression { $$ = $1;}
3015 object_method_call:
3016 variable object_operator
3017 object_method_name hh_typeargs_opt '('
3018 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$1,$2.num(),$3,$6);}
3019 | '(' expr_with_parens ')'
3020 object_operator
3021 object_method_name hh_typeargs_opt '('
3022 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$2,$4.num(),$5,$8);}
3025 class_method_call:
3026 static_class_name
3027 T_DOUBLE_COLON
3028 ident hh_typeargs_opt '('
3029 function_call_parameter_list ')' { _p->onCall($$,0,$3,$6,&$1);}
3030 | static_class_name
3031 T_DOUBLE_COLON
3032 /* !PHP5_ONLY */
3033 variable_no_objects '('
3034 /* !END */
3035 /* !PHP7_ONLY */
3036 compound_variable '('
3037 /* !END */
3038 function_call_parameter_list ')' { _p->onCall($$,1,$3,$5,&$1);}
3039 | static_class_name
3040 T_DOUBLE_COLON
3041 '{' expr '}' '('
3042 function_call_parameter_list ')' { _p->onCall($$,1,$4,$7,&$1);}
3045 variable_no_objects:
3046 reference_variable { $$ = $1;}
3047 /* !PHP5_ONLY */
3048 | simple_indirect_reference
3049 reference_variable { _p->onIndirectRef($$,$1,$2);}
3050 /* !END */
3053 reference_variable:
3054 reference_variable
3055 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
3056 | reference_variable '{' expr '}' { _p->onRefDim($$, $1, $3);}
3057 | compound_variable { $$ = $1;}
3060 compound_variable:
3061 T_VARIABLE { _p->onSimpleVariable($$, $1);}
3062 | T_PIPE_VAR { _p->onPipeVariable($$);}
3063 | '$' '{' expr '}' { _p->onDynamicVariable($$, $3, 0);}
3064 /* !PHP7_ONLY */
3065 | '$' compound_variable { $1 = 1; _p->onIndirectRef($$, $1, $2);}
3066 /* !END */
3069 dim_offset:
3070 expr { $$ = $1;}
3071 | { $$.reset();}
3074 /* !PHP5_ONLY */
3075 simple_indirect_reference:
3076 '$' { $$ = 1;}
3077 | simple_indirect_reference '$' { $$++;}
3079 /* !END */
3081 variable_no_calls:
3082 variable_no_objects { $$ = $1;}
3083 | dimmable_variable_no_calls_access { $$ = $1;}
3084 | object_property_access_on_expr { $$ = $1;}
3085 | variable_no_calls
3086 object_operator
3087 object_property_name { _p->onObjectProperty(
3090 !$2.num()
3091 ? HPHP::PropAccessType::Normal
3092 : HPHP::PropAccessType::NullSafe,
3096 | static_class_name_no_calls
3097 T_DOUBLE_COLON
3098 variable_no_objects { _p->onStaticMember($$,$1,$3);}
3099 | '(' variable ')' { $$ = $2;}
3102 dimmable_variable_no_calls:
3103 | dimmable_variable_no_calls_access { $$ = $1;}
3104 | object_property_access_on_expr_no_variables { $$ = $1;}
3105 | variable_no_calls object_operator
3106 object_property_name_no_variables
3107 { _p->onObjectProperty(
3110 !$2.num()
3111 ? HPHP::PropAccessType::Normal
3112 : HPHP::PropAccessType::NullSafe,
3116 | '(' variable ')' { $$ = $2;}
3119 assignment_list:
3120 assignment_list ',' { _p->onAListVar($$,&$1,NULL);}
3121 | assignment_list ',' variable { _p->onAListVar($$,&$1,&$3);}
3122 | assignment_list ','
3123 T_LIST '(' assignment_list ')' { _p->onAListSub($$,&$1,$5);}
3124 | { _p->onAListVar($$,NULL,NULL);}
3125 | variable { _p->onAListVar($$,NULL,&$1);}
3126 | T_LIST '(' assignment_list ')' { _p->onAListSub($$,NULL,$3);}
3129 array_pair_list:
3130 non_empty_array_pair_list
3131 possible_comma { $$ = $1;}
3132 | { $$.reset();}
3134 non_empty_array_pair_list:
3135 non_empty_array_pair_list
3136 ',' expr T_DOUBLE_ARROW expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
3137 | non_empty_array_pair_list ',' expr { _p->onArrayPair($$,&$1, 0,$3,0);}
3138 | expr T_DOUBLE_ARROW expr { _p->onArrayPair($$, 0,&$1,$3,0);}
3139 | expr { _p->onArrayPair($$, 0, 0,$1,0);}
3140 | non_empty_array_pair_list
3141 ',' expr T_DOUBLE_ARROW
3142 '&' variable { _p->onArrayPair($$,&$1,&$3,$6,1);}
3143 | non_empty_array_pair_list ','
3144 '&' variable { _p->onArrayPair($$,&$1, 0,$4,1);}
3145 | expr T_DOUBLE_ARROW '&' variable { _p->onArrayPair($$, 0,&$1,$4,1);}
3146 | '&' variable { _p->onArrayPair($$, 0, 0,$2,1);}
3149 collection_init:
3150 non_empty_collection_init
3151 possible_comma { $$ = $1;}
3152 | { _p->onEmptyCollection($$);}
3154 non_empty_collection_init:
3155 non_empty_collection_init
3156 ',' expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$,&$1,&$3,$5);}
3157 | non_empty_collection_init ',' expr { _p->onCollectionPair($$,&$1, 0,$3);}
3158 | expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$, 0,&$1,$3);}
3159 | expr { _p->onCollectionPair($$, 0, 0,$1);}
3162 static_collection_init:
3163 non_empty_static_collection_init
3164 possible_comma { $$ = $1;}
3165 | { _p->onEmptyCollection($$);}
3167 non_empty_static_collection_init:
3168 non_empty_static_collection_init
3169 ',' static_expr T_DOUBLE_ARROW
3170 static_expr { _p->onCollectionPair($$,&$1,&$3,$5);}
3171 | non_empty_static_collection_init
3172 ',' static_expr { _p->onCollectionPair($$,&$1, 0,$3);}
3173 | static_expr T_DOUBLE_ARROW
3174 static_expr { _p->onCollectionPair($$, 0,&$1,$3);}
3175 | static_expr { _p->onCollectionPair($$, 0, 0,$1);}
3178 encaps_list:
3179 encaps_list encaps_var { _p->addEncap($$, &$1, $2, -1);}
3180 | encaps_list
3181 T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, &$1, $2, 0);}
3182 | encaps_var { _p->addEncap($$, NULL, $1, -1);}
3183 | T_ENCAPSED_AND_WHITESPACE
3184 encaps_var { _p->addEncap($$, NULL, $1, 0);
3185 _p->addEncap($$, &$$, $2, -1); }
3188 encaps_var:
3189 T_VARIABLE { _p->onSimpleVariable($$, $1);}
3190 | T_VARIABLE '['
3191 encaps_var_offset ']' { _p->encapRefDim($$, $1, $3);}
3192 | T_VARIABLE object_operator
3193 ident_no_semireserved { _p->encapObjProp(
3196 !$2.num()
3197 ? HPHP::PropAccessType::Normal
3198 : HPHP::PropAccessType::NullSafe,
3202 | T_DOLLAR_OPEN_CURLY_BRACES
3203 expr '}' { _p->onDynamicVariable($$, $2, 1);}
3204 | T_DOLLAR_OPEN_CURLY_BRACES
3205 T_STRING_VARNAME '[' expr ']' '}' { _p->encapArray($$, $2, $4);}
3206 | T_CURLY_OPEN variable '}' { $$ = $2;}
3208 encaps_var_offset:
3209 ident_no_semireserved { $$ = $1; $$ = T_STRING;}
3210 | T_NUM_STRING { $$ = $1; $$ = T_NUM_STRING;}
3211 | T_VARIABLE { $$ = $1; $$ = T_VARIABLE;}
3214 internal_functions:
3215 T_ISSET '(' expr_list ')' { UEXP($$,$3,T_ISSET,1);}
3216 | T_EMPTY '(' variable ')' { UEXP($$,$3,T_EMPTY,1);}
3217 | T_EMPTY '(' expr_no_variable ')' { UEXP($$,$3,'!',1);}
3218 | T_EMPTY '(' lambda_or_closure ')' { UEXP($$,$3,'!',1);}
3219 | T_EMPTY '(' lambda_or_closure_with_parens ')' { UEXP($$,$3,'!',1);}
3220 | T_EMPTY '(' expr_with_parens ')' { UEXP($$,$3,'!',1);}
3221 | T_INCLUDE expr { UEXP($$,$2,T_INCLUDE,1);}
3222 | T_INCLUDE_ONCE expr { UEXP($$,$2,T_INCLUDE_ONCE,1);}
3223 | T_EVAL '(' expr ')' { UEXP($$,$3,T_EVAL,1);}
3224 | T_REQUIRE expr { UEXP($$,$2,T_REQUIRE,1);}
3225 | T_REQUIRE_ONCE expr { UEXP($$,$2,T_REQUIRE_ONCE,1);}
3228 variable_list:
3229 variable { _p->onExprListElem($$, NULL, $1);}
3230 | variable_list ',' variable { _p->onExprListElem($$, &$1, $3);}
3233 class_constant:
3234 static_class_name
3235 T_DOUBLE_COLON ident_for_class_const { _p->onClassConst($$, $1, $3, 0);}
3236 | static_class_name
3237 T_DOUBLE_COLON T_CLASS { _p->onClassClass($$, $1, $3, 0);}
3240 /* hack productions -- these allow some extra stuff in hack
3241 * mode, but simplify down to the original thing
3244 hh_opt_constraint:
3245 /* empty */
3246 | T_AS hh_type
3249 hh_type_alias_statement:
3250 T_TYPE hh_name_no_semireserved_with_typevar
3251 '=' hh_type ';' { $2.setText(_p->nsClassDecl($2.text()));
3252 _p->onTypedef($$, $2, $4);
3253 _p->popTypeScope(); }
3254 | non_empty_user_attributes
3255 T_TYPE hh_name_no_semireserved_with_typevar
3256 '=' hh_type ';' { $3.setText(_p->nsClassDecl($3.text()));
3257 _p->onTypedef($$, $3, $5, &$1);
3258 _p->popTypeScope(); }
3259 | T_NEWTYPE hh_name_no_semireserved_with_typevar
3260 hh_opt_constraint '=' hh_type ';' { $2.setText(_p->nsClassDecl($2.text()));
3261 _p->onTypedef($$, $2, $5);
3262 _p->popTypeScope(); }
3263 | non_empty_user_attributes
3264 T_NEWTYPE hh_name_no_semireserved_with_typevar
3265 hh_opt_constraint '=' hh_type ';' { $3.setText(_p->nsClassDecl($3.text()));
3266 _p->onTypedef($$, $3, $6, &$1);
3267 _p->popTypeScope(); }
3270 hh_name_with_type: /* foo -> int foo */
3271 ident { $$ = $1; }
3272 | hh_type ident { only_in_hh_syntax(_p); $$ = $2; }
3275 hh_constname_with_type: /* foo -> int foo, but in class constants */
3276 ident_for_class_const { $$ = $1; }
3277 | hh_type ident_for_class_const { only_in_hh_syntax(_p); $$ = $2; }
3280 hh_name_with_typevar: /* foo -> foo<X,Y>; this adds a typevar
3281 * scope and must be followed by a call to
3282 * popTypeScope() */
3283 ident { _p->pushTypeScope(); $$ = $1; }
3284 | ident
3285 T_TYPELIST_LT
3286 hh_typevar_list
3287 T_TYPELIST_GT { _p->pushTypeScope(); $$ = $1; }
3290 hh_name_no_semireserved_with_typevar: /* foo -> foo<X,Y>; this adds a typevar
3291 * scope and must be followed by a call
3292 * to popTypeScope() */
3293 ident_no_semireserved { _p->pushTypeScope(); $$ = $1; }
3294 | ident_no_semireserved
3295 T_TYPELIST_LT
3296 hh_typevar_list
3297 T_TYPELIST_GT { Token t; _p->setTypeVars(t, $1);
3298 _p->pushTypeScope(); $$ = t; }
3301 hh_typeargs_opt:
3302 T_TYPELIST_LT
3303 hh_type_list
3304 T_TYPELIST_GT { $$ = $2; }
3305 | { $$.reset(); }
3308 hh_non_empty_type_list:
3309 hh_type { Token t; t.reset();
3310 _p->onTypeList($1, t);
3311 $$ = $1; }
3312 | hh_non_empty_type_list ',' hh_type { _p->onTypeList($1, $3);
3313 $$ = $1; }
3316 hh_type_list:
3317 hh_non_empty_type_list
3318 possible_comma { $$ = $1; }
3321 hh_func_type_list:
3322 hh_non_empty_type_list
3323 ',' T_ELLIPSIS { $$ = $1; }
3324 | hh_type_list { $$ = $1; }
3325 | T_ELLIPSIS { $$.reset(); }
3326 | { $$.reset(); }
3329 opt_type_constraint_where_clause:
3330 /* empty */
3331 | T_WHERE
3332 non_empty_constraint_list
3333 hh_possible_comma
3336 non_empty_constraint_list:
3337 hh_generalised_constraint
3338 | non_empty_constraint_list ',' hh_generalised_constraint
3341 hh_generalised_constraint:
3342 hh_type '=' hh_type
3343 | hh_type hh_constraint
3346 opt_return_type:
3347 { $$.reset(); }
3348 | ':' hh_type { $$ = $2; $$ = 1; }
3351 hh_constraint:
3352 T_AS hh_type
3353 | T_SUPER hh_type
3355 hh_typevar_list:
3356 hh_non_empty_typevar_list
3357 possible_comma { $$ = $1; }
3360 hh_non_empty_constraint_list:
3361 hh_constraint
3362 | hh_non_empty_constraint_list hh_constraint
3365 hh_non_empty_typevar_list:
3366 hh_non_empty_typevar_list ','
3367 hh_typevar_variance
3368 ident_no_semireserved { _p->addTypeVar($4.text()); }
3369 | hh_typevar_variance
3370 ident_no_semireserved { _p->addTypeVar($2.text()); }
3371 | hh_non_empty_typevar_list ','
3372 hh_typevar_variance
3373 ident_no_semireserved
3374 hh_non_empty_constraint_list { _p->addTypeVar($4.text()); }
3375 | hh_typevar_variance
3376 ident_no_semireserved
3377 hh_non_empty_constraint_list { _p->addTypeVar($2.text()); }
3380 hh_typevar_variance:
3381 '+' {}
3382 | '-' {}
3383 | /* empty */ {}
3386 hh_shape_member_type:
3387 T_CONSTANT_ENCAPSED_STRING
3388 T_DOUBLE_ARROW
3389 hh_type { validate_shape_keyname($1, _p);
3390 _p->onTypeAnnotation($$, $1, $3); }
3391 | '?'
3392 T_CONSTANT_ENCAPSED_STRING
3393 T_DOUBLE_ARROW
3394 hh_type {
3395 /* should not reach here as
3396 * optional shape fields are not
3397 * supported in strict mode */
3398 validate_shape_keyname($2, _p);
3399 _p->onTypeAnnotation($$, $2, $4);
3401 | class_namespace_string_typeargs
3402 T_DOUBLE_COLON
3403 ident_no_semireserved
3404 T_DOUBLE_ARROW
3405 hh_type { _p->onClsCnsShapeField($$, $1, $3, $5); }
3408 hh_non_empty_shape_member_list:
3409 hh_non_empty_shape_member_list ','
3410 hh_shape_member_type { _p->onTypeList($$, $3); }
3411 | hh_shape_member_type { }
3414 hh_shape_member_list:
3415 hh_non_empty_shape_member_list
3416 possible_comma { _p->onShape($$, $1); }
3417 | /* empty */ { Token t; t.reset();
3418 _p->onShape($$, t); }
3421 hh_shape_type:
3422 T_SHAPE
3423 '(' hh_shape_member_list ')' { $$ = $3;
3424 $$.setText("array"); }
3427 hh_access_type_start:
3428 class_namespace_string_typeargs { $$ = $1; }
3430 hh_access_type:
3431 ident_no_semireserved
3432 T_DOUBLE_COLON
3433 hh_access_type { Token t; t.reset();
3434 _p->onTypeAnnotation($$, $1, t);
3435 _p->onTypeList($$, $3); }
3436 | ident_no_semireserved
3437 hh_typeargs_opt { _p->onTypeAnnotation($$, $1, $2); }
3440 array_typelist:
3441 T_TYPELIST_LT hh_type
3442 possible_comma T_TYPELIST_GT { $$ = $2;}
3443 | T_TYPELIST_LT hh_type ','
3444 hh_type T_TYPELIST_GT { _p->onTypeList($2, $4); $$ = $2;}
3446 /* extends non_empty_type_decl with some more types */
3447 hh_type:
3448 /* double-optional types will be rejected by the typechecker; we
3449 * already allow plenty of nonsense types anyway */
3450 '?' hh_type { only_in_hh_syntax(_p);
3451 _p->onTypeSpecialization($2, '?');
3452 $$ = $2; }
3453 | '@' hh_type { only_in_hh_syntax(_p);
3454 _p->onTypeSpecialization($2, '@');
3455 $$ = $2; }
3456 | class_namespace_string_typeargs { $$ = $1; }
3457 | T_ARRAY { Token t; t.reset();
3458 $1.setText("array");
3459 _p->onTypeAnnotation($$, $1, t); }
3460 | T_CALLABLE { Token t; t.reset();
3461 $1.setText("callable");
3462 _p->onTypeAnnotation($$, $1, t); }
3463 | hh_shape_type { $$ = $1; }
3464 | hh_access_type_start
3465 T_DOUBLE_COLON
3466 hh_access_type { only_in_hh_syntax(_p);
3467 _p->onTypeAnnotation($$, $1, $3);
3468 _p->onTypeSpecialization($$, 'a'); }
3469 | T_ARRAY array_typelist { $1.setText("array");
3470 _p->onTypeAnnotation($$, $1, $2); }
3471 | T_XHP_LABEL { $1.xhpLabel();
3472 Token t; t.reset();
3473 _p->onTypeAnnotation($$, $1, t);
3474 _p->onTypeSpecialization($$, 'x'); }
3475 | '(' T_FUNCTION
3476 '(' hh_func_type_list ')'
3477 ':' hh_type ')' { only_in_hh_syntax(_p);
3478 _p->onTypeList($7, $4);
3479 _p->onTypeAnnotation($$, $2, $7);
3480 _p->onTypeSpecialization($$, 'f'); }
3481 | '(' hh_type ','
3482 hh_non_empty_type_list
3483 possible_comma ')' { only_in_hh_syntax(_p);
3484 _p->onTypeList($2, $4);
3485 Token t; t.reset(); t.setText("array");
3486 _p->onTypeAnnotation($$, t, $2);
3487 _p->onTypeSpecialization($$, 't'); }
3490 hh_type_opt:
3491 hh_type { $$ = $1; }
3492 | { $$.reset(); }
3496 /* !PHP5_ONLY*/
3497 bool Parser::parseImpl5() {
3498 /* !END */
3499 /* !PHP7_ONLY*/
3500 bool Parser::parseImpl7() {
3501 /* !END */
3502 return yyparse(this) == 0;