Implement PHP7 null coalesce operator
[hiphop-php.git] / hphp / parser / hphp.y
blobf5c7c48ae7826a3490579177fe457159d8f397c5
1 %{
2 // macros for bison
3 #define YYSTYPE HPHP::HPHP_PARSER_NS::Token
4 #define YYSTYPE_IS_TRIVIAL false
5 #define YYLTYPE HPHP::Location
6 #define YYLTYPE_IS_TRIVIAL true
7 #define YYERROR_VERBOSE
8 #define YYINITDEPTH 500
9 #define YYLEX_PARAM _p
11 #include "hphp/compiler/parser/parser.h"
12 #include <folly/Conv.h>
13 #include "hphp/util/text-util.h"
14 #include "hphp/util/logger.h"
16 #define line0 r.line0
17 #define char0 r.char0
18 #define line1 r.line1
19 #define char1 r.char1
21 #ifdef yyerror
22 #undef yyerror
23 #endif
24 #define yyerror(loc,p,msg) p->parseFatal(loc,msg)
26 #ifdef YYLLOC_DEFAULT
27 # undef YYLLOC_DEFAULT
28 #endif
29 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
30 #define YYLLOC_DEFAULT(Current, Rhs, N) \
31 do \
32 if (N) { \
33 (Current).first(YYRHSLOC (Rhs, 1)); \
34 (Current).last (YYRHSLOC (Rhs, N)); \
35 } else { \
36 (Current).line0 = (Current).line1 = YYRHSLOC (Rhs, 0).line1;\
37 (Current).char0 = (Current).char1 = YYRHSLOC (Rhs, 0).char1;\
38 } \
39 while (0); \
40 _p->setRuleLocation(&Current);
42 #define YYCOPY(To, From, Count) \
43 do { \
44 YYSIZE_T yyi; \
45 for (yyi = 0; yyi < (Count); yyi++) { \
46 (To)[yyi] = (From)[yyi]; \
47 } \
48 if (From != From ## a) { \
49 YYSTACK_FREE (From); \
50 } \
51 } \
52 while (0)
54 #define YYCOPY_RESET(To, From, Count) \
55 do \
56 { \
57 YYSIZE_T yyi; \
58 for (yyi = 0; yyi < (Count); yyi++) { \
59 (To)[yyi] = (From)[yyi]; \
60 (From)[yyi].reset(); \
61 } \
62 if (From != From ## a) { \
63 YYSTACK_FREE (From); \
64 } \
65 } \
66 while (0)
68 #define YYTOKEN_RESET(From, Count) \
69 do \
70 { \
71 YYSIZE_T yyi; \
72 for (yyi = 0; yyi < (Count); yyi++) { \
73 (From)[yyi].reset(); \
74 } \
75 if (From != From ## a) { \
76 YYSTACK_FREE (From); \
77 } \
78 } \
79 while (0)
81 # define YYSTACK_RELOCATE_RESET(Stack_alloc, Stack) \
82 do \
83 { \
84 YYSIZE_T yynewbytes; \
85 YYCOPY_RESET (&yyptr->Stack_alloc, Stack, yysize); \
86 Stack = &yyptr->Stack_alloc; \
87 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
88 yyptr += yynewbytes / sizeof (*yyptr); \
89 } \
90 while (0)
92 #define YYSTACK_CLEANUP \
93 YYTOKEN_RESET (yyvs, yystacksize); \
94 if (yyvs != yyvsa) { \
95 YYSTACK_FREE (yyvs); \
96 } \
97 if (yyls != yylsa) { \
98 YYSTACK_FREE (yyls); \
99 } \
102 // macros for rules
103 #define BEXP(...) _p->onBinaryOpExp(__VA_ARGS__);
104 #define UEXP(...) _p->onUnaryOpExp(__VA_ARGS__);
106 using namespace HPHP::HPHP_PARSER_NS;
108 typedef HPHP::ClosureType ClosureType;
110 ///////////////////////////////////////////////////////////////////////////////
111 // helpers
113 static void scalar_num(Parser *_p, Token &out, const char *num) {
114 Token t;
115 t.setText(num);
116 _p->onScalar(out, T_LNUMBER, t);
119 static void scalar_num(Parser *_p, Token &out, int num) {
120 Token t;
121 t.setText(folly::to<std::string>(num));
122 _p->onScalar(out, T_LNUMBER, t);
125 static void scalar_null(Parser *_p, Token &out) {
126 Token tnull; tnull.setText("null");
127 _p->onConstantValue(out, tnull);
130 static void scalar_file(Parser *_p, Token &out) {
131 Token file; file.setText("__FILE__");
132 _p->onScalar(out, T_FILE, file);
135 static void scalar_line(Parser *_p, Token &out) {
136 Token line; line.setText("__LINE__");
137 _p->onScalar(out, T_LINE, line);
140 ///////////////////////////////////////////////////////////////////////////////
142 static void constant_ae(Parser *_p, Token &out, Token &value) {
143 const std::string& valueStr = value.text();
144 if (valueStr.size() < 3 || valueStr.size() > 5 ||
145 (strcasecmp("true", valueStr.c_str()) != 0 &&
146 strcasecmp("false", valueStr.c_str()) != 0 &&
147 strcasecmp("null", valueStr.c_str()) != 0 &&
148 strcasecmp("inf", valueStr.c_str()) != 0 &&
149 strcasecmp("nan", valueStr.c_str()) != 0)) {
150 HPHP_PARSER_ERROR("User-defined constants are not allowed in user "
151 "attribute expressions", _p);
153 _p->onConstantValue(out, value);
156 ///////////////////////////////////////////////////////////////////////////////
159 * XHP functions: They are defined here, so different parsers don't have to
160 * handle XHP rules at all.
163 static void xhp_tag(Parser *_p, Token &out, Token &label, Token &body) {
164 if (!body.text().empty() && body.text() != label.text()) {
165 HPHP_PARSER_ERROR("XHP: mismatched tag: '%s' not the same as '%s'",
166 _p, body.text().c_str(), label.text().c_str());
169 label.xhpLabel();
170 Token name; _p->onName(name, label, Parser::StringName);
171 _p->onNewObject(out, name, body);
174 static void xhp_attribute(Parser *_p, Token &out, Token &type, Token &label,
175 Token &def, Token &req) {
177 * The bool, int, float, and string typenames are not given any special
178 * treatment by the parser and are treated the same as regular class names
179 * (which initially gets marked as type code 5). However, XHP wants to use
180 * different type codes for bool, int, float, and string, so we need to fix
181 * up the type code here to make XHP happy.
183 if (type.num() == 5) {
184 auto* str = type.text().c_str();
185 if (_p->scanner().isHHSyntaxEnabled()) {
186 switch (type.text().size()) {
187 case 6:
188 if (!strcasecmp(str, "HH\\int")) {
189 type.reset(); type.setNum(3);
191 break;
192 case 7:
193 if (!strcasecmp(str, "HH\\bool")) {
194 type.reset(); type.setNum(2);
196 break;
197 case 8:
198 if (!strcasecmp(str, "HH\\float")) {
199 type.reset(); type.setNum(8);
200 } else if (!strcasecmp(str, "HH\\mixed")) {
201 type.reset(); type.setNum(6);
203 break;
204 case 9:
205 if (!strcasecmp(str, "HH\\string")) {
206 type.reset(); type.setNum(1);
208 break;
209 default:
210 break;
212 } else {
213 switch (type.text().size()) {
214 case 3:
215 if (!strcasecmp(str, "int")) {
216 type.reset(); type.setNum(3);
218 break;
219 case 4:
220 if (!strcasecmp(str, "bool")) {
221 type.reset(); type.setNum(2);
222 } else if (!strcasecmp(str, "real")) {
223 type.reset(); type.setNum(8);
225 break;
226 case 5:
227 if (!strcasecmp(str, "float")) {
228 type.reset(); type.setNum(8);
229 } else if (!strcasecmp(str, "mixed")) {
230 type.reset(); type.setNum(6);
232 break;
233 case 6:
234 if (!strcasecmp(str, "string")) {
235 type.reset(); type.setNum(1);
236 } else if (!strcasecmp(str, "double")) {
237 type.reset(); type.setNum(8);
239 break;
240 case 7:
241 if (!strcasecmp(str, "integer")) {
242 type.reset(); type.setNum(3);
243 } else if (!strcasecmp(str, "boolean")) {
244 type.reset(); type.setNum(2);
246 break;
247 default:
248 break;
253 Token num; scalar_num(_p, num, type.num());
254 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
256 Token arr2;
257 switch (type.num()) {
258 case 5: /* class */ {
259 Token cls; _p->onScalar(cls, T_CONSTANT_ENCAPSED_STRING, type);
260 _p->onArrayPair(arr2, &arr1, 0, cls, 0);
261 break;
263 case 7: /* enum */ {
264 Token arr; _p->onArray(arr, type);
265 _p->onArrayPair(arr2, &arr1, 0, arr, 0);
266 break;
268 default: {
269 Token tnull; scalar_null(_p, tnull);
270 _p->onArrayPair(arr2, &arr1, 0, tnull, 0);
271 break;
275 Token arr3; _p->onArrayPair(arr3, &arr2, 0, def, 0);
276 Token arr4; _p->onArrayPair(arr4, &arr3, 0, req, 0);
277 _p->onArray(out, arr4);
278 out.setText(label);
281 static void xhp_attribute_list(Parser *_p, Token &out, Token *list,
282 Token &decl) {
283 if (decl.num() == 0) {
284 decl.xhpLabel();
285 if (list) {
286 out = *list;
287 out.setText(list->text() + ":" + decl.text()); // avoiding vector<string>
288 } else {
289 out.setText(decl);
291 } else {
292 Token name; _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, decl);
293 _p->onArrayPair(out, list, &name, decl, 0);
294 if (list) {
295 out.setText(list->text());
296 } else {
297 out.setText("");
302 static void xhp_attribute_stmt(Parser *_p, Token &out, Token &attributes) {
303 Token modifiers;
304 Token fname; fname.setText("__xhpAttributeDeclaration");
306 Token m;
307 Token m1; m1.setNum(T_PROTECTED); _p->onMemberModifier(m, NULL, m1);
308 Token m2; m2.setNum(T_STATIC); _p->onMemberModifier(modifiers, &m, m2);
310 _p->pushFuncLocation();
311 _p->onMethodStart(fname, modifiers);
313 std::vector<std::string> classes;
314 HPHP::split(':', attributes.text().c_str(), classes, true);
315 Token arrAttributes; _p->onArray(arrAttributes, attributes);
317 Token dummy;
319 Token stmts0;
321 _p->onStatementListStart(stmts0);
323 Token stmts1;
325 // static $_ = -1;
326 Token one; scalar_num(_p, one, "1");
327 Token mone; UEXP(mone, one, '-', 1);
328 Token var; var.set(T_VARIABLE, "_");
329 Token decl; _p->onStaticVariable(decl, 0, var, &mone);
330 Token sdecl; _p->onStatic(sdecl, decl);
331 _p->addStatement(stmts1, stmts0, sdecl);
333 Token stmts2;
335 // if ($_ === -1) {
336 // $_ = array_merge(parent::__xhpAttributeDeclaration(),
337 // attributes);
338 // }
339 Token parent; parent.set(T_STRING, "parent");
340 Token cls; _p->onName(cls, parent, Parser::StringName);
341 Token fname; fname.setText("__xhpAttributeDeclaration");
342 Token param1; _p->onCall(param1, 0, fname, dummy, &cls);
343 Token params1; _p->onCallParam(params1, NULL, param1, false, false);
345 for (unsigned int i = 0; i < classes.size(); i++) {
346 Token parent; parent.set(T_STRING, classes[i]);
347 Token cls; _p->onName(cls, parent, Parser::StringName);
348 Token fname; fname.setText("__xhpAttributeDeclaration");
349 Token param; _p->onCall(param, 0, fname, dummy, &cls);
351 Token params; _p->onCallParam(params, &params1, param, false, false);
352 params1 = params;
355 Token params2; _p->onCallParam(params2, &params1, arrAttributes,
356 false, false);
358 Token name; name.set(T_STRING, "array_merge");
359 Token call; _p->onCall(call, 0, name, params2, NULL);
360 Token tvar; tvar.set(T_VARIABLE, "_");
361 Token var; _p->onSimpleVariable(var, tvar);
362 Token assign; _p->onAssign(assign, var, call, 0);
363 Token exp; _p->onExpStatement(exp, assign);
364 Token block; _p->onBlock(block, exp);
366 Token tvar2; tvar2.set(T_VARIABLE, "_");
367 Token var2; _p->onSimpleVariable(var2, tvar2);
368 Token one; scalar_num(_p, one, "1");
369 Token mone; UEXP(mone, one, '-', 1);
370 Token cond; BEXP(cond, var2, mone, T_IS_IDENTICAL);
371 Token dummy1, dummy2;
372 Token sif; _p->onIf(sif, cond, block, dummy1, dummy2);
373 _p->addStatement(stmts2, stmts1, sif);
375 Token stmts3;
377 // return $_;
378 Token tvar; tvar.set(T_VARIABLE, "_");
379 Token var; _p->onSimpleVariable(var, tvar);
380 Token ret; _p->onReturn(ret, &var);
381 _p->addStatement(stmts3, stmts2, ret);
383 Token stmt;
385 _p->finishStatement(stmt, stmts3);
386 stmt = 1;
389 Token params, ret, ref; ref = 1;
390 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
394 static void xhp_collect_attributes(Parser *_p, Token &out, Token &stmts) {
395 Token *attr = _p->xhpGetAttributes();
396 if (attr) {
397 Token stmt;
398 xhp_attribute_stmt(_p, stmt, *attr);
399 _p->onClassStatement(out, stmts, stmt);
400 } else {
401 out = stmts;
405 static void xhp_category_stmt(Parser *_p, Token &out, Token &categories) {
406 Token fname; fname.setText("__xhpCategoryDeclaration");
407 Token m1; m1.setNum(T_PROTECTED);
408 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
409 _p->pushFuncLocation();
410 _p->onMethodStart(fname, modifiers);
412 Token stmts0;
414 _p->onStatementListStart(stmts0);
416 Token stmts1;
418 // static $_ = categories;
419 Token arr; _p->onArray(arr, categories);
420 Token var; var.set(T_VARIABLE, "_");
421 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
422 Token sdecl; _p->onStatic(sdecl, decl);
423 _p->addStatement(stmts1, stmts0, sdecl);
425 Token stmts2;
427 // return $_;
428 Token tvar; tvar.set(T_VARIABLE, "_");
429 Token var; _p->onSimpleVariable(var, tvar);
430 Token ret; _p->onReturn(ret, &var);
431 _p->addStatement(stmts2, stmts1, ret);
433 Token stmt;
435 _p->finishStatement(stmt, stmts2);
436 stmt = 1;
439 Token params, ret, ref; ref = 1;
440 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
444 static void xhp_children_decl_tag(Parser *_p, Token &arr, Token &tag) {
445 Token num; scalar_num(_p, num, tag.num());
446 Token arr1; _p->onArrayPair(arr1, &arr, 0, num, 0);
448 Token name;
449 if (tag.num() == 3 || tag.num() == 4) {
450 _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, tag);
451 } else if (tag.num() >= 0) {
452 scalar_null(_p, name);
453 } else {
454 HPHP_PARSER_ERROR("XHP: unknown children declaration", _p);
456 Token arr2; _p->onArrayPair(arr2, &arr1, 0, name, 0);
457 arr = arr2;
460 static void xhp_children_decl(Parser *_p, Token &out, Token &op1, int op,
461 Token *op2) {
462 Token num; scalar_num(_p, num, op);
463 Token arr; _p->onArrayPair(arr, 0, 0, num, 0);
465 if (op2) {
466 Token arr1; _p->onArrayPair(arr1, &arr, 0, op1, 0);
467 Token arr2; _p->onArrayPair(arr2, &arr1, 0, *op2, 0);
468 _p->onArray(out, arr2);
469 } else {
470 xhp_children_decl_tag(_p, arr, op1);
471 _p->onArray(out, arr);
475 static void xhp_children_paren(Parser *_p, Token &out, Token exp, int op) {
476 Token num; scalar_num(_p, num, op);
477 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
479 Token num5; scalar_num(_p, num5, 5);
480 Token arr2; _p->onArrayPair(arr2, &arr1, 0, num5, 0);
482 Token arr3; _p->onArrayPair(arr3, &arr2, 0, exp, 0);
483 _p->onArray(out, arr3);
486 static void xhp_children_stmt(Parser *_p, Token &out, Token &children) {
487 Token fname; fname.setText("__xhpChildrenDeclaration");
488 Token m1; m1.setNum(T_PROTECTED);
489 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
490 _p->pushFuncLocation();
491 _p->onMethodStart(fname, modifiers);
493 Token stmts0;
495 _p->onStatementListStart(stmts0);
497 Token stmts1;
499 // static $_ = children;
500 Token arr;
501 if (children.num() == 2) {
502 arr = children;
503 } else if (children.num() >= 0) {
504 scalar_num(_p, arr, children.num());
505 } else {
506 HPHP_PARSER_ERROR("XHP: XHP unknown children declaration", _p);
508 Token var; var.set(T_VARIABLE, "_");
509 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
510 Token sdecl; _p->onStatic(sdecl, decl);
511 _p->addStatement(stmts1, stmts0, sdecl);
513 Token stmts2;
515 // return $_;
516 Token tvar; tvar.set(T_VARIABLE, "_");
517 Token var; _p->onSimpleVariable(var, tvar);
518 Token ret; _p->onReturn(ret, &var);
519 _p->addStatement(stmts2, stmts1, ret);
521 Token stmt;
523 _p->finishStatement(stmt, stmts2);
524 stmt = 1;
527 Token params, ret, ref; ref = 1;
528 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
532 static void only_in_hh_syntax(Parser *_p) {
533 if (!_p->scanner().isHHSyntaxEnabled()) {
534 HPHP_PARSER_ERROR(
535 "Syntax only allowed in Hack files (<?hh) or with -v "
536 "Eval.EnableHipHopSyntax=true",
537 _p);
541 static void validate_hh_variadic_variant(Parser* _p,
542 Token& userAttrs, Token& typehint,
543 Token* mod) {
544 if (!userAttrs.text().empty() || !typehint.text().empty() ||
545 (mod && !mod->text().empty())) {
546 HPHP_PARSER_ERROR("Variadic '...' should be followed by a '$variable'", _p);
548 only_in_hh_syntax(_p);
551 // Shapes may not have leading integers in key names, considered as a
552 // parse time error. This is because at runtime they are currently
553 // hphp arrays, which will treat leading integer keys as numbers.
554 static void validate_shape_keyname(Token& tok, Parser* _p) {
555 if (tok.text().empty()) {
556 HPHP_PARSER_ERROR("Shape key names may not be empty", _p);
558 if (isdigit(tok.text()[0])) {
559 HPHP_PARSER_ERROR("Shape key names may not start with integers", _p);
563 ///////////////////////////////////////////////////////////////////////////////
565 static int yylex(YYSTYPE *token, HPHP::Location *loc, Parser *_p) {
566 return _p->scan(token, loc);
570 %expect 2
571 %define api.pure
572 %lex-param {HPHP::HPHP_PARSER_NS::Parser *_p}
573 %parse-param {HPHP::HPHP_PARSER_NS::Parser *_p}
575 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
576 %right T_LAMBDA_ARROW
577 %left ','
578 %nonassoc "..."
579 %left T_LOGICAL_OR
580 %left T_LOGICAL_XOR
581 %left T_LOGICAL_AND
582 %right T_PRINT
583 %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
584 %right T_AWAIT T_YIELD
585 %left '?' ':'
586 %right T_COALESCE
587 %left T_BOOLEAN_OR
588 %left T_BOOLEAN_AND
589 %left '|'
590 %left '^'
591 %left '&'
592 %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
593 %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL T_SPACESHIP
594 %left T_SL T_SR
595 %left '+' '-' '.'
596 %left '*' '/' '%'
597 %right '!'
598 %nonassoc T_INSTANCEOF
599 %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 '@'
600 %right T_POW
601 %right '['
603 %nonassoc T_NEW T_CLONE
604 %token T_EXIT
605 %token T_IF
606 %left T_ELSEIF
607 %left T_ELSE
608 %left T_ENDIF
609 %token T_LNUMBER /* long */
610 %token T_DNUMBER /* double */
611 %token T_ONUMBER /* overflowed decimal, might get parsed as long or double */
612 %token T_STRING
613 %token T_STRING_VARNAME
614 %token T_VARIABLE
615 %token T_NUM_STRING
616 %token T_INLINE_HTML
617 %token T_HASHBANG
618 %token T_CHARACTER
619 %token T_BAD_CHARACTER
620 %token T_ENCAPSED_AND_WHITESPACE
621 %token T_CONSTANT_ENCAPSED_STRING
622 %token T_ECHO
623 %token T_DO
624 %token T_WHILE
625 %token T_ENDWHILE
626 %token T_FOR
627 %token T_ENDFOR
628 %token T_FOREACH
629 %token T_ENDFOREACH
630 %token T_DECLARE
631 %token T_ENDDECLARE
632 %token T_AS
633 %token T_SUPER
634 %token T_SWITCH
635 %token T_ENDSWITCH
636 %token T_CASE
637 %token T_DEFAULT
638 %token T_BREAK
639 %token T_GOTO
640 %token T_CONTINUE
641 %token T_FUNCTION
642 %token T_CONST
643 %token T_RETURN
644 %token T_TRY
645 %token T_CATCH
646 %token T_THROW
647 %token T_USE
648 %token T_GLOBAL
649 %right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC
650 %token T_VAR
651 %token T_UNSET
652 %token T_ISSET
653 %token T_EMPTY
654 %token T_HALT_COMPILER
655 %token T_CLASS
656 %token T_INTERFACE
657 %token T_EXTENDS
658 %token T_IMPLEMENTS
659 %token T_OBJECT_OPERATOR
660 %token T_NULLSAFE_OBJECT_OPERATOR
661 %token T_DOUBLE_ARROW
662 %token T_LIST
663 %token T_ARRAY
664 %token T_CALLABLE
665 %token T_CLASS_C
666 %token T_METHOD_C
667 %token T_FUNC_C
668 %token T_LINE
669 %token T_FILE
670 %token T_COMMENT
671 %token T_DOC_COMMENT
672 %token T_OPEN_TAG
673 %token T_OPEN_TAG_WITH_ECHO
674 %token T_CLOSE_TAG
675 %token T_WHITESPACE
676 %token T_START_HEREDOC
677 %token T_END_HEREDOC
678 %token T_DOLLAR_OPEN_CURLY_BRACES
679 %token T_CURLY_OPEN
680 %token T_DOUBLE_COLON
681 %token T_NAMESPACE
682 %token T_NS_C
683 %token T_DIR
684 %token T_NS_SEPARATOR
686 %token T_XHP_LABEL
687 %token T_XHP_TEXT
688 %token T_XHP_ATTRIBUTE
689 %token T_XHP_CATEGORY
690 %token T_XHP_CATEGORY_LABEL
691 %token T_XHP_CHILDREN
692 %token T_ENUM
693 %token T_XHP_REQUIRED
695 %token T_TRAIT
696 %token T_ELLIPSIS "..."
697 %token T_COALESCE "??"
698 %token T_INSTEADOF
699 %token T_TRAIT_C
701 %token T_HH_ERROR
702 %token T_FINALLY
704 %token T_XHP_TAG_LT
705 %token T_XHP_TAG_GT
706 %token T_TYPELIST_LT
707 %token T_TYPELIST_GT
708 %token T_UNRESOLVED_LT
710 %token T_COLLECTION
711 %token T_SHAPE
712 %token T_TYPE
713 %token T_UNRESOLVED_TYPE
714 %token T_NEWTYPE
715 %token T_UNRESOLVED_NEWTYPE
717 %token T_COMPILER_HALT_OFFSET
718 %token T_ASYNC
720 %token T_LAMBDA_OP
721 %token T_LAMBDA_CP
722 %token T_UNRESOLVED_OP
726 start:
727 { _p->onNewLabelScope(true);
728 _p->initParseTree();}
729 top_statement_list
730 { _p->popLabelInfo();
731 _p->finiParseTree();
732 _p->onCompleteLabelScope(true);}
735 top_statement_list:
736 top_statement_list
737 top_statement { _p->addTopStatement($2);}
738 | { }
740 top_statement:
741 statement { _p->nns($1.num(), $1.text()); $$ = $1;}
742 | function_declaration_statement { _p->nns(); $$ = $1;}
743 | class_declaration_statement { _p->nns(); $$ = $1;}
744 | enum_declaration_statement { _p->nns(); $$ = $1;}
745 | trait_declaration_statement { _p->nns(); $$ = $1;}
746 | hh_type_alias_statement { $$ = $1; }
747 | T_HALT_COMPILER '(' ')' ';' { _p->onHaltCompiler();
748 _p->finiParseTree();
749 YYACCEPT;}
750 | T_NAMESPACE namespace_name ';' { _p->onNamespaceStart($2.text(), true);
751 $$.reset();}
752 | T_NAMESPACE namespace_name '{' { _p->onNamespaceStart($2.text());}
753 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $5;}
754 | T_NAMESPACE '{' { _p->onNamespaceStart("");}
755 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $4;}
756 | T_USE use_declarations ';' { _p->nns(); $$.reset();}
757 | T_USE T_FUNCTION
758 use_fn_declarations ';' { _p->nns(); $$.reset();}
759 | T_USE T_CONST
760 use_const_declarations ';' { _p->nns(); $$.reset();}
761 | constant_declaration ';' { _p->nns();
762 _p->finishStatement($$, $1); $$ = 1;}
765 ident_no_semireserved:
766 T_STRING { $$ = $1;}
767 | T_SUPER { $$ = $1;}
768 | T_XHP_ATTRIBUTE { $$ = $1;}
769 | T_XHP_CATEGORY { $$ = $1;}
770 | T_XHP_CHILDREN { $$ = $1;}
771 | T_XHP_REQUIRED { $$ = $1;}
772 | T_ENUM { $$ = $1;}
775 ident_for_class_const:
776 ident_no_semireserved
777 | T_CALLABLE
778 | T_TRAIT
779 | T_EXTENDS
780 | T_IMPLEMENTS
781 | T_STATIC
782 | T_ABSTRACT
783 | T_FINAL
784 | T_PRIVATE
785 | T_PROTECTED
786 | T_PUBLIC
787 | T_CONST
788 | T_ENDDECLARE
789 | T_ENDFOR
790 | T_ENDFOREACH
791 | T_ENDIF
792 | T_ENDWHILE
793 | T_LOGICAL_AND
794 | T_GLOBAL
795 | T_GOTO
796 | T_INSTANCEOF
797 | T_INSTEADOF
798 | T_INTERFACE
799 | T_NAMESPACE
800 | T_NEW
801 | T_LOGICAL_OR
802 | T_LOGICAL_XOR
803 | T_TRY
804 | T_USE
805 | T_VAR
806 | T_EXIT
807 | T_LIST
808 | T_CLONE
809 | T_INCLUDE
810 | T_INCLUDE_ONCE
811 | T_THROW
812 | T_ARRAY
813 | T_PRINT
814 | T_ECHO
815 | T_REQUIRE
816 | T_REQUIRE_ONCE
817 | T_RETURN
818 | T_ELSE
819 | T_ELSEIF
820 | T_DEFAULT
821 | T_BREAK
822 | T_CONTINUE
823 | T_SWITCH
824 | T_YIELD
825 | T_FUNCTION
826 | T_IF
827 | T_ENDSWITCH
828 | T_FINALLY
829 | T_FOR
830 | T_FOREACH
831 | T_DECLARE
832 | T_CASE
833 | T_DO
834 | T_WHILE
835 | T_AS
836 | T_CATCH
837 /* no T_DIE ? */
838 /** The following must be made semi-reserved since they were keywords in HHVM
839 * but not PHP. */
840 | T_UNSET
843 ident:
844 ident_for_class_const
845 | T_CLASS
848 use_declarations:
849 use_declarations ','
850 use_declaration { }
851 | use_declaration { }
854 use_fn_declarations:
855 use_fn_declarations ','
856 use_fn_declaration { }
857 | use_fn_declaration { }
860 use_const_declarations:
861 use_const_declarations ','
862 use_const_declaration { }
863 | use_const_declaration { }
866 use_declaration:
867 namespace_name { _p->onUse($1.text(),"");}
868 | T_NS_SEPARATOR namespace_name { _p->onUse($2.text(),"");}
869 | namespace_name T_AS ident_no_semireserved { _p->onUse($1.text(),$3.text());}
870 | T_NS_SEPARATOR namespace_name
871 T_AS ident_no_semireserved { _p->onUse($2.text(),$4.text());}
874 use_fn_declaration:
875 namespace_name { _p->onUseFunction($1.text(),"");}
876 | T_NS_SEPARATOR namespace_name { _p->onUseFunction($2.text(),"");}
877 | namespace_name T_AS ident_no_semireserved { _p->onUseFunction($1.text(),$3.text());}
878 | T_NS_SEPARATOR namespace_name
879 T_AS ident_no_semireserved { _p->onUseFunction($2.text(),$4.text());}
882 use_const_declaration:
883 namespace_name { _p->onUseConst($1.text(),"");}
884 | T_NS_SEPARATOR namespace_name { _p->onUseConst($2.text(),"");}
885 | namespace_name T_AS ident_no_semireserved { _p->onUseConst($1.text(),$3.text());}
886 | T_NS_SEPARATOR namespace_name
887 T_AS ident_no_semireserved { _p->onUseConst($2.text(),$4.text());}
890 namespace_name:
891 ident_no_semireserved { $$ = $1;}
892 | namespace_name T_NS_SEPARATOR
893 ident_no_semireserved { $$ = $1 + $2 + $3; $$ = $1.num() | 2;}
895 namespace_string:
896 namespace_name { $$ = $1; $$ = $$.num() | 1;}
897 | T_NAMESPACE T_NS_SEPARATOR
898 namespace_name { $$.set($3.num() | 2, _p->nsDecl($3.text()));}
899 | T_NS_SEPARATOR namespace_name { $$ = $2; $$ = $$.num() | 2;}
902 namespace_string_typeargs:
903 namespace_string
904 hh_typeargs_opt { if ($1.num() & 1) {
905 $1.setText(_p->resolve($1.text(),0));
907 $$ = $1;}
909 class_namespace_string_typeargs:
910 namespace_string
911 hh_typeargs_opt { if ($1.num() & 1) {
912 $1.setText(_p->resolve($1.text(),1));
914 _p->onTypeAnnotation($$, $1, $2);}
916 constant_declaration:
917 constant_declaration ','
918 hh_name_with_type
919 '=' static_expr { $3.setText(_p->nsDecl($3.text()));
920 _p->onConst($$,$3,$5);}
921 | T_CONST hh_name_with_type '='
922 static_expr { $2.setText(_p->nsDecl($2.text()));
923 _p->onConst($$,$2,$4);}
926 inner_statement_list:
927 inner_statement_list
928 inner_statement { _p->addStatement($$,$1,$2);}
929 | { _p->onStatementListStart($$);}
931 inner_statement:
932 statement { $$ = $1;}
933 | function_declaration_statement { $$ = $1;}
934 | class_declaration_statement { $$ = $1;}
935 | trait_declaration_statement { $$ = $1;}
937 statement:
938 '{' inner_statement_list '}' { _p->onBlock($$, $2);}
939 | T_IF parenthesis_expr
940 statement
941 elseif_list
942 else_single { _p->onIf($$,$2,$3,$4,$5);}
943 | T_IF parenthesis_expr ':'
944 inner_statement_list
945 new_elseif_list
946 new_else_single
947 T_ENDIF ';' { _p->onIf($$,$2,$4,$5,$6);}
948 | T_WHILE parenthesis_expr { _p->onNewLabelScope(false);
949 _p->pushLabelScope();}
950 while_statement { _p->popLabelScope();
951 _p->onWhile($$,$2,$4);
952 _p->onCompleteLabelScope(false);}
954 | T_DO { _p->onNewLabelScope(false);
955 _p->pushLabelScope();}
956 statement T_WHILE parenthesis_expr
957 ';' { _p->popLabelScope();
958 _p->onDo($$,$3,$5);
959 _p->onCompleteLabelScope(false);}
960 | T_FOR '(' for_expr ';'
961 for_expr ';' for_expr ')' { _p->onNewLabelScope(false);
962 _p->pushLabelScope();}
963 for_statement { _p->popLabelScope();
964 _p->onFor($$,$3,$5,$7,$10);
965 _p->onCompleteLabelScope(false);}
966 | T_SWITCH parenthesis_expr { _p->onNewLabelScope(false);
967 _p->pushLabelScope();}
968 switch_case_list { _p->popLabelScope();
969 _p->onSwitch($$,$2,$4);
970 _p->onCompleteLabelScope(false);}
971 | T_BREAK ';' { _p->onBreakContinue($$, true, NULL);}
972 | T_BREAK expr ';' { _p->onBreakContinue($$, true, &$2);}
973 | T_CONTINUE ';' { _p->onBreakContinue($$, false, NULL);}
974 | T_CONTINUE expr ';' { _p->onBreakContinue($$, false, &$2);}
975 | T_RETURN ';' { _p->onReturn($$, NULL);}
976 | T_RETURN expr ';' { _p->onReturn($$, &$2);}
977 | T_YIELD T_BREAK ';' { _p->onYieldBreak($$);}
978 | T_GLOBAL global_var_list ';' { _p->onGlobal($$, $2);}
979 | T_STATIC static_var_list ';' { _p->onStatic($$, $2);}
980 | T_ECHO expr_list ';' { _p->onEcho($$, $2, 0);}
981 | T_OPEN_TAG_WITH_ECHO expr_list ';' { _p->onEcho($$, $2, 0);}
982 | T_UNSET '(' variable_list ')' ';' { _p->onUnset($$, $3);}
983 | ';' { $$.reset(); $$ = ';';}
984 | T_INLINE_HTML { _p->onEcho($$, $1, 1);}
985 | T_HASHBANG { _p->onHashBang($$, $1);
986 $$ = T_HASHBANG;}
987 | T_FOREACH '(' expr
988 T_AS foreach_variable
989 foreach_optional_arg ')' { _p->onNewLabelScope(false);
990 _p->pushLabelScope();}
991 foreach_statement { _p->popLabelScope();
992 _p->onForEach($$,$3,$5,$6,$9, false);
993 _p->onCompleteLabelScope(false);}
994 | T_FOREACH '(' expr
995 T_AWAIT T_AS foreach_variable
996 foreach_optional_arg ')' { _p->onNewLabelScope(false);
997 _p->pushLabelScope();}
998 foreach_statement { _p->popLabelScope();
999 _p->onForEach($$,$3,$6,$7,$10, true);
1000 _p->onCompleteLabelScope(false);}
1001 | T_DECLARE '(' declare_list ')'
1002 declare_statement { _p->onBlock($$, $5); $$ = T_DECLARE;}
1003 | T_TRY
1004 try_statement_list
1005 T_CATCH '('
1006 fully_qualified_class_name
1007 T_VARIABLE ')' '{'
1008 inner_statement_list '}'
1009 additional_catches { _p->onCompleteLabelScope(false);}
1010 optional_finally { _p->onTry($$,$2,$5,$6,$9,$11,$13);}
1011 | T_TRY
1012 try_statement_list
1013 T_FINALLY { _p->onCompleteLabelScope(false);}
1014 finally_statement_list { _p->onTry($$, $2, $5);}
1015 | T_THROW expr ';' { _p->onThrow($$, $2);}
1016 | T_GOTO ident_no_semireserved ';' { _p->onGoto($$, $2, true);
1017 _p->addGoto($2.text(),
1018 _p->getRange(),
1019 &$$);}
1020 | expr ';' { _p->onExpStatement($$, $1);}
1021 | yield_expr ';' { _p->onExpStatement($$, $1);}
1022 | yield_assign_expr ';' { _p->onExpStatement($$, $1);}
1023 | yield_list_assign_expr ';' { _p->onExpStatement($$, $1);}
1024 | await_expr ';' { _p->onExpStatement($$, $1);}
1025 | await_assign_expr ';' { _p->onExpStatement($$, $1);}
1026 | T_RETURN await_expr ';' { _p->onReturn($$, &$2); }
1027 | await_list_assign_expr ';' { _p->onExpStatement($$, $1);}
1028 | ident_no_semireserved ':' { _p->onLabel($$, $1);
1029 _p->addLabel($1.text(),
1030 _p->getRange(),
1031 &$$);
1032 _p->onScopeLabel($$, $1);}
1035 try_statement_list:
1036 '{' { _p->onNewLabelScope(false);}
1037 inner_statement_list '}' { $$ = $3;}
1040 additional_catches:
1041 additional_catches
1042 T_CATCH '('
1043 fully_qualified_class_name
1044 T_VARIABLE ')'
1046 inner_statement_list '}' { _p->onCatch($$, $1, $4, $5, $8);}
1047 | { $$.reset();}
1050 finally_statement_list:
1051 '{' { _p->onNewLabelScope(false);
1052 _p->pushLabelScope();}
1053 inner_statement_list '}' { _p->popLabelScope();
1054 _p->onFinally($$, $3);
1055 _p->onCompleteLabelScope(false);}
1058 optional_finally:
1059 T_FINALLY finally_statement_list { $$ = $2;}
1060 | { $$.reset();}
1063 is_reference:
1064 '&' { $$ = 1;}
1065 | { $$.reset();}
1068 function_loc:
1069 T_FUNCTION { _p->pushFuncLocation(); }
1072 function_declaration_statement:
1073 function_loc
1074 is_reference
1075 hh_name_no_semireserved_with_typevar { $3.setText(_p->nsDecl($3.text()));
1076 _p->onNewLabelScope(true);
1077 _p->onFunctionStart($3);
1078 _p->pushLabelInfo();}
1079 '(' parameter_list ')'
1080 hh_opt_return_type
1081 function_body { _p->onFunction($$,nullptr,$8,$2,$3,$6,$9,nullptr);
1082 _p->popLabelInfo();
1083 _p->popTypeScope();
1084 _p->onCompleteLabelScope(true);}
1085 | non_empty_member_modifiers
1086 function_loc
1087 is_reference
1088 hh_name_no_semireserved_with_typevar { $4.setText(_p->nsDecl($4.text()));
1089 _p->onNewLabelScope(true);
1090 _p->onFunctionStart($4);
1091 _p->pushLabelInfo();}
1092 '(' parameter_list ')'
1093 hh_opt_return_type
1094 function_body { _p->onFunction($$,&$1,$9,$3,$4,$7,$10,nullptr);
1095 _p->popLabelInfo();
1096 _p->popTypeScope();
1097 _p->onCompleteLabelScope(true);}
1098 | non_empty_user_attributes
1099 method_modifiers function_loc
1100 is_reference
1101 hh_name_no_semireserved_with_typevar { $5.setText(_p->nsDecl($5.text()));
1102 _p->onNewLabelScope(true);
1103 _p->onFunctionStart($5);
1104 _p->pushLabelInfo();}
1105 '(' parameter_list ')'
1106 hh_opt_return_type
1107 function_body { _p->onFunction($$,&$2,$10,$4,$5,$8,$11,&$1);
1108 _p->popLabelInfo();
1109 _p->popTypeScope();
1110 _p->onCompleteLabelScope(true);}
1113 enum_declaration_statement:
1114 T_ENUM
1115 ident_no_semireserved { $2.setText(_p->nsClassDecl($2.text()));
1116 _p->onClassStart(T_ENUM,$2);}
1117 ':' hh_type
1118 hh_opt_constraint
1119 '{' enum_statement_list '}' { _p->onEnum($$,$2,$5,$8,0); }
1121 | non_empty_user_attributes
1122 T_ENUM
1123 ident_no_semireserved { $3.setText(_p->nsClassDecl($3.text()));
1124 _p->onClassStart(T_ENUM,$3);}
1125 ':' hh_type
1126 hh_opt_constraint
1127 '{' enum_statement_list '}' { _p->onEnum($$,$3,$6,$9,&$1); }
1131 class_declaration_statement:
1132 class_entry_type
1133 class_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1134 _p->onClassStart($1.num(),$2);}
1135 extends_from implements_list '{'
1136 class_statement_list '}' { Token stmts;
1137 if (_p->peekClass()) {
1138 xhp_collect_attributes(_p,stmts,$7);
1139 } else {
1140 stmts = $7;
1142 _p->onClass($$,$1.num(),$2,$4,$5,
1143 stmts,0,nullptr);
1144 if (_p->peekClass()) {
1145 _p->xhpResetAttributes();
1147 _p->popClass();
1148 _p->popTypeScope();}
1149 | non_empty_user_attributes
1150 class_entry_type
1151 class_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1152 _p->onClassStart($2.num(),$3);}
1153 extends_from implements_list '{'
1154 class_statement_list '}' { Token stmts;
1155 if (_p->peekClass()) {
1156 xhp_collect_attributes(_p,stmts,$8);
1157 } else {
1158 stmts = $8;
1160 _p->onClass($$,$2.num(),$3,$5,$6,
1161 stmts,&$1,nullptr);
1162 if (_p->peekClass()) {
1163 _p->xhpResetAttributes();
1165 _p->popClass();
1166 _p->popTypeScope();}
1167 | T_INTERFACE
1168 interface_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1169 _p->onClassStart(T_INTERFACE,$2);}
1170 interface_extends_list '{'
1171 class_statement_list '}' { _p->onInterface($$,$2,$4,$6,0);
1172 _p->popClass();
1173 _p->popTypeScope();}
1174 | non_empty_user_attributes
1175 T_INTERFACE
1176 interface_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1177 _p->onClassStart(T_INTERFACE,$3);}
1178 interface_extends_list '{'
1179 class_statement_list '}' { _p->onInterface($$,$3,$5,$7,&$1);
1180 _p->popClass();
1181 _p->popTypeScope();}
1184 class_expression:
1185 T_CLASS { _p->onClassExpressionStart(); }
1186 ctor_arguments
1187 extends_from implements_list '{'
1188 class_statement_list '}' { _p->onClassExpression($$, $3, $4, $5, $7); }
1190 trait_declaration_statement:
1191 T_TRAIT
1192 trait_decl_name { $2.setText(_p->nsClassDecl($2.text()));
1193 _p->onClassStart(T_TRAIT, $2);}
1194 implements_list
1195 '{' class_statement_list '}' { Token t_ext;
1196 t_ext.reset();
1197 _p->onClass($$,T_TRAIT,$2,t_ext,$4,
1198 $6, 0, nullptr);
1199 _p->popClass();
1200 _p->popTypeScope();}
1201 | non_empty_user_attributes
1202 T_TRAIT
1203 trait_decl_name { $3.setText(_p->nsClassDecl($3.text()));
1204 _p->onClassStart(T_TRAIT, $3);}
1205 implements_list
1206 '{' class_statement_list '}' { Token t_ext;
1207 t_ext.reset();
1208 _p->onClass($$,T_TRAIT,$3,t_ext,$5,
1209 $7, &$1, nullptr);
1210 _p->popClass();
1211 _p->popTypeScope();}
1213 class_decl_name:
1214 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1215 | T_XHP_LABEL { $1.xhpLabel(); _p->pushTypeScope();
1216 _p->pushClass(true); $$ = $1;}
1218 interface_decl_name:
1219 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1221 trait_decl_name:
1222 hh_name_no_semireserved_with_typevar { _p->pushClass(false); $$ = $1;}
1224 class_entry_type:
1225 T_CLASS { $$ = T_CLASS;}
1226 | T_ABSTRACT T_CLASS { $$ = T_ABSTRACT; }
1227 | T_ABSTRACT T_FINAL T_CLASS { only_in_hh_syntax(_p);
1228 /* hacky, but transforming to a single token is quite convenient */
1229 $$ = T_STATIC; }
1230 | T_FINAL T_ABSTRACT T_CLASS { only_in_hh_syntax(_p); $$ = T_STATIC; }
1231 | T_FINAL T_CLASS { $$ = T_FINAL;}
1233 extends_from:
1234 T_EXTENDS
1235 fully_qualified_class_name { $$ = $2;}
1236 | { $$.reset();}
1238 implements_list:
1239 T_IMPLEMENTS interface_list { $$ = $2;}
1240 | { $$.reset();}
1242 interface_extends_list:
1243 T_EXTENDS interface_list { $$ = $2;}
1244 | { $$.reset();}
1246 interface_list:
1247 fully_qualified_class_name { _p->onInterfaceName($$, NULL, $1);}
1248 | interface_list ','
1249 fully_qualified_class_name { _p->onInterfaceName($$, &$1, $3);}
1251 trait_list:
1252 fully_qualified_class_name { _p->onTraitName($$, NULL, $1);}
1253 | trait_list ','
1254 fully_qualified_class_name { _p->onTraitName($$, &$1, $3);}
1257 foreach_optional_arg:
1258 T_DOUBLE_ARROW foreach_variable { $$ = $2;}
1259 | { $$.reset();}
1261 foreach_variable:
1262 variable { $$ = $1; $$ = 0;}
1263 | '&' variable { $$ = $2; $$ = 1;}
1264 | T_LIST '(' assignment_list ')' { _p->onListAssignment($$, $3, NULL);}
1267 for_statement:
1268 statement { $$ = $1;}
1269 | ':' inner_statement_list
1270 T_ENDFOR ';' { $$ = $2;}
1272 foreach_statement:
1273 statement { $$ = $1;}
1274 | ':' inner_statement_list
1275 T_ENDFOREACH ';' { $$ = $2;}
1277 while_statement:
1278 statement { $$ = $1;}
1279 | ':' inner_statement_list
1280 T_ENDWHILE ';' { $$ = $2;}
1282 declare_statement:
1283 statement { $$ = $1;}
1284 | ':' inner_statement_list
1285 T_ENDDECLARE ';' { $$ = $2;}
1288 declare_list:
1289 ident_no_semireserved '=' static_expr
1290 | declare_list ','
1291 ident_no_semireserved '=' static_expr
1294 switch_case_list:
1295 '{' case_list '}' { $$ = $2;}
1296 | '{' ';' case_list '}' { $$ = $3;}
1297 | ':' case_list T_ENDSWITCH ';' { $$ = $2;}
1298 | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3;}
1300 case_list:
1301 case_list T_CASE expr
1302 case_separator
1303 inner_statement_list { _p->onCase($$,$1,&$3,$5);}
1304 | case_list T_DEFAULT case_separator
1305 inner_statement_list { _p->onCase($$,$1,NULL,$4);}
1306 | { $$.reset();}
1308 case_separator:
1309 ':' { $$.reset();}
1310 | ';' { $$.reset();}
1313 elseif_list:
1314 elseif_list T_ELSEIF parenthesis_expr
1315 statement { _p->onElseIf($$,$1,$3,$4);}
1316 | { $$.reset();}
1318 new_elseif_list:
1319 new_elseif_list T_ELSEIF
1320 parenthesis_expr ':'
1321 inner_statement_list { _p->onElseIf($$,$1,$3,$5);}
1322 | { $$.reset();}
1324 else_single:
1325 T_ELSE statement { $$ = $2;}
1326 | { $$.reset();}
1328 new_else_single:
1329 T_ELSE ':' inner_statement_list { $$ = $3;}
1330 | { $$.reset();}
1333 method_parameter_list:
1334 non_empty_method_parameter_list ','
1335 optional_user_attributes
1336 parameter_modifiers
1337 hh_type_opt "..." T_VARIABLE
1338 { _p->onVariadicParam($$,&$1,$5,$7,false,
1339 &$3,&$4); }
1340 | non_empty_method_parameter_list ','
1341 optional_user_attributes
1342 parameter_modifiers
1343 hh_type_opt '&' "..." T_VARIABLE
1344 { _p->onVariadicParam($$,&$1,$5,$8,true,
1345 &$3,&$4); }
1346 | non_empty_method_parameter_list ','
1347 optional_user_attributes
1348 parameter_modifiers
1349 hh_type_opt "..."
1350 { validate_hh_variadic_variant(
1351 _p, $3, $5, &$4);
1352 $$ = $1; }
1353 | non_empty_method_parameter_list
1354 hh_possible_comma { $$ = $1;}
1355 | optional_user_attributes
1356 parameter_modifiers
1357 hh_type_opt "..." T_VARIABLE
1358 { _p->onVariadicParam($$,NULL,$3,$5,false,
1359 &$1,&$2); }
1360 | optional_user_attributes
1361 parameter_modifiers
1362 hh_type_opt '&' "..." T_VARIABLE
1363 { _p->onVariadicParam($$,NULL,$3,$6,true,
1364 &$1,&$2); }
1365 | optional_user_attributes
1366 parameter_modifiers
1367 hh_type_opt "..."
1368 { validate_hh_variadic_variant(
1369 _p, $1, $3, &$2);
1370 $$.reset(); }
1371 | { $$.reset(); }
1374 non_empty_method_parameter_list:
1375 optional_user_attributes
1376 parameter_modifiers
1377 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$3,$4,0,
1378 NULL,&$1,&$2);}
1379 | optional_user_attributes
1380 parameter_modifiers
1381 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$3,$5,1,
1382 NULL,&$1,&$2);}
1383 | optional_user_attributes
1384 parameter_modifiers
1385 hh_type_opt '&' T_VARIABLE
1386 '=' expr { _p->onParam($$,NULL,$3,$5,1,
1387 &$7,&$1,&$2);}
1388 | optional_user_attributes
1389 parameter_modifiers
1390 hh_type_opt T_VARIABLE
1391 '=' expr { _p->onParam($$,NULL,$3,$4,0,
1392 &$6,&$1,&$2);}
1393 | non_empty_method_parameter_list ','
1394 optional_user_attributes
1395 parameter_modifiers
1396 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$5,$6,0,
1397 NULL,&$3,&$4);}
1398 | non_empty_method_parameter_list ','
1399 optional_user_attributes
1400 parameter_modifiers
1401 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$5,$7,1,
1402 NULL,&$3,&$4);}
1403 | non_empty_method_parameter_list ','
1404 optional_user_attributes
1405 parameter_modifiers
1406 hh_type_opt '&' T_VARIABLE
1407 '=' expr { _p->onParam($$,&$1,$5,$7,1,
1408 &$9,&$3,&$4);}
1409 | non_empty_method_parameter_list ','
1410 optional_user_attributes
1411 parameter_modifiers
1412 hh_type_opt T_VARIABLE
1413 '=' expr { _p->onParam($$,&$1,$5,$6,0,
1414 &$8,&$3,&$4);}
1417 parameter_list:
1418 non_empty_parameter_list ','
1419 optional_user_attributes
1420 hh_type_opt "..." T_VARIABLE
1421 { _p->onVariadicParam($$,&$1,$4,$6,
1422 false,&$3,NULL); }
1423 | non_empty_parameter_list ','
1424 optional_user_attributes
1425 hh_type_opt '&' "..." T_VARIABLE
1426 { _p->onVariadicParam($$,&$1,$4,$7,
1427 true,&$3,NULL); }
1428 | non_empty_parameter_list ','
1429 optional_user_attributes
1430 hh_type_opt "..."
1431 { validate_hh_variadic_variant(
1432 _p, $3, $4, NULL);
1433 $$ = $1; }
1434 | non_empty_parameter_list
1435 hh_possible_comma { $$ = $1;}
1436 | optional_user_attributes
1437 hh_type_opt "..." T_VARIABLE
1438 { _p->onVariadicParam($$,NULL,$2,$4,
1439 false,&$1,NULL); }
1440 | optional_user_attributes
1441 hh_type_opt '&' "..." T_VARIABLE
1442 { _p->onVariadicParam($$,NULL,$2,$5,
1443 true,&$1,NULL); }
1444 | optional_user_attributes
1445 hh_type_opt "..."
1446 { validate_hh_variadic_variant(
1447 _p, $1, $2, NULL);
1448 $$.reset(); }
1449 | { $$.reset();}
1452 non_empty_parameter_list:
1453 optional_user_attributes
1454 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$2,$3,false,
1455 NULL,&$1,NULL); }
1456 | optional_user_attributes
1457 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$2,$4,true,
1458 NULL,&$1,NULL); }
1459 | optional_user_attributes
1460 hh_type_opt '&' T_VARIABLE
1461 '=' expr { _p->onParam($$,NULL,$2,$4,true,
1462 &$6,&$1,NULL); }
1463 | optional_user_attributes
1464 hh_type_opt T_VARIABLE
1465 '=' expr { _p->onParam($$,NULL,$2,$3,false,
1466 &$5,&$1,NULL); }
1467 | non_empty_parameter_list ','
1468 optional_user_attributes
1469 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$4,$5,false,
1470 NULL,&$3,NULL); }
1471 | non_empty_parameter_list ','
1472 optional_user_attributes
1473 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$4,$6,true,
1474 NULL,&$3,NULL); }
1475 | non_empty_parameter_list ','
1476 optional_user_attributes
1477 hh_type_opt '&' T_VARIABLE
1478 '=' expr { _p->onParam($$,&$1,$4,$6,true,
1479 &$8,&$3,NULL); }
1480 | non_empty_parameter_list ','
1481 optional_user_attributes
1482 hh_type_opt T_VARIABLE
1483 '=' expr { _p->onParam($$,&$1,$4,$5,false,
1484 &$7,&$3,NULL); }
1487 function_call_parameter_list:
1488 non_empty_fcall_parameter_list
1489 hh_possible_comma { $$ = $1;}
1490 | { $$.reset();}
1492 non_empty_fcall_parameter_list:
1493 expr { _p->onCallParam($$,NULL,$1,false,false);}
1494 | '&' variable { _p->onCallParam($$,NULL,$2,true,false);}
1495 | "..." expr { _p->onCallParam($$,NULL,$2,false,true);}
1496 | non_empty_fcall_parameter_list
1497 ',' expr { _p->onCallParam($$,&$1,$3,false, false);}
1498 | non_empty_fcall_parameter_list
1499 ',' "..." expr { _p->onCallParam($$,&$1,$4,false,true);}
1500 | non_empty_fcall_parameter_list
1501 ',' '&' variable { _p->onCallParam($$,&$1,$4,true, false);}
1504 global_var_list:
1505 global_var_list ',' global_var { _p->onGlobalVar($$, &$1, $3);}
1506 | global_var { _p->onGlobalVar($$, NULL, $1);}
1508 global_var:
1509 T_VARIABLE { $$ = $1;}
1510 | '$' variable { $$ = $2; $$ = 1;}
1511 | '$' '{' expr '}' { $$ = $3; $$ = 1;}
1514 static_var_list:
1515 static_var_list ',' T_VARIABLE { _p->onStaticVariable($$,&$1,$3,0);}
1516 | static_var_list ',' T_VARIABLE
1517 '=' static_expr { _p->onStaticVariable($$,&$1,$3,&$5);}
1518 | T_VARIABLE { _p->onStaticVariable($$,0,$1,0);}
1519 | T_VARIABLE '=' static_expr { _p->onStaticVariable($$,0,$1,&$3);}
1522 enum_statement_list:
1523 enum_statement_list
1524 enum_statement { _p->onClassStatement($$, $1, $2);}
1525 | { $$.reset();}
1527 enum_statement:
1528 enum_constant_declaration ';' { _p->onClassVariableStart
1529 ($$,NULL,$1,NULL);}
1531 enum_constant_declaration:
1532 hh_constname_with_type '='
1533 static_expr { _p->onClassConstant($$,0,$1,$3);}
1537 class_statement_list:
1538 class_statement_list
1539 class_statement { _p->onClassStatement($$, $1, $2);}
1540 | { $$.reset();}
1542 class_statement:
1543 variable_modifiers { _p->onClassVariableModifer($1);}
1544 class_variable_declaration ';' { _p->onClassVariableStart
1545 ($$,&$1,$3,NULL);}
1546 | non_empty_member_modifiers
1547 hh_type { _p->onClassVariableModifer($1);}
1548 class_variable_declaration ';' { _p->onClassVariableStart
1549 ($$,&$1,$4,&$2);}
1550 | class_constant_declaration ';' { _p->onClassVariableStart
1551 ($$,NULL,$1,NULL);}
1552 | class_abstract_constant_declaration ';'
1553 { _p->onClassVariableStart
1554 ($$,NULL,$1,NULL, true);}
1555 | class_type_constant_declaration ';' { $$ = $1; }
1556 | method_modifiers function_loc
1557 is_reference hh_name_with_typevar '('
1558 { _p->onNewLabelScope(true);
1559 _p->onMethodStart($4, $1);
1560 _p->pushLabelInfo();}
1561 method_parameter_list ')'
1562 hh_opt_return_type
1563 method_body
1564 { _p->onMethod($$,$1,$9,$3,$4,$7,$10,nullptr);
1565 _p->popLabelInfo();
1566 _p->popTypeScope();
1567 _p->onCompleteLabelScope(true);}
1568 | non_empty_user_attributes
1569 method_modifiers function_loc
1570 is_reference
1571 hh_name_no_semireserved_with_typevar '('
1572 { _p->onNewLabelScope(true);
1573 _p->onMethodStart($5, $2);
1574 _p->pushLabelInfo();}
1575 method_parameter_list ')'
1576 hh_opt_return_type
1577 method_body
1578 { _p->onMethod($$,$2,$10,$4,$5,$8,$11,&$1);
1579 _p->popLabelInfo();
1580 _p->popTypeScope();
1581 _p->onCompleteLabelScope(true);}
1582 | T_XHP_ATTRIBUTE
1583 xhp_attribute_stmt ';' { _p->xhpSetAttributes($2);}
1584 | T_XHP_CATEGORY
1585 xhp_category_stmt ';' { xhp_category_stmt(_p,$$,$2);}
1586 | T_XHP_CHILDREN
1587 xhp_children_stmt ';' { xhp_children_stmt(_p,$$,$2);}
1588 | T_REQUIRE T_EXTENDS fully_qualified_class_name ';'
1589 { _p->onClassRequire($$, $3, true); }
1590 | T_REQUIRE T_IMPLEMENTS fully_qualified_class_name ';'
1591 { _p->onClassRequire($$, $3, false); }
1592 | T_USE trait_list ';' { Token t; t.reset();
1593 _p->onTraitUse($$,$2,t); }
1594 | T_USE trait_list '{'
1595 trait_rules '}' { _p->onTraitUse($$,$2,$4); }
1597 trait_rules:
1598 trait_rules trait_precedence_rule { _p->onTraitRule($$,$1,$2); }
1599 | trait_rules trait_alias_rule { _p->onTraitRule($$,$1,$2); }
1600 | /* empty */ { $$.reset(); }
1602 trait_precedence_rule:
1603 class_namespace_string_typeargs
1604 T_DOUBLE_COLON
1605 ident_no_semireserved
1606 T_INSTEADOF trait_list ';' { _p->onTraitPrecRule($$,$1,$3,$5);}
1608 trait_alias_rule:
1609 trait_alias_rule_method T_AS
1610 method_modifiers ident_no_semireserved ';'
1611 { _p->onTraitAliasRuleModify($$,$1,$3,
1612 $4);}
1613 | trait_alias_rule_method T_AS
1614 non_empty_member_modifiers ';' { Token t; t.reset();
1615 _p->onTraitAliasRuleModify($$,$1,$3,
1616 t);}
1618 trait_alias_rule_method:
1619 class_namespace_string_typeargs
1620 T_DOUBLE_COLON
1621 ident_no_semireserved { _p->onTraitAliasRuleStart($$,$1,$3);}
1622 | ident_no_semireserved { Token t; t.reset();
1623 _p->onTraitAliasRuleStart($$,t,$1);}
1626 xhp_attribute_stmt:
1627 xhp_attribute_decl { xhp_attribute_list(_p,$$,
1628 _p->xhpGetAttributes(),$1);}
1629 | xhp_attribute_stmt ','
1630 xhp_attribute_decl { xhp_attribute_list(_p,$$, &$1,$3);}
1633 xhp_attribute_decl:
1634 xhp_nullable_attribute_decl_type
1635 xhp_label_ws
1636 xhp_attribute_default
1637 xhp_attribute_is_required { xhp_attribute(_p,$$,$1,$2,$3,$4);
1638 $$ = 1;}
1639 | T_XHP_LABEL { $$ = $1; $$ = 0;}
1642 xhp_nullable_attribute_decl_type:
1643 '?' xhp_attribute_decl_type { $$ = $2;}
1644 | xhp_attribute_decl_type
1647 xhp_attribute_decl_type:
1648 T_ARRAY { $$ = 4;}
1649 | T_ARRAY T_TYPELIST_LT hh_type
1650 T_TYPELIST_GT { $$ = 4;}
1651 | T_ARRAY T_TYPELIST_LT hh_type ','
1652 hh_type T_TYPELIST_GT { $$ = 4;}
1653 | fully_qualified_class_name { /* This case handles all types other
1654 than "array", "var" and "enum".
1655 For now we just use type code 5;
1656 later xhp_attribute() will fix up
1657 the type code as appropriate. */
1658 $$ = 5; $$.setText($1);}
1659 | T_VAR { $$ = 6;}
1660 | T_ENUM '{'
1661 xhp_attribute_enum '}' { $$ = $3; $$ = 7;}
1662 | T_CALLABLE { $$ = 9; }
1665 non_empty_xhp_attribute_enum:
1666 common_scalar { _p->onArrayPair($$, 0,0,$1,0);}
1667 | non_empty_xhp_attribute_enum ','
1668 common_scalar { _p->onArrayPair($$,&$1,0,$3,0);}
1671 xhp_attribute_enum:
1672 non_empty_xhp_attribute_enum
1673 possible_comma { $$ = $1;}
1675 xhp_attribute_default:
1676 '=' static_expr { $$ = $2;}
1677 | { scalar_null(_p, $$);}
1680 xhp_attribute_is_required:
1681 '@' T_XHP_REQUIRED { scalar_num(_p, $$, "1");}
1682 | { scalar_num(_p, $$, "0");}
1685 xhp_category_stmt:
1686 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1687 _p->onArrayPair($$,0,&$1,t,0);}
1688 | xhp_category_stmt ','
1689 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1690 _p->onArrayPair($$,&$1,&$3,t,0);}
1693 xhp_category_decl:
1694 T_XHP_CATEGORY_LABEL { _p->onScalar($$,
1695 T_CONSTANT_ENCAPSED_STRING, $1);}
1698 xhp_children_stmt:
1699 xhp_children_paren_expr { $$ = $1; $$ = 2;}
1700 | ident_no_semireserved { $$ = -1;
1701 if ($1.same("any")) $$ = 1;}
1702 | T_EMPTY { $$ = 0;}
1705 xhp_children_paren_expr:
1706 '(' xhp_children_decl_expr ')' { xhp_children_paren(_p, $$, $2, 0);}
1707 | '(' xhp_children_decl_expr ')' '*' { xhp_children_paren(_p, $$, $2, 1);}
1708 | '(' xhp_children_decl_expr ')' '?' { xhp_children_paren(_p, $$, $2, 2);}
1709 | '(' xhp_children_decl_expr ')' '+' { xhp_children_paren(_p, $$, $2, 3);}
1712 xhp_children_decl_expr:
1713 xhp_children_paren_expr { $$ = $1;}
1714 | xhp_children_decl_tag { xhp_children_decl(_p,$$,$1,0, 0);}
1715 | xhp_children_decl_tag '*' { xhp_children_decl(_p,$$,$1,1, 0);}
1716 | xhp_children_decl_tag '?' { xhp_children_decl(_p,$$,$1,2, 0);}
1717 | xhp_children_decl_tag '+' { xhp_children_decl(_p,$$,$1,3, 0);}
1718 | xhp_children_decl_expr ','
1719 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,4,&$3);}
1720 | xhp_children_decl_expr '|'
1721 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,5,&$3);}
1724 xhp_children_decl_tag:
1725 ident_no_semireserved { $$ = -1;
1726 if ($1.same("any")) $$ = 1; else
1727 if ($1.same("pcdata")) $$ = 2;}
1728 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1; $$ = 3;}
1729 | T_XHP_CATEGORY_LABEL { $1.xhpLabel(0); $$ = $1; $$ = 4;}
1732 function_body:
1733 ';' { $$.reset();}
1734 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1737 method_body:
1738 ';' { $$.reset();}
1739 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1741 variable_modifiers:
1742 non_empty_member_modifiers { $$ = $1;}
1743 | T_VAR { $$.reset();}
1745 method_modifiers:
1746 non_empty_member_modifiers { $$ = $1;}
1747 | { $$.reset();}
1749 non_empty_member_modifiers:
1750 member_modifier { _p->onMemberModifier($$,NULL,$1);}
1751 | non_empty_member_modifiers
1752 member_modifier { _p->onMemberModifier($$,&$1,$2);}
1754 member_modifier:
1755 T_PUBLIC { $$ = T_PUBLIC;}
1756 | T_PROTECTED { $$ = T_PROTECTED;}
1757 | T_PRIVATE { $$ = T_PRIVATE;}
1758 | T_STATIC { $$ = T_STATIC;}
1759 | T_ABSTRACT { $$ = T_ABSTRACT;}
1760 | T_FINAL { $$ = T_FINAL;}
1761 | T_ASYNC { $$ = T_ASYNC;}
1764 parameter_modifiers:
1765 parameter_modifier { $$ = $1;}
1766 | { $$.reset();}
1768 parameter_modifier:
1769 T_PUBLIC { $$ = T_PUBLIC;}
1770 | T_PROTECTED { $$ = T_PROTECTED;}
1771 | T_PRIVATE { $$ = T_PRIVATE;}
1773 class_variable_declaration:
1774 class_variable_declaration ','
1775 T_VARIABLE { _p->onClassVariable($$,&$1,$3,0);}
1776 | class_variable_declaration ','
1777 T_VARIABLE '=' static_expr { _p->onClassVariable($$,&$1,$3,&$5);}
1778 | T_VARIABLE { _p->onClassVariable($$,0,$1,0);}
1779 | T_VARIABLE '=' static_expr { _p->onClassVariable($$,0,$1,&$3);}
1781 class_constant_declaration:
1782 class_constant_declaration ','
1783 hh_constname_with_type '=' static_expr { _p->onClassConstant($$,&$1,$3,$5);}
1784 | T_CONST hh_constname_with_type '='
1785 static_expr { _p->onClassConstant($$,0,$2,$4);}
1787 class_abstract_constant_declaration:
1788 class_abstract_constant_declaration ','
1789 hh_constname_with_type { _p->onClassAbstractConstant($$,&$1,$3);}
1790 | T_ABSTRACT T_CONST hh_constname_with_type
1791 { _p->onClassAbstractConstant($$,NULL,$3);}
1793 class_type_constant_declaration:
1794 T_ABSTRACT class_type_constant
1795 hh_opt_constraint { Token t;
1796 _p->onClassTypeConstant($$, $2, t);
1797 _p->popTypeScope(); }
1798 | class_type_constant
1799 hh_opt_constraint '=' hh_type { _p->onClassTypeConstant($$, $1, $4);
1800 _p->popTypeScope(); }
1801 class_type_constant:
1802 T_CONST T_TYPE
1803 hh_name_no_semireserved_with_typevar { $$ = $3; }
1806 expr_with_parens:
1807 '(' expr_with_parens ')' { $$ = $2;}
1808 | T_NEW class_name_reference
1809 ctor_arguments { _p->onNewObject($$, $2, $3);}
1810 | T_NEW class_expression { $$ = $2;}
1811 | T_CLONE expr { UEXP($$,$2,T_CLONE,1);}
1812 | xhp_tag { $$ = $1;}
1813 | collection_literal { $$ = $1;}
1815 parenthesis_expr:
1816 '(' expr ')' { $$ = $2;}
1819 expr_list:
1820 expr_list ',' expr { _p->onExprListElem($$, &$1, $3);}
1821 | expr { _p->onExprListElem($$, NULL, $1);}
1824 for_expr:
1825 expr_list { $$ = $1;}
1826 | { $$.reset();}
1829 yield_expr:
1830 T_YIELD { _p->onYield($$, NULL);}
1831 | T_YIELD expr { _p->onYield($$, &$2);}
1832 | T_YIELD expr T_DOUBLE_ARROW expr { _p->onYieldPair($$, &$2, &$4);}
1833 | '(' yield_expr ')' { $$ = $2; }
1836 yield_assign_expr:
1837 variable '=' yield_expr { _p->onAssign($$, $1, $3, 0, true);}
1840 yield_list_assign_expr:
1841 T_LIST '(' assignment_list ')'
1842 '=' yield_expr { _p->onListAssignment($$, $3, &$6, true);}
1845 await_expr:
1846 T_AWAIT expr { _p->onAwait($$, $2); }
1849 await_assign_expr:
1850 variable '=' await_expr { _p->onAssign($$, $1, $3, 0, true);}
1853 await_list_assign_expr:
1854 T_LIST '(' assignment_list ')'
1855 '=' await_expr { _p->onListAssignment($$, $3, &$6, true);}
1858 expr:
1859 expr_no_variable { $$ = $1;}
1860 | variable { $$ = $1;}
1861 | expr_with_parens { $$ = $1;}
1862 | lambda_or_closure { $$ = $1;}
1863 | lambda_or_closure_with_parens { $$ = $1;}
1866 expr_no_variable:
1867 T_LIST '(' assignment_list ')'
1868 '=' expr { _p->onListAssignment($$, $3, &$6);}
1869 | variable '=' expr { _p->onAssign($$, $1, $3, 0);}
1870 | variable '=' '&' variable { _p->onAssign($$, $1, $4, 1);}
1871 | variable '=' '&' T_NEW
1872 class_name_reference
1873 ctor_arguments { _p->onAssignNew($$,$1,$5,$6);}
1874 | variable T_PLUS_EQUAL expr { BEXP($$,$1,$3,T_PLUS_EQUAL);}
1875 | variable T_MINUS_EQUAL expr { BEXP($$,$1,$3,T_MINUS_EQUAL);}
1876 | variable T_MUL_EQUAL expr { BEXP($$,$1,$3,T_MUL_EQUAL);}
1877 | variable T_DIV_EQUAL expr { BEXP($$,$1,$3,T_DIV_EQUAL);}
1878 | variable T_CONCAT_EQUAL expr { BEXP($$,$1,$3,T_CONCAT_EQUAL);}
1879 | variable T_MOD_EQUAL expr { BEXP($$,$1,$3,T_MOD_EQUAL);}
1880 | variable T_AND_EQUAL expr { BEXP($$,$1,$3,T_AND_EQUAL);}
1881 | variable T_OR_EQUAL expr { BEXP($$,$1,$3,T_OR_EQUAL);}
1882 | variable T_XOR_EQUAL expr { BEXP($$,$1,$3,T_XOR_EQUAL);}
1883 | variable T_SL_EQUAL expr { BEXP($$,$1,$3,T_SL_EQUAL);}
1884 | variable T_SR_EQUAL expr { BEXP($$,$1,$3,T_SR_EQUAL);}
1885 | variable T_POW_EQUAL expr { BEXP($$,$1,$3,T_POW_EQUAL);}
1886 | variable T_INC { UEXP($$,$1,T_INC,0);}
1887 | T_INC variable { UEXP($$,$2,T_INC,1);}
1888 | variable T_DEC { UEXP($$,$1,T_DEC,0);}
1889 | T_DEC variable { UEXP($$,$2,T_DEC,1);}
1890 | expr T_BOOLEAN_OR expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
1891 | expr T_BOOLEAN_AND expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
1892 | expr T_LOGICAL_OR expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
1893 | expr T_LOGICAL_AND expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
1894 | expr T_LOGICAL_XOR expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
1895 | expr '|' expr { BEXP($$,$1,$3,'|');}
1896 | expr '&' expr { BEXP($$,$1,$3,'&');}
1897 | expr '^' expr { BEXP($$,$1,$3,'^');}
1898 | expr '.' expr { BEXP($$,$1,$3,'.');}
1899 | expr '+' expr { BEXP($$,$1,$3,'+');}
1900 | expr '-' expr { BEXP($$,$1,$3,'-');}
1901 | expr '*' expr { BEXP($$,$1,$3,'*');}
1902 | expr '/' expr { BEXP($$,$1,$3,'/');}
1903 | expr T_POW expr { BEXP($$,$1,$3,T_POW);}
1904 | expr '%' expr { BEXP($$,$1,$3,'%');}
1905 | expr T_SL expr { BEXP($$,$1,$3,T_SL);}
1906 | expr T_SR expr { BEXP($$,$1,$3,T_SR);}
1907 | '+' expr %prec T_INC { UEXP($$,$2,'+',1);}
1908 | '-' expr %prec T_INC { UEXP($$,$2,'-',1);}
1909 | '!' expr { UEXP($$,$2,'!',1);}
1910 | '~' expr { UEXP($$,$2,'~',1);}
1911 | expr T_IS_IDENTICAL expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
1912 | expr T_IS_NOT_IDENTICAL expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
1913 | expr T_IS_EQUAL expr { BEXP($$,$1,$3,T_IS_EQUAL);}
1914 | expr T_IS_NOT_EQUAL expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
1915 | expr '<' expr { BEXP($$,$1,$3,'<');}
1916 | expr T_IS_SMALLER_OR_EQUAL expr { BEXP($$,$1,$3,
1917 T_IS_SMALLER_OR_EQUAL);}
1918 | expr '>' expr { BEXP($$,$1,$3,'>');}
1919 | expr T_IS_GREATER_OR_EQUAL expr { BEXP($$,$1,$3,
1920 T_IS_GREATER_OR_EQUAL);}
1921 | expr T_SPACESHIP expr { BEXP($$,$1,$3,T_SPACESHIP);}
1922 | expr T_INSTANCEOF
1923 class_name_reference { BEXP($$,$1,$3,T_INSTANCEOF);}
1924 | '(' expr_no_variable ')' { $$ = $2;}
1925 | expr '?' expr ':' expr { _p->onQOp($$, $1, &$3, $5);}
1926 | expr '?' ':' expr { _p->onQOp($$, $1, 0, $4);}
1927 | expr T_COALESCE expr { _p->onNullCoalesce($$, $1, $3);}
1928 | internal_functions { $$ = $1;}
1929 | T_INT_CAST expr { UEXP($$,$2,T_INT_CAST,1);}
1930 | T_DOUBLE_CAST expr { UEXP($$,$2,T_DOUBLE_CAST,1);}
1931 | T_STRING_CAST expr { UEXP($$,$2,T_STRING_CAST,1);}
1932 | T_ARRAY_CAST expr { UEXP($$,$2,T_ARRAY_CAST,1);}
1933 | T_OBJECT_CAST expr { UEXP($$,$2,T_OBJECT_CAST,1);}
1934 | T_BOOL_CAST expr { UEXP($$,$2,T_BOOL_CAST,1);}
1935 | T_UNSET_CAST expr { UEXP($$,$2,T_UNSET_CAST,1);}
1936 | T_EXIT exit_expr { UEXP($$,$2,T_EXIT,1);}
1937 | '@' expr { UEXP($$,$2,'@',1);}
1938 | scalar { $$ = $1; }
1939 | array_literal { $$ = $1; }
1940 | shape_literal { $$ = $1; }
1941 | '`' backticks_expr '`' { _p->onEncapsList($$,'`',$2);}
1942 | T_PRINT expr { UEXP($$,$2,T_PRINT,1);}
1943 | dim_expr { $$ = $1;}
1946 lambda_use_vars:
1947 T_USE '('
1948 lexical_var_list
1949 hh_possible_comma
1950 ')' { $$ = $3;}
1951 | { $$.reset();}
1954 closure_expression:
1955 function_loc
1956 is_reference '(' { Token t;
1957 _p->onNewLabelScope(true);
1958 _p->onClosureStart(t);
1959 _p->pushLabelInfo(); }
1960 parameter_list ')'
1961 hh_opt_return_type lambda_use_vars
1962 '{' inner_statement_list '}' { _p->finishStatement($10, $10); $10 = 1;
1963 $$ = _p->onClosure(ClosureType::Long,
1964 nullptr,
1965 $2,$5,$8,$10,$7);
1966 _p->popLabelInfo();
1967 _p->onCompleteLabelScope(true);}
1968 | non_empty_member_modifiers
1969 function_loc
1970 is_reference '(' { Token t;
1971 _p->onNewLabelScope(true);
1972 _p->onClosureStart(t);
1973 _p->pushLabelInfo(); }
1974 parameter_list ')'
1975 hh_opt_return_type lambda_use_vars
1976 '{' inner_statement_list '}' { _p->finishStatement($11, $11); $11 = 1;
1977 $$ = _p->onClosure(ClosureType::Long,
1978 &$1,
1979 $3,$6,$9,$11,$8);
1980 _p->popLabelInfo();
1981 _p->onCompleteLabelScope(true);}
1984 lambda_expression:
1985 T_ASYNC
1986 T_VARIABLE { _p->pushFuncLocation();
1987 Token t;
1988 _p->onNewLabelScope(true);
1989 _p->onClosureStart(t);
1990 _p->pushLabelInfo();
1991 Token u;
1992 _p->onParam($2,NULL,u,$2,0,
1993 NULL,NULL,NULL);}
1994 lambda_body { Token v; Token w; Token x;
1995 $1 = T_ASYNC;
1996 _p->onMemberModifier($1, nullptr, $1);
1997 _p->finishStatement($4, $4); $4 = 1;
1998 $$ = _p->onClosure(ClosureType::Short,
1999 &$1,
2000 v,$2,w,$4,x);
2001 _p->popLabelInfo();
2002 _p->onCompleteLabelScope(true);}
2003 | T_ASYNC
2004 T_LAMBDA_OP { _p->pushFuncLocation();
2005 Token t;
2006 _p->onNewLabelScope(true);
2007 _p->onClosureStart(t);
2008 _p->pushLabelInfo();}
2009 parameter_list
2010 T_LAMBDA_CP
2011 hh_opt_return_type
2012 lambda_body { Token u; Token v;
2013 $1 = T_ASYNC;
2014 _p->onMemberModifier($1, nullptr, $1);
2015 _p->finishStatement($7, $7); $7 = 1;
2016 $$ = _p->onClosure(ClosureType::Short,
2017 &$1,
2018 u,$4,v,$7,$6);
2019 _p->popLabelInfo();
2020 _p->onCompleteLabelScope(true);}
2021 | T_ASYNC
2022 '{' { _p->pushFuncLocation();
2023 Token t;
2024 _p->onNewLabelScope(true);
2025 _p->onClosureStart(t);
2026 _p->pushLabelInfo();}
2027 inner_statement_list
2028 '}' { Token u; Token v; Token w; Token x;
2029 Token y;
2030 $1 = T_ASYNC;
2031 _p->onMemberModifier($1, nullptr, $1);
2032 _p->finishStatement($4, $4); $4 = 1;
2033 $$ = _p->onClosure(ClosureType::Short,
2034 &$1,
2035 u,v,w,$4,x);
2036 _p->popLabelInfo();
2037 _p->onCompleteLabelScope(true);
2038 _p->onCall($$,1,$$,y,NULL);}
2039 | T_VARIABLE { _p->pushFuncLocation();
2040 Token t;
2041 _p->onNewLabelScope(true);
2042 _p->onClosureStart(t);
2043 _p->pushLabelInfo();
2044 Token u;
2045 _p->onParam($1,NULL,u,$1,0,
2046 NULL,NULL,NULL);}
2047 lambda_body { Token v; Token w; Token x;
2048 _p->finishStatement($3, $3); $3 = 1;
2049 $$ = _p->onClosure(ClosureType::Short,
2050 nullptr,
2051 v,$1,w,$3,x);
2052 _p->popLabelInfo();
2053 _p->onCompleteLabelScope(true);}
2054 | T_LAMBDA_OP { _p->pushFuncLocation();
2055 Token t;
2056 _p->onNewLabelScope(true);
2057 _p->onClosureStart(t);
2058 _p->pushLabelInfo();}
2059 parameter_list
2060 T_LAMBDA_CP
2061 hh_opt_return_type
2062 lambda_body { Token u; Token v;
2063 _p->finishStatement($6, $6); $6 = 1;
2064 $$ = _p->onClosure(ClosureType::Short,
2065 nullptr,
2066 u,$3,v,$6,$5);
2067 _p->popLabelInfo();
2068 _p->onCompleteLabelScope(true);}
2071 lambda_body:
2072 T_LAMBDA_ARROW expr { $$ = _p->onExprForLambda($2);}
2073 | T_LAMBDA_ARROW await_expr { $$ = _p->onExprForLambda($2);}
2074 | T_LAMBDA_ARROW
2075 '{' inner_statement_list '}' { $$ = $3; }
2078 shape_keyname:
2079 T_CONSTANT_ENCAPSED_STRING { validate_shape_keyname($1, _p);
2080 _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $1); }
2081 | class_constant { $$ = $1; }
2084 non_empty_shape_pair_list:
2085 non_empty_shape_pair_list ','
2086 shape_keyname
2087 T_DOUBLE_ARROW
2088 expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
2089 | shape_keyname
2090 T_DOUBLE_ARROW
2091 expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2094 non_empty_static_shape_pair_list:
2095 non_empty_static_shape_pair_list ','
2096 shape_keyname
2097 T_DOUBLE_ARROW
2098 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
2099 | shape_keyname
2100 T_DOUBLE_ARROW
2101 static_expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2104 shape_pair_list:
2105 non_empty_shape_pair_list
2106 possible_comma { $$ = $1; }
2107 | { $$.reset(); }
2110 static_shape_pair_list:
2111 non_empty_static_shape_pair_list
2112 possible_comma { $$ = $1; }
2113 | { $$.reset(); }
2116 shape_literal:
2117 T_SHAPE '(' shape_pair_list ')' { _p->onArray($$, $3, T_ARRAY);}
2120 array_literal:
2121 T_ARRAY '(' array_pair_list ')' { _p->onArray($$,$3,T_ARRAY);}
2122 | '[' array_pair_list ']' { _p->onArray($$,$2,T_ARRAY);}
2125 collection_literal:
2126 fully_qualified_class_name
2127 '{' collection_init '}' { Token t;
2128 _p->onName(t,$1,Parser::StringName);
2129 BEXP($$,t,$3,T_COLLECTION);}
2132 static_collection_literal:
2133 fully_qualified_class_name
2134 '{' static_collection_init '}' { Token t;
2135 _p->onName(t,$1,Parser::StringName);
2136 BEXP($$,t,$3,T_COLLECTION);}
2139 dim_expr:
2140 dim_expr
2141 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2142 | dim_expr_base
2143 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2146 dim_expr_base:
2147 array_literal { $$ = $1;}
2148 | class_constant { $$ = $1;}
2149 | lambda_or_closure_with_parens { $$ = $1;}
2150 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2151 T_CONSTANT_ENCAPSED_STRING, $1); }
2152 | '(' expr_no_variable ')' { $$ = $2;}
2155 lexical_var_list:
2156 lexical_var_list ',' T_VARIABLE { _p->onClosureParam($$,&$1,$3,0);}
2157 | lexical_var_list ',' '&'T_VARIABLE { _p->onClosureParam($$,&$1,$4,1);}
2158 | T_VARIABLE { _p->onClosureParam($$, 0,$1,0);}
2159 | '&' T_VARIABLE { _p->onClosureParam($$, 0,$2,1);}
2162 xhp_tag:
2163 T_XHP_TAG_LT
2164 T_XHP_LABEL
2165 xhp_tag_body
2166 T_XHP_TAG_GT { xhp_tag(_p,$$,$2,$3);}
2168 xhp_tag_body:
2169 xhp_attributes '/' { Token t1; _p->onArray(t1,$1);
2170 Token t2; _p->onArray(t2,$2);
2171 Token file; scalar_file(_p, file);
2172 Token line; scalar_line(_p, line);
2173 _p->onCallParam($1,NULL,t1,0,0);
2174 _p->onCallParam($$, &$1,t2,0,0);
2175 _p->onCallParam($1, &$1,file,0,0);
2176 _p->onCallParam($1, &$1,line,0,0);
2177 $$.setText("");}
2178 | xhp_attributes T_XHP_TAG_GT
2179 xhp_children T_XHP_TAG_LT '/'
2180 xhp_opt_end_label { Token file; scalar_file(_p, file);
2181 Token line; scalar_line(_p, line);
2182 _p->onArray($4,$1);
2183 _p->onArray($5,$3);
2184 _p->onCallParam($2,NULL,$4,0,0);
2185 _p->onCallParam($$, &$2,$5,0,0);
2186 _p->onCallParam($2, &$2,file,0,0);
2187 _p->onCallParam($2, &$2,line,0,0);
2188 $$.setText($6.text());}
2190 xhp_opt_end_label:
2191 { $$.reset(); $$.setText("");}
2192 | T_XHP_LABEL { $$.reset(); $$.setText($1);}
2194 xhp_attributes:
2195 xhp_attributes
2196 xhp_attribute_name '='
2197 xhp_attribute_value { _p->onArrayPair($$,&$1,&$2,$4,0);}
2198 | { $$.reset();}
2200 xhp_children:
2201 xhp_children xhp_child { _p->onArrayPair($$,&$1,0,$2,0);}
2202 | { $$.reset();}
2204 xhp_attribute_name:
2205 T_XHP_LABEL { _p->onScalar($$,
2206 T_CONSTANT_ENCAPSED_STRING, $1);}
2208 xhp_attribute_value:
2209 T_XHP_TEXT { $1.xhpDecode();
2210 _p->onScalar($$,
2211 T_CONSTANT_ENCAPSED_STRING, $1);}
2212 | '{' expr '}' { $$ = $2;}
2214 xhp_child:
2215 T_XHP_TEXT { $$.reset();
2216 if ($1.htmlTrim()) {
2217 $1.xhpDecode();
2218 _p->onScalar($$,
2219 T_CONSTANT_ENCAPSED_STRING, $1);
2222 | '{' expr '}' { $$ = $2; }
2223 | xhp_tag { $$ = $1; }
2226 xhp_label_ws:
2227 xhp_bareword { $$ = $1;}
2228 | xhp_label_ws ':'
2229 xhp_bareword { $$ = $1 + ":" + $3;}
2230 | xhp_label_ws '-'
2231 xhp_bareword { $$ = $1 + "-" + $3;}
2233 xhp_bareword:
2234 ident_no_semireserved { $$ = $1;}
2235 | T_EXIT { $$ = $1;}
2236 | T_FUNCTION { $$ = $1;}
2237 | T_CONST { $$ = $1;}
2238 | T_RETURN { $$ = $1;}
2239 | T_YIELD { $$ = $1;}
2240 | T_AWAIT { $$ = $1;}
2241 | T_TRY { $$ = $1;}
2242 | T_CATCH { $$ = $1;}
2243 | T_FINALLY { $$ = $1;}
2244 | T_THROW { $$ = $1;}
2245 | T_IF { $$ = $1;}
2246 | T_ELSEIF { $$ = $1;}
2247 | T_ENDIF { $$ = $1;}
2248 | T_ELSE { $$ = $1;}
2249 | T_WHILE { $$ = $1;}
2250 | T_ENDWHILE { $$ = $1;}
2251 | T_DO { $$ = $1;}
2252 | T_FOR { $$ = $1;}
2253 | T_ENDFOR { $$ = $1;}
2254 | T_FOREACH { $$ = $1;}
2255 | T_ENDFOREACH { $$ = $1;}
2256 | T_DECLARE { $$ = $1;}
2257 | T_ENDDECLARE { $$ = $1;}
2258 | T_INSTANCEOF { $$ = $1;}
2259 | T_AS { $$ = $1;}
2260 | T_SWITCH { $$ = $1;}
2261 | T_ENDSWITCH { $$ = $1;}
2262 | T_CASE { $$ = $1;}
2263 | T_DEFAULT { $$ = $1;}
2264 | T_BREAK { $$ = $1;}
2265 | T_CONTINUE { $$ = $1;}
2266 | T_GOTO { $$ = $1;}
2267 | T_ECHO { $$ = $1;}
2268 | T_PRINT { $$ = $1;}
2269 | T_CLASS { $$ = $1;}
2270 | T_INTERFACE { $$ = $1;}
2271 | T_EXTENDS { $$ = $1;}
2272 | T_IMPLEMENTS { $$ = $1;}
2273 | T_NEW { $$ = $1;}
2274 | T_CLONE { $$ = $1;}
2275 | T_VAR { $$ = $1;}
2276 | T_EVAL { $$ = $1;}
2277 | T_INCLUDE { $$ = $1;}
2278 | T_INCLUDE_ONCE { $$ = $1;}
2279 | T_REQUIRE { $$ = $1;}
2280 | T_REQUIRE_ONCE { $$ = $1;}
2281 | T_NAMESPACE { $$ = $1;}
2282 | T_USE { $$ = $1;}
2283 | T_GLOBAL { $$ = $1;}
2284 | T_ISSET { $$ = $1;}
2285 | T_EMPTY { $$ = $1;}
2286 | T_HALT_COMPILER { $$ = $1;}
2287 | T_STATIC { $$ = $1;}
2288 | T_ABSTRACT { $$ = $1;}
2289 | T_FINAL { $$ = $1;}
2290 | T_PRIVATE { $$ = $1;}
2291 | T_PROTECTED { $$ = $1;}
2292 | T_PUBLIC { $$ = $1;}
2293 | T_ASYNC { $$ = $1;}
2294 | T_UNSET { $$ = $1;}
2295 | T_LIST { $$ = $1;}
2296 | T_ARRAY { $$ = $1;}
2297 | T_LOGICAL_OR { $$ = $1;}
2298 | T_LOGICAL_AND { $$ = $1;}
2299 | T_LOGICAL_XOR { $$ = $1;}
2300 | T_CLASS_C { $$ = $1;}
2301 | T_FUNC_C { $$ = $1;}
2302 | T_METHOD_C { $$ = $1;}
2303 | T_LINE { $$ = $1;}
2304 | T_FILE { $$ = $1;}
2305 | T_DIR { $$ = $1;}
2306 | T_NS_C { $$ = $1;}
2307 | T_COMPILER_HALT_OFFSET { $$ = $1;}
2308 | T_TRAIT { $$ = $1;}
2309 | T_TRAIT_C { $$ = $1;}
2310 | T_INSTEADOF { $$ = $1;}
2311 | T_TYPE { $$ = $1;}
2312 | T_NEWTYPE { $$ = $1;}
2313 | T_SHAPE { $$ = $1;}
2316 simple_function_call:
2317 namespace_string_typeargs '('
2318 function_call_parameter_list ')' { _p->onCall($$,0,$1,$3,NULL);}
2321 fully_qualified_class_name:
2322 class_namespace_string_typeargs { $$ = $1;}
2323 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1;}
2326 static_class_name_base:
2327 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2328 | common_scalar { _p->onName($$,$1,Parser::StringName);}
2329 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2330 | reference_variable { _p->onName($$,$1,
2331 Parser::StaticClassExprName);}
2332 | '(' expr_no_variable ')' { _p->onName($$,$2,
2333 Parser::StaticClassExprName);}
2335 static_class_name_no_calls:
2336 static_class_name_base { $$ = $1; }
2337 | static_class_name_no_calls
2338 T_DOUBLE_COLON
2339 /* !PHP5_ONLY */
2340 variable_no_objects
2341 /* !END */
2342 /* !PHP7_ONLY */
2343 compound_variable
2344 /* !END */
2345 { _p->onStaticMember($$,$1,$3);}
2347 static_class_name:
2348 static_class_name_base { $$ = $1; }
2349 | class_method_call { _p->onName($$,$1,
2350 Parser::StaticClassExprName);}
2351 | static_class_name
2352 T_DOUBLE_COLON
2353 /* !PHP5_ONLY */
2354 variable_no_objects
2355 /* !END */
2356 /* !PHP7_ONLY */
2357 compound_variable
2358 /* !END */
2359 { _p->onStaticMember($$,$1,$3);}
2362 class_name_reference:
2363 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2364 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2365 | variable_no_calls { _p->onName($$,$1,Parser::ExprName);}
2368 exit_expr:
2369 '(' ')' { $$.reset();}
2370 | parenthesis_expr { $$ = $1;}
2371 | { $$.reset();}
2374 backticks_expr:
2375 /* empty */ { $$.reset();}
2376 | T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, NULL, $1, 0);}
2377 | encaps_list { $$ = $1;}
2379 ctor_arguments:
2381 function_call_parameter_list ')' { $$ = $2;}
2382 | { $$.reset();}
2385 common_scalar:
2386 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2387 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2388 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2389 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2390 T_CONSTANT_ENCAPSED_STRING, $1);}
2391 | T_LINE { _p->onScalar($$, T_LINE, $1);}
2392 | T_FILE { _p->onScalar($$, T_FILE, $1);}
2393 | T_DIR { _p->onScalar($$, T_DIR, $1);}
2394 | T_CLASS_C { _p->onScalar($$, T_CLASS_C, $1);}
2395 | T_TRAIT_C { _p->onScalar($$, T_TRAIT_C, $1);}
2396 | T_METHOD_C { _p->onScalar($$, T_METHOD_C, $1);}
2397 | T_FUNC_C { _p->onScalar($$, T_FUNC_C, $1);}
2398 | T_NS_C { _p->onScalar($$, T_NS_C, $1);}
2399 | T_COMPILER_HALT_OFFSET { _p->onScalar($$, T_COMPILER_HALT_OFFSET, $1);}
2400 | T_START_HEREDOC
2401 T_ENCAPSED_AND_WHITESPACE
2402 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2403 | T_START_HEREDOC
2404 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2407 static_expr:
2408 common_scalar { $$ = $1;}
2409 | namespace_string { _p->onConstantValue($$, $1);}
2410 | T_ARRAY '('
2411 static_array_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2412 | '[' static_array_pair_list ']' { _p->onArray($$,$2,T_ARRAY); }
2413 | T_SHAPE '('
2414 static_shape_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2415 | static_class_constant { $$ = $1;}
2416 | static_collection_literal { $$ = $1;}
2417 | '(' static_expr ')' { $$ = $2;}
2418 | static_expr T_BOOLEAN_OR
2419 static_expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
2420 | static_expr T_BOOLEAN_AND
2421 static_expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
2422 | static_expr T_LOGICAL_OR
2423 static_expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
2424 | static_expr T_LOGICAL_AND
2425 static_expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
2426 | static_expr T_LOGICAL_XOR
2427 static_expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
2428 | static_expr '|' static_expr { BEXP($$,$1,$3,'|');}
2429 | static_expr '&' static_expr { BEXP($$,$1,$3,'&');}
2430 | static_expr '^' static_expr { BEXP($$,$1,$3,'^');}
2431 | static_expr '.' static_expr { BEXP($$,$1,$3,'.');}
2432 | static_expr '+' static_expr { BEXP($$,$1,$3,'+');}
2433 | static_expr '-' static_expr { BEXP($$,$1,$3,'-');}
2434 | static_expr '*' static_expr { BEXP($$,$1,$3,'*');}
2435 | static_expr '/' static_expr { BEXP($$,$1,$3,'/');}
2436 | static_expr '%' static_expr { BEXP($$,$1,$3,'%');}
2437 | static_expr T_SL static_expr { BEXP($$,$1,$3,T_SL);}
2438 | static_expr T_SR static_expr { BEXP($$,$1,$3,T_SR);}
2439 | static_expr T_POW static_expr { BEXP($$,$1,$3,T_POW);}
2440 | '!' static_expr { UEXP($$,$2,'!',1);}
2441 | '~' static_expr { UEXP($$,$2,'~',1);}
2442 | '+' static_expr { UEXP($$,$2,'+',1);}
2443 | '-' static_expr { UEXP($$,$2,'-',1);}
2444 | static_expr T_IS_IDENTICAL
2445 static_expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
2446 | static_expr T_IS_NOT_IDENTICAL
2447 static_expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
2448 | static_expr T_IS_EQUAL
2449 static_expr { BEXP($$,$1,$3,T_IS_EQUAL);}
2450 | static_expr T_IS_NOT_EQUAL
2451 static_expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
2452 | static_expr '<' static_expr { BEXP($$,$1,$3,'<');}
2453 | static_expr T_IS_SMALLER_OR_EQUAL
2454 static_expr { BEXP($$,$1,$3,
2455 T_IS_SMALLER_OR_EQUAL);}
2456 | static_expr '>' static_expr { BEXP($$,$1,$3,'>');}
2457 | static_expr
2458 T_IS_GREATER_OR_EQUAL
2459 static_expr { BEXP($$,$1,$3,
2460 T_IS_GREATER_OR_EQUAL);}
2461 | static_expr
2462 T_SPACESHIP
2463 static_expr { BEXP($$,$1,$3,T_SPACESHIP);}
2465 | static_expr '?' static_expr ':'
2466 static_expr { _p->onQOp($$, $1, &$3, $5);}
2467 | static_expr '?' ':' static_expr { _p->onQOp($$, $1, 0, $4);}
2470 static_class_constant:
2471 class_namespace_string_typeargs
2472 T_DOUBLE_COLON
2473 ident_for_class_const { _p->onClassConst($$, $1, $3, 1);}
2474 | T_XHP_LABEL T_DOUBLE_COLON
2475 ident_for_class_const { $1.xhpLabel();
2476 _p->onClassConst($$, $1, $3, 1);}
2477 | class_namespace_string_typeargs
2478 T_DOUBLE_COLON
2479 T_CLASS { _p->onClassClass($$, $1, $3, 1);}
2482 scalar:
2483 namespace_string { _p->onConstantValue($$, $1);}
2484 | T_STRING_VARNAME { _p->onConstantValue($$, $1);}
2485 | class_constant { $$ = $1;}
2486 | common_scalar { $$ = $1;}
2487 | '"' encaps_list '"' { _p->onEncapsList($$,'"',$2);}
2488 | '\'' encaps_list '\'' { _p->onEncapsList($$,'\'',$2);}
2489 | T_START_HEREDOC encaps_list
2490 T_END_HEREDOC { _p->onEncapsList($$,T_START_HEREDOC,
2491 $2);}
2493 static_array_pair_list:
2494 non_empty_static_array_pair_list
2495 possible_comma { $$ = $1;}
2496 | { $$.reset();}
2499 possible_comma:
2500 ',' { $$.reset();}
2501 | { $$.reset();}
2503 hh_possible_comma:
2504 ',' { only_in_hh_syntax(_p); $$.reset();}
2505 | { $$.reset();}
2508 non_empty_static_array_pair_list:
2509 non_empty_static_array_pair_list
2510 ',' static_expr T_DOUBLE_ARROW
2511 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2512 | non_empty_static_array_pair_list
2513 ',' static_expr { _p->onArrayPair($$,&$1, 0,$3,0);}
2514 | static_expr T_DOUBLE_ARROW
2515 static_expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2516 | static_expr { _p->onArrayPair($$, 0, 0,$1,0);}
2519 common_scalar_ae:
2520 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2521 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2522 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2523 | T_START_HEREDOC
2524 T_ENCAPSED_AND_WHITESPACE
2525 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2526 | T_START_HEREDOC
2527 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2529 static_numeric_scalar_ae:
2530 T_LNUMBER { _p->onScalar($$,T_LNUMBER,$1);}
2531 | T_DNUMBER { _p->onScalar($$,T_DNUMBER,$1);}
2532 | T_ONUMBER { _p->onScalar($$,T_ONUMBER,$1);}
2533 | ident_no_semireserved { constant_ae(_p,$$,$1);}
2536 static_string_expr_ae:
2537 T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2538 T_CONSTANT_ENCAPSED_STRING,$1);}
2539 | T_CONSTANT_ENCAPSED_STRING '.' static_string_expr_ae
2540 { _p->onScalar($$,
2541 T_CONSTANT_ENCAPSED_STRING,
2542 $1 + $3);}
2545 static_scalar_ae:
2546 common_scalar_ae
2547 | static_string_expr_ae { $$ = $1;}
2548 | ident_no_semireserved { constant_ae(_p,$$,$1);}
2549 | '+' static_numeric_scalar_ae { UEXP($$,$2,'+',1);}
2550 | '-' static_numeric_scalar_ae { UEXP($$,$2,'-',1);}
2551 | T_ARRAY '('
2552 static_array_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY);}
2553 | '[' static_array_pair_list_ae ']' { _p->onArray($$,$2,T_ARRAY);}
2554 | T_SHAPE '('
2555 static_shape_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY); }
2558 static_array_pair_list_ae:
2559 non_empty_static_array_pair_list_ae
2560 possible_comma { $$ = $1;}
2561 | { $$.reset();}
2563 non_empty_static_array_pair_list_ae:
2564 non_empty_static_array_pair_list_ae
2565 ',' static_scalar_ae T_DOUBLE_ARROW
2566 static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0);}
2567 | non_empty_static_array_pair_list_ae
2568 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2569 | static_scalar_ae T_DOUBLE_ARROW
2570 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0);}
2571 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2573 non_empty_static_scalar_list_ae:
2574 non_empty_static_scalar_list_ae
2575 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2576 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2579 static_shape_pair_list_ae:
2580 non_empty_static_shape_pair_list_ae
2581 possible_comma { $$ = $1; }
2582 | { $$.reset(); }
2584 non_empty_static_shape_pair_list_ae:
2585 non_empty_static_shape_pair_list_ae
2586 ',' shape_keyname
2587 T_DOUBLE_ARROW static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0); }
2588 | shape_keyname
2589 T_DOUBLE_ARROW
2590 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0); }
2593 static_scalar_list_ae:
2594 non_empty_static_scalar_list_ae
2595 possible_comma { $$ = $1;}
2596 | { $$.reset();}
2598 attribute_static_scalar_list:
2599 '(' static_scalar_list_ae ')' { _p->onArray($$,$2,T_ARRAY);}
2600 | { Token t; t.reset();
2601 _p->onArray($$,t,T_ARRAY);}
2604 non_empty_user_attribute_list:
2605 non_empty_user_attribute_list
2606 ',' ident_no_semireserved
2607 attribute_static_scalar_list { _p->onUserAttribute($$,&$1,$3,$4);}
2608 | ident_no_semireserved
2609 attribute_static_scalar_list { _p->onUserAttribute($$, 0,$1,$2);}
2611 user_attribute_list:
2612 { only_in_hh_syntax(_p);}
2613 non_empty_user_attribute_list
2614 possible_comma { $$ = $2;}
2616 non_empty_user_attributes:
2617 T_SL user_attribute_list T_SR { $$ = $2;}
2619 optional_user_attributes:
2620 non_empty_user_attributes { $$ = $1;}
2621 | { $$.reset();}
2624 object_operator:
2625 T_OBJECT_OPERATOR { $$ = $1; $$ = 0;}
2626 | T_NULLSAFE_OBJECT_OPERATOR { $$ = $1; $$ = 1;}
2629 object_property_name_no_variables:
2630 ident_no_semireserved { $$ = $1; $$ = HPHP::ObjPropNormal;}
2631 | T_XHP_LABEL { $$ = $1; $$ = HPHP::ObjPropXhpAttr;}
2632 | '{' expr '}' { $$ = $2; $$ = HPHP::ObjPropNormal;}
2635 object_property_name:
2636 object_property_name_no_variables { $$ = $1;}
2637 /* !PHP5_ONLY */
2638 | variable_no_objects { $$ = $1; $$ = HPHP::ObjPropNormal;}
2639 /* !END */
2640 /* !PHP7_ONLY */
2641 | compound_variable { $$ = $1; $$ = HPHP::ObjPropNormal;}
2642 /* !END */
2645 object_method_name_no_variables:
2646 ident_no_semireserved { $$ = $1;}
2647 | '{' expr '}' { $$ = $2;}
2650 object_method_name:
2651 object_method_name_no_variables { $$ = $1;}
2652 /* !PHP5_ONLY */
2653 | variable_no_objects { $$ = $1;}
2654 /* !END */
2655 /* !PHP7_ONLY */
2656 | compound_variable { $$ = $1;}
2657 /* !END */
2660 array_access:
2661 '[' dim_offset ']' { $$ = $2;}
2662 | '{' expr '}' { $$ = $2;}
2665 dimmable_variable_access:
2666 dimmable_variable array_access { _p->onRefDim($$, $1, $2);}
2667 | '(' expr_with_parens ')'
2668 array_access { _p->onRefDim($$, $2, $4);}
2671 dimmable_variable_no_calls_access:
2672 dimmable_variable_no_calls
2673 array_access { _p->onRefDim($$, $1, $2);}
2674 | '(' expr_with_parens ')'
2675 array_access { _p->onRefDim($$, $2, $4);}
2678 object_property_access_on_expr:
2679 '(' expr_with_parens ')'
2680 object_operator
2681 object_property_name { _p->onObjectProperty(
2684 !$4.num()
2685 ? HPHP::PropAccessType::Normal
2686 : HPHP::PropAccessType::NullSafe,
2690 | '(' expr_no_variable ')'
2691 object_operator
2692 object_property_name { _p->onObjectProperty(
2695 !$4.num()
2696 ? HPHP::PropAccessType::Normal
2697 : HPHP::PropAccessType::NullSafe,
2703 object_property_access_on_expr_no_variables:
2704 '(' expr_with_parens ')'
2705 object_operator
2706 object_property_name_no_variables
2707 { _p->onObjectProperty(
2710 !$4.num()
2711 ? HPHP::PropAccessType::Normal
2712 : HPHP::PropAccessType::NullSafe,
2716 | '(' expr_no_variable ')'
2717 object_operator
2718 object_property_name_no_variables
2719 { _p->onObjectProperty(
2722 !$4.num()
2723 ? HPHP::PropAccessType::Normal
2724 : HPHP::PropAccessType::NullSafe,
2730 variable:
2731 variable_no_objects { $$ = $1;}
2732 | simple_function_call { $$ = $1;}
2733 | object_method_call { $$ = $1;}
2734 | class_method_call { $$ = $1;}
2735 | dimmable_variable_access { $$ = $1;}
2736 | object_property_access_on_expr { $$ = $1;}
2737 | variable object_operator
2738 object_property_name { _p->onObjectProperty(
2741 !$2.num()
2742 ? HPHP::PropAccessType::Normal
2743 : HPHP::PropAccessType::NullSafe,
2747 | static_class_name
2748 T_DOUBLE_COLON
2749 /* !PHP5_ONLY */
2750 variable_no_objects
2751 /* !END */
2752 /* !PHP7_ONLY */
2753 compound_variable
2754 /* !END */
2755 { _p->onStaticMember($$,$1,$3);}
2756 | callable_variable '('
2757 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2758 | lambda_or_closure_with_parens '('
2759 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2760 | '(' variable ')' { $$ = $2;}
2763 dimmable_variable:
2764 simple_function_call { $$ = $1;}
2765 | object_method_call { $$ = $1;}
2766 | class_method_call { $$ = $1;}
2767 | dimmable_variable_access { $$ = $1;}
2768 | variable object_operator
2769 /* !PHP5_ONLY */
2770 object_property_name_no_variables
2771 /* !END */
2772 /* !PHP7_ONLY */
2773 object_property_name
2774 /* !END */
2775 { _p->onObjectProperty(
2778 !$2.num()
2779 ? HPHP::PropAccessType::Normal
2780 : HPHP::PropAccessType::NullSafe,
2784 | object_property_access_on_expr_no_variables { $$ = $1;}
2785 | callable_variable '('
2786 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2787 | '(' variable ')' { $$ = $2;}
2788 /* !PHP7_ONLY */
2789 | static_class_name
2790 T_DOUBLE_COLON
2791 compound_variable { _p->onStaticMember($$,$1,$3);}
2792 /* !END */
2795 callable_variable:
2796 variable_no_objects { $$ = $1;}
2797 | dimmable_variable_access { $$ = $1;}
2798 | simple_function_call { $$ = $1;}
2799 | array_literal { $$ = $1;}
2800 | common_scalar { $$ = $1;}
2801 | '(' variable ')' { $$ = $2;}
2802 | '(' expr_no_variable ')' { $$ = $2;}
2803 | lambda_or_closure_with_parens '('
2804 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2805 | callable_variable '('
2806 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2809 lambda_or_closure_with_parens:
2810 '(' lambda_or_closure ')' { $$ = $2;}
2813 lambda_or_closure:
2814 closure_expression { $$ = $1;}
2815 | lambda_expression { $$ = $1;}
2818 object_method_call:
2819 variable object_operator
2820 object_method_name hh_typeargs_opt '('
2821 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$1,$2.num(),$3,$6);}
2822 | '(' expr_with_parens ')'
2823 object_operator
2824 object_method_name hh_typeargs_opt '('
2825 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$2,$4.num(),$5,$8);}
2828 class_method_call:
2829 static_class_name
2830 T_DOUBLE_COLON
2831 ident hh_typeargs_opt '('
2832 function_call_parameter_list ')' { _p->onCall($$,0,$3,$6,&$1);}
2833 | static_class_name
2834 T_DOUBLE_COLON
2835 /* !PHP5_ONLY */
2836 variable_no_objects '('
2837 /* !END */
2838 /* !PHP7_ONLY */
2839 compound_variable '('
2840 /* !END */
2841 function_call_parameter_list ')' { _p->onCall($$,1,$3,$5,&$1);}
2842 | static_class_name
2843 T_DOUBLE_COLON
2844 '{' expr '}' '('
2845 function_call_parameter_list ')' { _p->onCall($$,1,$4,$7,&$1);}
2848 variable_no_objects:
2849 reference_variable { $$ = $1;}
2850 /* !PHP5_ONLY */
2851 | simple_indirect_reference
2852 reference_variable { _p->onIndirectRef($$,$1,$2);}
2853 /* !END */
2856 reference_variable:
2857 reference_variable
2858 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2859 | reference_variable '{' expr '}' { _p->onRefDim($$, $1, $3);}
2860 | compound_variable { $$ = $1;}
2863 compound_variable:
2864 T_VARIABLE { _p->onSimpleVariable($$, $1);}
2865 | '$' '{' expr '}' { _p->onDynamicVariable($$, $3, 0);}
2866 /* !PHP7_ONLY */
2867 | '$' compound_variable { $1 = 1; _p->onIndirectRef($$, $1, $2);}
2868 /* !END */
2871 dim_offset:
2872 expr { $$ = $1;}
2873 | { $$.reset();}
2876 /* !PHP5_ONLY */
2877 simple_indirect_reference:
2878 '$' { $$ = 1;}
2879 | simple_indirect_reference '$' { $$++;}
2881 /* !END */
2883 variable_no_calls:
2884 variable_no_objects { $$ = $1;}
2885 | dimmable_variable_no_calls_access { $$ = $1;}
2886 | object_property_access_on_expr { $$ = $1;}
2887 | variable_no_calls
2888 object_operator
2889 object_property_name { _p->onObjectProperty(
2892 !$2.num()
2893 ? HPHP::PropAccessType::Normal
2894 : HPHP::PropAccessType::NullSafe,
2898 | static_class_name_no_calls
2899 T_DOUBLE_COLON
2900 variable_no_objects { _p->onStaticMember($$,$1,$3);}
2901 | '(' variable ')' { $$ = $2;}
2904 dimmable_variable_no_calls:
2905 | dimmable_variable_no_calls_access { $$ = $1;}
2906 | object_property_access_on_expr_no_variables { $$ = $1;}
2907 | variable_no_calls object_operator
2908 object_property_name_no_variables
2909 { _p->onObjectProperty(
2912 !$2.num()
2913 ? HPHP::PropAccessType::Normal
2914 : HPHP::PropAccessType::NullSafe,
2918 | '(' variable ')' { $$ = $2;}
2921 assignment_list:
2922 assignment_list ',' { _p->onAListVar($$,&$1,NULL);}
2923 | assignment_list ',' variable { _p->onAListVar($$,&$1,&$3);}
2924 | assignment_list ','
2925 T_LIST '(' assignment_list ')' { _p->onAListSub($$,&$1,$5);}
2926 | { _p->onAListVar($$,NULL,NULL);}
2927 | variable { _p->onAListVar($$,NULL,&$1);}
2928 | T_LIST '(' assignment_list ')' { _p->onAListSub($$,NULL,$3);}
2931 array_pair_list:
2932 non_empty_array_pair_list
2933 possible_comma { $$ = $1;}
2934 | { $$.reset();}
2936 non_empty_array_pair_list:
2937 non_empty_array_pair_list
2938 ',' expr T_DOUBLE_ARROW expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2939 | non_empty_array_pair_list ',' expr { _p->onArrayPair($$,&$1, 0,$3,0);}
2940 | expr T_DOUBLE_ARROW expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2941 | expr { _p->onArrayPair($$, 0, 0,$1,0);}
2942 | non_empty_array_pair_list
2943 ',' expr T_DOUBLE_ARROW
2944 '&' variable { _p->onArrayPair($$,&$1,&$3,$6,1);}
2945 | non_empty_array_pair_list ','
2946 '&' variable { _p->onArrayPair($$,&$1, 0,$4,1);}
2947 | expr T_DOUBLE_ARROW '&' variable { _p->onArrayPair($$, 0,&$1,$4,1);}
2948 | '&' variable { _p->onArrayPair($$, 0, 0,$2,1);}
2951 collection_init:
2952 non_empty_collection_init
2953 possible_comma { $$ = $1;}
2954 | { _p->onEmptyCollection($$);}
2956 non_empty_collection_init:
2957 non_empty_collection_init
2958 ',' expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$,&$1,&$3,$5);}
2959 | non_empty_collection_init ',' expr { _p->onCollectionPair($$,&$1, 0,$3);}
2960 | expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$, 0,&$1,$3);}
2961 | expr { _p->onCollectionPair($$, 0, 0,$1);}
2964 static_collection_init:
2965 non_empty_static_collection_init
2966 possible_comma { $$ = $1;}
2967 | { _p->onEmptyCollection($$);}
2969 non_empty_static_collection_init:
2970 non_empty_static_collection_init
2971 ',' static_expr T_DOUBLE_ARROW
2972 static_expr { _p->onCollectionPair($$,&$1,&$3,$5);}
2973 | non_empty_static_collection_init
2974 ',' static_expr { _p->onCollectionPair($$,&$1, 0,$3);}
2975 | static_expr T_DOUBLE_ARROW
2976 static_expr { _p->onCollectionPair($$, 0,&$1,$3);}
2977 | static_expr { _p->onCollectionPair($$, 0, 0,$1);}
2980 encaps_list:
2981 encaps_list encaps_var { _p->addEncap($$, &$1, $2, -1);}
2982 | encaps_list
2983 T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, &$1, $2, 0);}
2984 | encaps_var { _p->addEncap($$, NULL, $1, -1);}
2985 | T_ENCAPSED_AND_WHITESPACE
2986 encaps_var { _p->addEncap($$, NULL, $1, 0);
2987 _p->addEncap($$, &$$, $2, -1); }
2990 encaps_var:
2991 T_VARIABLE { _p->onSimpleVariable($$, $1);}
2992 | T_VARIABLE '['
2993 encaps_var_offset ']' { _p->encapRefDim($$, $1, $3);}
2994 | T_VARIABLE object_operator
2995 ident_no_semireserved { _p->encapObjProp(
2998 !$2.num()
2999 ? HPHP::PropAccessType::Normal
3000 : HPHP::PropAccessType::NullSafe,
3004 | T_DOLLAR_OPEN_CURLY_BRACES
3005 expr '}' { _p->onDynamicVariable($$, $2, 1);}
3006 | T_DOLLAR_OPEN_CURLY_BRACES
3007 T_STRING_VARNAME '[' expr ']' '}' { _p->encapArray($$, $2, $4);}
3008 | T_CURLY_OPEN variable '}' { $$ = $2;}
3010 encaps_var_offset:
3011 ident_no_semireserved { $$ = $1; $$ = T_STRING;}
3012 | T_NUM_STRING { $$ = $1; $$ = T_NUM_STRING;}
3013 | T_VARIABLE { $$ = $1; $$ = T_VARIABLE;}
3016 internal_functions:
3017 T_ISSET '(' expr_list ')' { UEXP($$,$3,T_ISSET,1);}
3018 | T_EMPTY '(' variable ')' { UEXP($$,$3,T_EMPTY,1);}
3019 | T_EMPTY '(' expr_no_variable ')' { UEXP($$,$3,'!',1);}
3020 | T_EMPTY '(' lambda_or_closure ')' { UEXP($$,$3,'!',1);}
3021 | T_EMPTY '(' lambda_or_closure_with_parens ')' { UEXP($$,$3,'!',1);}
3022 | T_EMPTY '(' expr_with_parens ')' { UEXP($$,$3,'!',1);}
3023 | T_INCLUDE expr { UEXP($$,$2,T_INCLUDE,1);}
3024 | T_INCLUDE_ONCE expr { UEXP($$,$2,T_INCLUDE_ONCE,1);}
3025 | T_EVAL '(' expr ')' { UEXP($$,$3,T_EVAL,1);}
3026 | T_REQUIRE expr { UEXP($$,$2,T_REQUIRE,1);}
3027 | T_REQUIRE_ONCE expr { UEXP($$,$2,T_REQUIRE_ONCE,1);}
3030 variable_list:
3031 variable { _p->onExprListElem($$, NULL, $1);}
3032 | variable_list ',' variable { _p->onExprListElem($$, &$1, $3);}
3035 class_constant:
3036 static_class_name
3037 T_DOUBLE_COLON ident_for_class_const { _p->onClassConst($$, $1, $3, 0);}
3038 | static_class_name
3039 T_DOUBLE_COLON T_CLASS { _p->onClassClass($$, $1, $3, 0);}
3042 /* hack productions -- these allow some extra stuff in hack
3043 * mode, but simplify down to the original thing
3046 hh_opt_constraint:
3047 /* empty */
3048 | T_AS hh_type
3051 hh_type_alias_statement:
3052 T_TYPE hh_name_no_semireserved_with_typevar
3053 '=' hh_type ';' { $2.setText(_p->nsClassDecl($2.text()));
3054 _p->onTypedef($$, $2, $4);
3055 _p->popTypeScope(); }
3056 | non_empty_user_attributes
3057 T_TYPE hh_name_no_semireserved_with_typevar
3058 '=' hh_type ';' { $3.setText(_p->nsClassDecl($3.text()));
3059 _p->onTypedef($$, $3, $5, &$1);
3060 _p->popTypeScope(); }
3061 | T_NEWTYPE hh_name_no_semireserved_with_typevar
3062 hh_opt_constraint '=' hh_type ';' { $2.setText(_p->nsClassDecl($2.text()));
3063 _p->onTypedef($$, $2, $5);
3064 _p->popTypeScope(); }
3065 | non_empty_user_attributes
3066 T_NEWTYPE hh_name_no_semireserved_with_typevar
3067 hh_opt_constraint '=' hh_type ';' { $3.setText(_p->nsClassDecl($3.text()));
3068 _p->onTypedef($$, $3, $6, &$1);
3069 _p->popTypeScope(); }
3072 hh_name_with_type: /* foo -> int foo */
3073 ident { $$ = $1; }
3074 | hh_type ident { only_in_hh_syntax(_p); $$ = $2; }
3077 hh_constname_with_type: /* foo -> int foo, but in class constants */
3078 ident_for_class_const { $$ = $1; }
3079 | hh_type ident_for_class_const { only_in_hh_syntax(_p); $$ = $2; }
3082 hh_name_with_typevar: /* foo -> foo<X,Y>; this adds a typevar
3083 * scope and must be followed by a call to
3084 * popTypeScope() */
3085 ident { _p->pushTypeScope(); $$ = $1; }
3086 | ident
3087 T_TYPELIST_LT
3088 hh_typevar_list
3089 T_TYPELIST_GT { _p->pushTypeScope(); $$ = $1; }
3092 hh_name_no_semireserved_with_typevar: /* foo -> foo<X,Y>; this adds a typevar
3093 * scope and must be followed by a call
3094 * to popTypeScope() */
3095 ident_no_semireserved { _p->pushTypeScope(); $$ = $1; }
3096 | ident_no_semireserved
3097 T_TYPELIST_LT
3098 hh_typevar_list
3099 T_TYPELIST_GT { Token t; _p->setTypeVars(t, $1);
3100 _p->pushTypeScope(); $$ = t; }
3103 hh_typeargs_opt:
3104 T_TYPELIST_LT
3105 hh_type_list
3106 T_TYPELIST_GT { $$ = $2; }
3107 | { $$.reset(); }
3110 hh_non_empty_type_list:
3111 hh_type { Token t; t.reset();
3112 _p->onTypeList($1, t);
3113 $$ = $1; }
3114 | hh_non_empty_type_list ',' hh_type { _p->onTypeList($1, $3);
3115 $$ = $1; }
3118 hh_type_list:
3119 hh_non_empty_type_list
3120 possible_comma { $$ = $1; }
3123 hh_func_type_list:
3124 hh_non_empty_type_list
3125 ',' T_ELLIPSIS { $$ = $1; }
3126 | hh_type_list { $$ = $1; }
3127 | T_ELLIPSIS { $$.reset(); }
3128 | { $$.reset(); }
3131 hh_opt_return_type:
3132 { $$.reset(); }
3133 | ':' hh_type { only_in_hh_syntax(_p); $$ = $2; }
3136 hh_constraint:
3137 T_AS hh_type
3138 | T_SUPER hh_type
3140 hh_typevar_list:
3141 hh_typevar_list ','
3142 hh_typevar_variance
3143 ident_no_semireserved { _p->addTypeVar($4.text()); }
3144 | hh_typevar_variance
3145 ident_no_semireserved { _p->addTypeVar($2.text()); }
3146 | hh_typevar_list ','
3147 hh_typevar_variance
3148 ident_no_semireserved
3149 hh_constraint { _p->addTypeVar($4.text()); }
3150 | hh_typevar_variance
3151 ident_no_semireserved
3152 hh_constraint { _p->addTypeVar($2.text()); }
3155 hh_typevar_variance:
3156 '+' {}
3157 | '-' {}
3158 | /* empty */ {}
3161 hh_shape_member_type:
3162 T_CONSTANT_ENCAPSED_STRING
3163 T_DOUBLE_ARROW
3164 hh_type { validate_shape_keyname($1, _p);
3165 _p->onTypeAnnotation($$, $1, $3); }
3166 | '?'
3167 T_CONSTANT_ENCAPSED_STRING
3168 T_DOUBLE_ARROW
3169 hh_type {
3170 /* should not reach here as
3171 * optional shape fields are not
3172 * supported in strict mode */
3173 validate_shape_keyname($2, _p);
3174 _p->onTypeAnnotation($$, $2, $4);
3176 | class_namespace_string_typeargs
3177 T_DOUBLE_COLON
3178 ident_no_semireserved
3179 T_DOUBLE_ARROW
3180 hh_type { _p->onClsCnsShapeField($$, $1, $3, $5); }
3183 hh_non_empty_shape_member_list:
3184 hh_non_empty_shape_member_list ','
3185 hh_shape_member_type { _p->onTypeList($$, $3); }
3186 | hh_shape_member_type { }
3189 hh_shape_member_list:
3190 hh_non_empty_shape_member_list
3191 possible_comma { _p->onShape($$, $1); }
3192 | /* empty */ { Token t; t.reset();
3193 _p->onShape($$, t); }
3196 hh_shape_type:
3197 T_SHAPE
3198 '(' hh_shape_member_list ')' { $$ = $3;
3199 $$.setText("array"); }
3202 hh_access_type_start:
3203 class_namespace_string_typeargs { $$ = $1; }
3205 hh_access_type:
3206 ident_no_semireserved
3207 T_DOUBLE_COLON
3208 hh_access_type { Token t; t.reset();
3209 _p->onTypeAnnotation($$, $1, t);
3210 _p->onTypeList($$, $3); }
3211 | ident_no_semireserved
3212 hh_typeargs_opt { _p->onTypeAnnotation($$, $1, $2); }
3215 /* extends non_empty_type_decl with some more types */
3216 hh_type:
3217 /* double-optional types will be rejected by the typechecker; we
3218 * already allow plenty of nonsense types anyway */
3219 '?' hh_type { only_in_hh_syntax(_p);
3220 _p->onTypeSpecialization($2, '?');
3221 $$ = $2; }
3222 | '@' hh_type { only_in_hh_syntax(_p);
3223 _p->onTypeSpecialization($2, '@');
3224 $$ = $2; }
3225 | class_namespace_string_typeargs { $$ = $1; }
3226 | T_ARRAY { Token t; t.reset();
3227 $1.setText("array");
3228 _p->onTypeAnnotation($$, $1, t); }
3229 | T_CALLABLE { Token t; t.reset();
3230 $1.setText("callable");
3231 _p->onTypeAnnotation($$, $1, t); }
3232 | hh_shape_type { $$ = $1; }
3233 | hh_access_type_start
3234 T_DOUBLE_COLON
3235 hh_access_type { only_in_hh_syntax(_p);
3236 _p->onTypeAnnotation($$, $1, $3);
3237 _p->onTypeSpecialization($$, 'a'); }
3238 | T_ARRAY T_TYPELIST_LT hh_type
3239 T_TYPELIST_GT { $1.setText("array");
3240 _p->onTypeAnnotation($$, $1, $3); }
3241 | T_ARRAY T_TYPELIST_LT hh_type ','
3242 hh_type T_TYPELIST_GT { _p->onTypeList($3, $5);
3243 $1.setText("array");
3244 _p->onTypeAnnotation($$, $1, $3); }
3245 | T_XHP_LABEL { $1.xhpLabel();
3246 Token t; t.reset();
3247 _p->onTypeAnnotation($$, $1, t);
3248 _p->onTypeSpecialization($$, 'x'); }
3249 | '(' T_FUNCTION
3250 '(' hh_func_type_list ')'
3251 ':' hh_type ')' { only_in_hh_syntax(_p);
3252 _p->onTypeList($7, $4);
3253 _p->onTypeAnnotation($$, $2, $7);
3254 _p->onTypeSpecialization($$, 'f'); }
3255 | '(' hh_type ','
3256 hh_non_empty_type_list
3257 possible_comma ')' { only_in_hh_syntax(_p);
3258 _p->onTypeList($2, $4);
3259 Token t; t.reset(); t.setText("array");
3260 _p->onTypeAnnotation($$, t, $2);
3261 _p->onTypeSpecialization($$, 't'); }
3264 hh_type_opt:
3265 hh_type { $$ = $1; }
3266 | { $$.reset(); }
3270 /* !PHP5_ONLY*/
3271 bool Parser::parseImpl5() {
3272 /* !END */
3273 /* !PHP7_ONLY*/
3274 bool Parser::parseImpl7() {
3275 /* !END */
3276 return yyparse(this) == 0;