Allow non-static expressions in function parameter defaults
[hiphop-php.git] / hphp / parser / hphp.y
blobe8869e7fc5fd4532b599106738097ba52cc7bc29
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 #ifdef yyerror
17 #undef yyerror
18 #endif
19 #define yyerror(loc,p,msg) p->parseFatal(loc,msg)
21 #ifdef YYLLOC_DEFAULT
22 # undef YYLLOC_DEFAULT
23 #endif
24 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
25 #define YYLLOC_DEFAULT(Current, Rhs, N) \
26 do \
27 if (N) { \
28 (Current).first(YYRHSLOC (Rhs, 1)); \
29 (Current).last (YYRHSLOC (Rhs, N)); \
30 } else { \
31 (Current).line0 = (Current).line1 = YYRHSLOC (Rhs, 0).line1; \
32 (Current).char0 = (Current).char1 = YYRHSLOC (Rhs, 0).char1; \
33 } \
34 while (0); \
35 _p->setRuleLocation(&Current);
37 #define YYCOPY(To, From, Count) \
38 do { \
39 YYSIZE_T yyi; \
40 for (yyi = 0; yyi < (Count); yyi++) { \
41 (To)[yyi] = (From)[yyi]; \
42 } \
43 if (From != From ## a) { \
44 YYSTACK_FREE (From); \
45 } \
46 } \
47 while (0)
49 #define YYCOPY_RESET(To, From, Count) \
50 do \
51 { \
52 YYSIZE_T yyi; \
53 for (yyi = 0; yyi < (Count); yyi++) { \
54 (To)[yyi] = (From)[yyi]; \
55 (From)[yyi].reset(); \
56 } \
57 if (From != From ## a) { \
58 YYSTACK_FREE (From); \
59 } \
60 } \
61 while (0)
63 #define YYTOKEN_RESET(From, Count) \
64 do \
65 { \
66 YYSIZE_T yyi; \
67 for (yyi = 0; yyi < (Count); yyi++) { \
68 (From)[yyi].reset(); \
69 } \
70 if (From != From ## a) { \
71 YYSTACK_FREE (From); \
72 } \
73 } \
74 while (0)
76 # define YYSTACK_RELOCATE_RESET(Stack_alloc, Stack) \
77 do \
78 { \
79 YYSIZE_T yynewbytes; \
80 YYCOPY_RESET (&yyptr->Stack_alloc, Stack, yysize); \
81 Stack = &yyptr->Stack_alloc; \
82 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
83 yyptr += yynewbytes / sizeof (*yyptr); \
84 } \
85 while (0)
87 #define YYSTACK_CLEANUP \
88 YYTOKEN_RESET (yyvs, yystacksize); \
89 if (yyvs != yyvsa) { \
90 YYSTACK_FREE (yyvs); \
91 } \
92 if (yyls != yylsa) { \
93 YYSTACK_FREE (yyls); \
94 } \
97 // macros for rules
98 #define BEXP(e...) _p->onBinaryOpExp(e);
99 #define UEXP(e...) _p->onUnaryOpExp(e);
101 using namespace HPHP::HPHP_PARSER_NS;
103 typedef HPHP::ClosureType ClosureType;
105 ///////////////////////////////////////////////////////////////////////////////
106 // helpers
108 static void scalar_num(Parser *_p, Token &out, const char *num) {
109 Token t;
110 t.setText(num);
111 _p->onScalar(out, T_LNUMBER, t);
114 static void scalar_num(Parser *_p, Token &out, int num) {
115 Token t;
116 t.setText(folly::to<std::string>(num));
117 _p->onScalar(out, T_LNUMBER, t);
120 static void scalar_null(Parser *_p, Token &out) {
121 Token tnull; tnull.setText("null");
122 _p->onConstantValue(out, tnull);
125 static void scalar_file(Parser *_p, Token &out) {
126 Token file; file.setText("__FILE__");
127 _p->onScalar(out, T_FILE, file);
130 static void scalar_line(Parser *_p, Token &out) {
131 Token line; line.setText("__LINE__");
132 _p->onScalar(out, T_LINE, line);
135 ///////////////////////////////////////////////////////////////////////////////
137 static void constant_ae(Parser *_p, Token &out, Token &value) {
138 const std::string& valueStr = value.text();
139 if (valueStr.size() < 3 || valueStr.size() > 5 ||
140 (strcasecmp("true", valueStr.c_str()) != 0 &&
141 strcasecmp("false", valueStr.c_str()) != 0 &&
142 strcasecmp("null", valueStr.c_str()) != 0 &&
143 strcasecmp("inf", valueStr.c_str()) != 0 &&
144 strcasecmp("nan", valueStr.c_str()) != 0)) {
145 HPHP_PARSER_ERROR("User-defined constants are not allowed in user "
146 "attribute expressions", _p);
148 _p->onConstantValue(out, value);
151 ///////////////////////////////////////////////////////////////////////////////
154 * XHP functions: They are defined here, so different parsers don't have to
155 * handle XHP rules at all.
158 static void xhp_tag(Parser *_p, Token &out, Token &label, Token &body) {
159 if (!body.text().empty() && body.text() != label.text()) {
160 HPHP_PARSER_ERROR("XHP: mismatched tag: '%s' not the same as '%s'",
161 _p, body.text().c_str(), label.text().c_str());
164 label.xhpLabel();
165 Token name; _p->onName(name, label, Parser::StringName);
166 _p->onNewObject(out, name, body);
169 static void xhp_attribute(Parser *_p, Token &out, Token &type, Token &label,
170 Token &def, Token &req) {
172 * The bool, int, float, and string typenames are not given any special
173 * treatment by the parser and are treated the same as regular class names
174 * (which initially gets marked as type code 5). However, XHP wants to use
175 * different type codes for bool, int, float, and string, so we need to fix
176 * up the type code here to make XHP happy.
178 if (type.num() == 5) {
179 auto* str = type.text().c_str();
180 if (_p->scanner().isHHSyntaxEnabled()) {
181 switch (type.text().size()) {
182 case 6:
183 if (!strcasecmp(str, "HH\\int")) {
184 type.reset(); type.setNum(3);
186 break;
187 case 7:
188 if (!strcasecmp(str, "HH\\bool")) {
189 type.reset(); type.setNum(2);
191 break;
192 case 8:
193 if (!strcasecmp(str, "HH\\float")) {
194 type.reset(); type.setNum(8);
195 } else if (!strcasecmp(str, "HH\\mixed")) {
196 type.reset(); type.setNum(6);
198 break;
199 case 9:
200 if (!strcasecmp(str, "HH\\string")) {
201 type.reset(); type.setNum(1);
203 break;
204 default:
205 break;
207 } else {
208 switch (type.text().size()) {
209 case 3:
210 if (!strcasecmp(str, "int")) {
211 type.reset(); type.setNum(3);
213 break;
214 case 4:
215 if (!strcasecmp(str, "bool")) {
216 type.reset(); type.setNum(2);
217 } else if (!strcasecmp(str, "real")) {
218 type.reset(); type.setNum(8);
220 break;
221 case 5:
222 if (!strcasecmp(str, "float")) {
223 type.reset(); type.setNum(8);
224 } else if (!strcasecmp(str, "mixed")) {
225 type.reset(); type.setNum(6);
227 break;
228 case 6:
229 if (!strcasecmp(str, "string")) {
230 type.reset(); type.setNum(1);
231 } else if (!strcasecmp(str, "double")) {
232 type.reset(); type.setNum(8);
234 break;
235 case 7:
236 if (!strcasecmp(str, "integer")) {
237 type.reset(); type.setNum(3);
238 } else if (!strcasecmp(str, "boolean")) {
239 type.reset(); type.setNum(2);
241 break;
242 default:
243 break;
248 Token num; scalar_num(_p, num, type.num());
249 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
251 Token arr2;
252 switch (type.num()) {
253 case 5: /* class */ {
254 Token cls; _p->onScalar(cls, T_CONSTANT_ENCAPSED_STRING, type);
255 _p->onArrayPair(arr2, &arr1, 0, cls, 0);
256 break;
258 case 7: /* enum */ {
259 Token arr; _p->onArray(arr, type);
260 _p->onArrayPair(arr2, &arr1, 0, arr, 0);
261 break;
263 default: {
264 Token tnull; scalar_null(_p, tnull);
265 _p->onArrayPair(arr2, &arr1, 0, tnull, 0);
266 break;
270 Token arr3; _p->onArrayPair(arr3, &arr2, 0, def, 0);
271 Token arr4; _p->onArrayPair(arr4, &arr3, 0, req, 0);
272 _p->onArray(out, arr4);
273 out.setText(label);
276 static void xhp_attribute_list(Parser *_p, Token &out, Token *list,
277 Token &decl) {
278 if (decl.num() == 0) {
279 decl.xhpLabel();
280 if (list) {
281 out = *list;
282 out.setText(list->text() + ":" + decl.text()); // avoiding vector<string>
283 } else {
284 out.setText(decl);
286 } else {
287 Token name; _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, decl);
288 _p->onArrayPair(out, list, &name, decl, 0);
289 if (list) {
290 out.setText(list->text());
291 } else {
292 out.setText("");
297 static void xhp_attribute_stmt(Parser *_p, Token &out, Token &attributes) {
298 Token modifiers;
299 Token fname; fname.setText("__xhpAttributeDeclaration");
301 Token m;
302 Token m1; m1.setNum(T_PROTECTED); _p->onMemberModifier(m, NULL, m1);
303 Token m2; m2.setNum(T_STATIC); _p->onMemberModifier(modifiers, &m, m2);
305 _p->pushFuncLocation();
306 _p->onMethodStart(fname, modifiers);
308 std::vector<std::string> classes;
309 HPHP::split(':', attributes.text().c_str(), classes, true);
310 Token arrAttributes; _p->onArray(arrAttributes, attributes);
312 Token dummy;
314 Token stmts0;
316 _p->onStatementListStart(stmts0);
318 Token stmts1;
320 // static $_ = -1;
321 Token one; scalar_num(_p, one, "1");
322 Token mone; UEXP(mone, one, '-', 1);
323 Token var; var.set(T_VARIABLE, "_");
324 Token decl; _p->onStaticVariable(decl, 0, var, &mone);
325 Token sdecl; _p->onStatic(sdecl, decl);
326 _p->addStatement(stmts1, stmts0, sdecl);
328 Token stmts2;
330 // if ($_ === -1) {
331 // $_ = array_merge(parent::__xhpAttributeDeclaration(),
332 // attributes);
333 // }
334 Token parent; parent.set(T_STRING, "parent");
335 Token cls; _p->onName(cls, parent, Parser::StringName);
336 Token fname; fname.setText("__xhpAttributeDeclaration");
337 Token param1; _p->onCall(param1, 0, fname, dummy, &cls);
338 Token params1; _p->onCallParam(params1, NULL, param1, false, false);
340 for (unsigned int i = 0; i < classes.size(); i++) {
341 Token parent; parent.set(T_STRING, classes[i]);
342 Token cls; _p->onName(cls, parent, Parser::StringName);
343 Token fname; fname.setText("__xhpAttributeDeclaration");
344 Token param; _p->onCall(param, 0, fname, dummy, &cls);
346 Token params; _p->onCallParam(params, &params1, param, false, false);
347 params1 = params;
350 Token params2; _p->onCallParam(params2, &params1, arrAttributes,
351 false, false);
353 Token name; name.set(T_STRING, "array_merge");
354 Token call; _p->onCall(call, 0, name, params2, NULL);
355 Token tvar; tvar.set(T_VARIABLE, "_");
356 Token var; _p->onSimpleVariable(var, tvar);
357 Token assign; _p->onAssign(assign, var, call, 0);
358 Token exp; _p->onExpStatement(exp, assign);
359 Token block; _p->onBlock(block, exp);
361 Token tvar2; tvar2.set(T_VARIABLE, "_");
362 Token var2; _p->onSimpleVariable(var2, tvar2);
363 Token one; scalar_num(_p, one, "1");
364 Token mone; UEXP(mone, one, '-', 1);
365 Token cond; BEXP(cond, var2, mone, T_IS_IDENTICAL);
366 Token dummy1, dummy2;
367 Token sif; _p->onIf(sif, cond, block, dummy1, dummy2);
368 _p->addStatement(stmts2, stmts1, sif);
370 Token stmts3;
372 // return $_;
373 Token tvar; tvar.set(T_VARIABLE, "_");
374 Token var; _p->onSimpleVariable(var, tvar);
375 Token ret; _p->onReturn(ret, &var);
376 _p->addStatement(stmts3, stmts2, ret);
378 Token stmt;
380 _p->finishStatement(stmt, stmts3);
381 stmt = 1;
384 Token params, ret, ref; ref = 1;
385 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
389 static void xhp_collect_attributes(Parser *_p, Token &out, Token &stmts) {
390 Token *attr = _p->xhpGetAttributes();
391 if (attr) {
392 Token stmt;
393 xhp_attribute_stmt(_p, stmt, *attr);
394 _p->onClassStatement(out, stmts, stmt);
395 } else {
396 out = stmts;
400 static void xhp_category_stmt(Parser *_p, Token &out, Token &categories) {
401 Token fname; fname.setText("__xhpCategoryDeclaration");
402 Token m1; m1.setNum(T_PROTECTED);
403 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
404 _p->pushFuncLocation();
405 _p->onMethodStart(fname, modifiers);
407 Token stmts0;
409 _p->onStatementListStart(stmts0);
411 Token stmts1;
413 // static $_ = categories;
414 Token arr; _p->onArray(arr, categories);
415 Token var; var.set(T_VARIABLE, "_");
416 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
417 Token sdecl; _p->onStatic(sdecl, decl);
418 _p->addStatement(stmts1, stmts0, sdecl);
420 Token stmts2;
422 // return $_;
423 Token tvar; tvar.set(T_VARIABLE, "_");
424 Token var; _p->onSimpleVariable(var, tvar);
425 Token ret; _p->onReturn(ret, &var);
426 _p->addStatement(stmts2, stmts1, ret);
428 Token stmt;
430 _p->finishStatement(stmt, stmts2);
431 stmt = 1;
434 Token params, ret, ref; ref = 1;
435 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
439 static void xhp_children_decl_tag(Parser *_p, Token &arr, Token &tag) {
440 Token num; scalar_num(_p, num, tag.num());
441 Token arr1; _p->onArrayPair(arr1, &arr, 0, num, 0);
443 Token name;
444 if (tag.num() == 3 || tag.num() == 4) {
445 _p->onScalar(name, T_CONSTANT_ENCAPSED_STRING, tag);
446 } else if (tag.num() >= 0) {
447 scalar_null(_p, name);
448 } else {
449 HPHP_PARSER_ERROR("XHP: unknown children declaration", _p);
451 Token arr2; _p->onArrayPair(arr2, &arr1, 0, name, 0);
452 arr = arr2;
455 static void xhp_children_decl(Parser *_p, Token &out, Token &op1, int op,
456 Token *op2) {
457 Token num; scalar_num(_p, num, op);
458 Token arr; _p->onArrayPair(arr, 0, 0, num, 0);
460 if (op2) {
461 Token arr1; _p->onArrayPair(arr1, &arr, 0, op1, 0);
462 Token arr2; _p->onArrayPair(arr2, &arr1, 0, *op2, 0);
463 _p->onArray(out, arr2);
464 } else {
465 xhp_children_decl_tag(_p, arr, op1);
466 _p->onArray(out, arr);
470 static void xhp_children_paren(Parser *_p, Token &out, Token exp, int op) {
471 Token num; scalar_num(_p, num, op);
472 Token arr1; _p->onArrayPair(arr1, 0, 0, num, 0);
474 Token num5; scalar_num(_p, num5, 5);
475 Token arr2; _p->onArrayPair(arr2, &arr1, 0, num5, 0);
477 Token arr3; _p->onArrayPair(arr3, &arr2, 0, exp, 0);
478 _p->onArray(out, arr3);
481 static void xhp_children_stmt(Parser *_p, Token &out, Token &children) {
482 Token fname; fname.setText("__xhpChildrenDeclaration");
483 Token m1; m1.setNum(T_PROTECTED);
484 Token modifiers; _p->onMemberModifier(modifiers, 0, m1);
485 _p->pushFuncLocation();
486 _p->onMethodStart(fname, modifiers);
488 Token stmts0;
490 _p->onStatementListStart(stmts0);
492 Token stmts1;
494 // static $_ = children;
495 Token arr;
496 if (children.num() == 2) {
497 arr = children;
498 } else if (children.num() >= 0) {
499 scalar_num(_p, arr, children.num());
500 } else {
501 HPHP_PARSER_ERROR("XHP: XHP unknown children declaration", _p);
503 Token var; var.set(T_VARIABLE, "_");
504 Token decl; _p->onStaticVariable(decl, 0, var, &arr);
505 Token sdecl; _p->onStatic(sdecl, decl);
506 _p->addStatement(stmts1, stmts0, sdecl);
508 Token stmts2;
510 // return $_;
511 Token tvar; tvar.set(T_VARIABLE, "_");
512 Token var; _p->onSimpleVariable(var, tvar);
513 Token ret; _p->onReturn(ret, &var);
514 _p->addStatement(stmts2, stmts1, ret);
516 Token stmt;
518 _p->finishStatement(stmt, stmts2);
519 stmt = 1;
522 Token params, ret, ref; ref = 1;
523 _p->onMethod(out, modifiers, ret, ref, fname, params, stmt, nullptr, false);
527 static void only_in_hh_syntax(Parser *_p) {
528 if (!_p->scanner().isHHSyntaxEnabled()) {
529 HPHP_PARSER_ERROR(
530 "Syntax only allowed in Hack files (<?hh) or with -v "
531 "Eval.EnableHipHopSyntax=true",
532 _p);
536 static void validate_hh_variadic_variant(Parser* _p,
537 Token& userAttrs, Token& typehint,
538 Token* mod) {
539 if (!userAttrs.text().empty() || !typehint.text().empty() ||
540 (mod && !mod->text().empty())) {
541 HPHP_PARSER_ERROR("Variadic '...' should be followed by a '$variable'", _p);
543 only_in_hh_syntax(_p);
546 // Shapes may not have leading integers in key names, considered as a
547 // parse time error. This is because at runtime they are currently
548 // hphp arrays, which will treat leading integer keys as numbers.
549 static void validate_shape_keyname(Token& tok, Parser* _p) {
550 if (tok.text().empty()) {
551 HPHP_PARSER_ERROR("Shape key names may not be empty", _p);
553 if (isdigit(tok.text()[0])) {
554 HPHP_PARSER_ERROR("Shape key names may not start with integers", _p);
558 ///////////////////////////////////////////////////////////////////////////////
560 static int yylex(YYSTYPE *token, HPHP::Location *loc, Parser *_p) {
561 return _p->scan(token, loc);
565 %expect 2
566 %define api.pure
567 %lex-param {HPHP::HPHP_PARSER_NS::Parser *_p}
568 %parse-param {HPHP::HPHP_PARSER_NS::Parser *_p}
570 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
571 %right T_LAMBDA_ARROW
572 %left ','
573 %nonassoc "..."
574 %left T_LOGICAL_OR
575 %left T_LOGICAL_XOR
576 %left T_LOGICAL_AND
577 %right T_PRINT
578 %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
579 %right T_AWAIT T_YIELD
580 %left '?' ':'
581 %left T_BOOLEAN_OR
582 %left T_BOOLEAN_AND
583 %left '|'
584 %left '^'
585 %left '&'
586 %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
587 %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
588 %left T_SL T_SR
589 %left '+' '-' '.'
590 %left '*' '/' '%'
591 %right '!'
592 %nonassoc T_INSTANCEOF
593 %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 '@'
594 %right T_POW
595 %right '['
597 %nonassoc T_NEW T_CLONE
598 %token T_EXIT
599 %token T_IF
600 %left T_ELSEIF
601 %left T_ELSE
602 %left T_ENDIF
603 %token T_LNUMBER /* long */
604 %token T_DNUMBER /* double */
605 %token T_ONUMBER /* overflowed decimal, might get parsed as long or double */
606 %token T_STRING
607 %token T_STRING_VARNAME
608 %token T_VARIABLE
609 %token T_NUM_STRING
610 %token T_INLINE_HTML
611 %token T_HASHBANG
612 %token T_CHARACTER
613 %token T_BAD_CHARACTER
614 %token T_ENCAPSED_AND_WHITESPACE
615 %token T_CONSTANT_ENCAPSED_STRING
616 %token T_ECHO
617 %token T_DO
618 %token T_WHILE
619 %token T_ENDWHILE
620 %token T_FOR
621 %token T_ENDFOR
622 %token T_FOREACH
623 %token T_ENDFOREACH
624 %token T_DECLARE
625 %token T_ENDDECLARE
626 %token T_AS
627 %token T_SWITCH
628 %token T_ENDSWITCH
629 %token T_CASE
630 %token T_DEFAULT
631 %token T_BREAK
632 %token T_GOTO
633 %token T_CONTINUE
634 %token T_FUNCTION
635 %token T_CONST
636 %token T_RETURN
637 %token T_TRY
638 %token T_CATCH
639 %token T_THROW
640 %token T_USE
641 %token T_GLOBAL
642 %right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC
643 %token T_VAR
644 %token T_UNSET
645 %token T_ISSET
646 %token T_EMPTY
647 %token T_HALT_COMPILER
648 %token T_CLASS
649 %token T_INTERFACE
650 %token T_EXTENDS
651 %token T_IMPLEMENTS
652 %token T_OBJECT_OPERATOR
653 %token T_NULLSAFE_OBJECT_OPERATOR
654 %token T_DOUBLE_ARROW
655 %token T_LIST
656 %token T_ARRAY
657 %token T_CALLABLE
658 %token T_CLASS_C
659 %token T_METHOD_C
660 %token T_FUNC_C
661 %token T_LINE
662 %token T_FILE
663 %token T_COMMENT
664 %token T_DOC_COMMENT
665 %token T_OPEN_TAG
666 %token T_OPEN_TAG_WITH_ECHO
667 %token T_CLOSE_TAG
668 %token T_WHITESPACE
669 %token T_START_HEREDOC
670 %token T_END_HEREDOC
671 %token T_DOLLAR_OPEN_CURLY_BRACES
672 %token T_CURLY_OPEN
673 %token T_DOUBLE_COLON
674 %token T_NAMESPACE
675 %token T_NS_C
676 %token T_DIR
677 %token T_NS_SEPARATOR
679 %token T_XHP_LABEL
680 %token T_XHP_TEXT
681 %token T_XHP_ATTRIBUTE
682 %token T_XHP_CATEGORY
683 %token T_XHP_CATEGORY_LABEL
684 %token T_XHP_CHILDREN
685 %token T_ENUM
686 %token T_XHP_REQUIRED
688 %token T_TRAIT
689 %token T_ELLIPSIS "..."
690 %token T_INSTEADOF
691 %token T_TRAIT_C
693 %token T_HH_ERROR
694 %token T_FINALLY
696 %token T_XHP_TAG_LT
697 %token T_XHP_TAG_GT
698 %token T_TYPELIST_LT
699 %token T_TYPELIST_GT
700 %token T_UNRESOLVED_LT
702 %token T_COLLECTION
703 %token T_SHAPE
704 %token T_VARRAY
705 %token T_MIARRAY
706 %token T_MSARRAY
707 %token T_TYPE
708 %token T_UNRESOLVED_TYPE
709 %token T_NEWTYPE
710 %token T_UNRESOLVED_NEWTYPE
712 %token T_COMPILER_HALT_OFFSET
713 %token T_ASYNC
715 %right T_FROM
716 %token T_WHERE
717 %token T_JOIN
718 %token T_IN
719 %token T_ON
720 %token T_EQUALS
721 %token T_INTO
722 %token T_LET
723 %token T_ORDERBY
724 %token T_ASCENDING
725 %token T_DESCENDING
726 %token T_SELECT
727 %token T_GROUP
728 %token T_BY
730 %token T_LAMBDA_OP
731 %token T_LAMBDA_CP
732 %token T_UNRESOLVED_OP
736 start:
737 { _p->onNewLabelScope(true);
738 _p->initParseTree();}
739 top_statement_list
740 { _p->popLabelInfo();
741 _p->finiParseTree();
742 _p->onCompleteLabelScope(true);}
745 top_statement_list:
746 top_statement_list
747 top_statement { _p->addTopStatement($2);}
748 | { }
750 top_statement:
751 statement { _p->nns($1.num(), $1.text()); $$ = $1;}
752 | function_declaration_statement { _p->nns(); $$ = $1;}
753 | class_declaration_statement { _p->nns(); $$ = $1;}
754 | enum_declaration_statement { _p->nns(); $$ = $1;}
755 | trait_declaration_statement { _p->nns(); $$ = $1;}
756 | hh_type_alias_statement { $$ = $1; }
757 | T_HALT_COMPILER '(' ')' ';' { _p->onHaltCompiler();
758 _p->finiParseTree();
759 YYACCEPT;}
760 | T_NAMESPACE namespace_name ';' { _p->onNamespaceStart($2.text(), true);
761 $$.reset();}
762 | T_NAMESPACE namespace_name '{' { _p->onNamespaceStart($2.text());}
763 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $5;}
764 | T_NAMESPACE '{' { _p->onNamespaceStart("");}
765 top_statement_list '}' { _p->onNamespaceEnd(); $$ = $4;}
766 | T_USE use_declarations ';' { _p->nns(); $$.reset();}
767 | T_USE T_FUNCTION
768 use_fn_declarations ';' { _p->nns(); $$.reset();}
769 | T_USE T_CONST
770 use_const_declarations ';' { _p->nns(); $$.reset();}
771 | constant_declaration ';' { _p->nns();
772 _p->finishStatement($$, $1); $$ = 1;}
775 ident:
776 T_STRING { $$ = $1;}
777 | T_XHP_ATTRIBUTE { $$ = $1;}
778 | T_XHP_CATEGORY { $$ = $1;}
779 | T_XHP_CHILDREN { $$ = $1;}
780 | T_XHP_REQUIRED { $$ = $1;}
781 | T_ENUM { $$ = $1;}
782 | T_WHERE { $$ = $1;}
783 | T_JOIN { $$ = $1;}
784 | T_ON { $$ = $1;}
785 | T_IN { $$ = $1;}
786 | T_EQUALS { $$ = $1;}
787 | T_INTO { $$ = $1;}
788 | T_LET { $$ = $1;}
789 | T_ORDERBY { $$ = $1;}
790 | T_ASCENDING { $$ = $1;}
791 | T_DESCENDING { $$ = $1;}
792 | T_SELECT { $$ = $1;}
793 | T_GROUP { $$ = $1;}
794 | T_BY { $$ = $1;}
797 use_declarations:
798 use_declarations ','
799 use_declaration { }
800 | use_declaration { }
803 use_fn_declarations:
804 use_fn_declaration ','
805 use_fn_declaration { }
806 | use_fn_declaration { }
809 use_const_declarations:
810 use_const_declaration ','
811 use_const_declaration { }
812 | use_const_declaration { }
815 use_declaration:
816 namespace_name { _p->onUse($1.text(),"");}
817 | T_NS_SEPARATOR namespace_name { _p->onUse($2.text(),"");}
818 | namespace_name T_AS ident { _p->onUse($1.text(),$3.text());}
819 | T_NS_SEPARATOR namespace_name
820 T_AS ident { _p->onUse($2.text(),$4.text());}
823 use_fn_declaration:
824 namespace_name { _p->onUseFunction($1.text(),"");}
825 | T_NS_SEPARATOR namespace_name { _p->onUseFunction($2.text(),"");}
826 | namespace_name T_AS ident { _p->onUseFunction($1.text(),$3.text());}
827 | T_NS_SEPARATOR namespace_name
828 T_AS ident { _p->onUseFunction($2.text(),$4.text());}
831 use_const_declaration:
832 namespace_name { _p->onUseConst($1.text(),"");}
833 | T_NS_SEPARATOR namespace_name { _p->onUseConst($2.text(),"");}
834 | namespace_name T_AS ident { _p->onUseConst($1.text(),$3.text());}
835 | T_NS_SEPARATOR namespace_name
836 T_AS ident { _p->onUseConst($2.text(),$4.text());}
839 namespace_name:
840 ident { $$ = $1;}
841 | namespace_name T_NS_SEPARATOR
842 ident { $$ = $1 + $2 + $3; $$ = $1.num() | 2;}
844 namespace_string_base:
845 namespace_name { $$ = $1; $$ = $$.num() | 1;}
846 | T_NAMESPACE T_NS_SEPARATOR
847 namespace_name { $$.set($3.num() | 2, _p->nsDecl($3.text()));}
848 | T_NS_SEPARATOR namespace_name { $$ = $2; $$ = $$.num() | 2;}
850 namespace_string:
851 namespace_string_base { if ($1.num() & 1) {
852 $1.setText(_p->resolve($1.text(),0));
854 $$ = $1;}
856 namespace_string_typeargs:
857 namespace_string_base
858 hh_typeargs_opt { if ($1.num() & 1) {
859 $1.setText(_p->resolve($1.text(),0));
861 $$ = $1;}
863 class_namespace_string_typeargs:
864 namespace_string_base
865 hh_typeargs_opt { if ($1.num() & 1) {
866 $1.setText(_p->resolve($1.text(),1));
868 _p->onTypeAnnotation($$, $1, $2);}
870 constant_declaration:
871 constant_declaration ','
872 hh_name_with_type
873 '=' static_expr { $3.setText(_p->nsDecl($3.text()));
874 _p->onConst($$,$3,$5);}
875 | T_CONST hh_name_with_type '='
876 static_expr { $2.setText(_p->nsDecl($2.text()));
877 _p->onConst($$,$2,$4);}
880 inner_statement_list:
881 inner_statement_list
882 inner_statement { _p->addStatement($$,$1,$2);}
883 | { _p->onStatementListStart($$);}
885 inner_statement:
886 statement { $$ = $1;}
887 | function_declaration_statement { $$ = $1;}
888 | class_declaration_statement { $$ = $1;}
889 | trait_declaration_statement { $$ = $1;}
891 statement:
892 '{' inner_statement_list '}' { _p->onBlock($$, $2);}
893 | T_IF parenthesis_expr
894 statement
895 elseif_list
896 else_single { _p->onIf($$,$2,$3,$4,$5);}
897 | T_IF parenthesis_expr ':'
898 inner_statement_list
899 new_elseif_list
900 new_else_single
901 T_ENDIF ';' { _p->onIf($$,$2,$4,$5,$6);}
902 | T_WHILE parenthesis_expr { _p->onNewLabelScope(false);
903 _p->pushLabelScope();}
904 while_statement { _p->popLabelScope();
905 _p->onWhile($$,$2,$4);
906 _p->onCompleteLabelScope(false);}
908 | T_DO { _p->onNewLabelScope(false);
909 _p->pushLabelScope();}
910 statement T_WHILE parenthesis_expr
911 ';' { _p->popLabelScope();
912 _p->onDo($$,$3,$5);
913 _p->onCompleteLabelScope(false);}
914 | T_FOR '(' for_expr ';'
915 for_expr ';' for_expr ')' { _p->onNewLabelScope(false);
916 _p->pushLabelScope();}
917 for_statement { _p->popLabelScope();
918 _p->onFor($$,$3,$5,$7,$10);
919 _p->onCompleteLabelScope(false);}
920 | T_SWITCH parenthesis_expr { _p->onNewLabelScope(false);
921 _p->pushLabelScope();}
922 switch_case_list { _p->popLabelScope();
923 _p->onSwitch($$,$2,$4);
924 _p->onCompleteLabelScope(false);}
925 | T_BREAK ';' { _p->onBreakContinue($$, true, NULL);}
926 | T_BREAK expr ';' { _p->onBreakContinue($$, true, &$2);}
927 | T_CONTINUE ';' { _p->onBreakContinue($$, false, NULL);}
928 | T_CONTINUE expr ';' { _p->onBreakContinue($$, false, &$2);}
929 | T_RETURN ';' { _p->onReturn($$, NULL);}
930 | T_RETURN expr ';' { _p->onReturn($$, &$2);}
931 | T_YIELD T_BREAK ';' { _p->onYieldBreak($$);}
932 | T_GLOBAL global_var_list ';' { _p->onGlobal($$, $2);}
933 | T_STATIC static_var_list ';' { _p->onStatic($$, $2);}
934 | T_ECHO expr_list ';' { _p->onEcho($$, $2, 0);}
935 | T_UNSET '(' variable_list ')' ';' { _p->onUnset($$, $3);}
936 | ';' { $$.reset(); $$ = ';';}
937 | T_INLINE_HTML { _p->onEcho($$, $1, 1);}
938 | T_HASHBANG { _p->onHashBang($$, $1);
939 $$ = T_HASHBANG;}
940 | T_FOREACH '(' expr
941 T_AS foreach_variable
942 foreach_optional_arg ')' { _p->onNewLabelScope(false);
943 _p->pushLabelScope();}
944 foreach_statement { _p->popLabelScope();
945 _p->onForEach($$,$3,$5,$6,$9, false);
946 _p->onCompleteLabelScope(false);}
947 | T_FOREACH '(' expr
948 T_AWAIT T_AS foreach_variable
949 foreach_optional_arg ')' { _p->onNewLabelScope(false);
950 _p->pushLabelScope();}
951 foreach_statement { _p->popLabelScope();
952 _p->onForEach($$,$3,$6,$7,$10, true);
953 _p->onCompleteLabelScope(false);}
954 | T_DECLARE '(' declare_list ')'
955 declare_statement { _p->onBlock($$, $5); $$ = T_DECLARE;}
956 | T_TRY
957 try_statement_list
958 T_CATCH '('
959 fully_qualified_class_name
960 T_VARIABLE ')' '{'
961 inner_statement_list '}'
962 additional_catches { _p->onCompleteLabelScope(false);}
963 optional_finally { _p->onTry($$,$2,$5,$6,$9,$11,$13);}
964 | T_TRY
965 try_statement_list
966 T_FINALLY { _p->onCompleteLabelScope(false);}
967 finally_statement_list { _p->onTry($$, $2, $5);}
968 | T_THROW expr ';' { _p->onThrow($$, $2);}
969 | T_GOTO ident ';' { _p->onGoto($$, $2, true);
970 _p->addGoto($2.text(),
971 _p->getLocation(),
972 &$$);}
973 | expr ';' { _p->onExpStatement($$, $1);}
974 | yield_expr ';' { _p->onExpStatement($$, $1);}
975 | yield_assign_expr ';' { _p->onExpStatement($$, $1);}
976 | yield_list_assign_expr ';' { _p->onExpStatement($$, $1);}
977 | await_expr ';' { _p->onExpStatement($$, $1);}
978 | await_assign_expr ';' { _p->onExpStatement($$, $1);}
979 | T_RETURN await_expr ';' { _p->onReturn($$, &$2); }
980 | await_list_assign_expr ';' { _p->onExpStatement($$, $1);}
981 | query_assign_expr ';' { _p->onExpStatement($$, $1);}
982 | T_RETURN query_expr ';' { _p->onReturn($$, &$2); }
983 | ident ':' { _p->onLabel($$, $1);
984 _p->addLabel($1.text(),
985 _p->getLocation(),
986 &$$);
987 _p->onScopeLabel($$, $1);}
990 try_statement_list:
991 '{' { _p->onNewLabelScope(false);}
992 inner_statement_list '}' { $$ = $3;}
995 additional_catches:
996 additional_catches
997 T_CATCH '('
998 fully_qualified_class_name
999 T_VARIABLE ')'
1001 inner_statement_list '}' { _p->onCatch($$, $1, $4, $5, $8);}
1002 | { $$.reset();}
1005 finally_statement_list:
1006 '{' { _p->onNewLabelScope(false);
1007 _p->pushLabelScope();}
1008 inner_statement_list '}' { _p->popLabelScope();
1009 _p->onFinally($$, $3);
1010 _p->onCompleteLabelScope(false);}
1013 optional_finally:
1014 T_FINALLY finally_statement_list { $$ = $2;}
1015 | { $$.reset();}
1018 is_reference:
1019 '&' { $$ = 1;}
1020 | { $$.reset();}
1023 function_loc:
1024 T_FUNCTION { _p->pushFuncLocation(); }
1027 function_declaration_statement:
1028 function_loc
1029 is_reference hh_name_with_typevar { $3.setText(_p->nsDecl($3.text()));
1030 _p->onNewLabelScope(true);
1031 _p->onFunctionStart($3);
1032 _p->pushLabelInfo();}
1033 '(' parameter_list ')'
1034 hh_opt_return_type
1035 function_body { _p->onFunction($$,nullptr,$8,$2,$3,$6,$9,nullptr);
1036 _p->popLabelInfo();
1037 _p->popTypeScope();
1038 _p->onCompleteLabelScope(true);}
1039 | non_empty_member_modifiers
1040 function_loc
1041 is_reference hh_name_with_typevar { $4.setText(_p->nsDecl($4.text()));
1042 _p->onNewLabelScope(true);
1043 _p->onFunctionStart($4);
1044 _p->pushLabelInfo();}
1045 '(' parameter_list ')'
1046 hh_opt_return_type
1047 function_body { _p->onFunction($$,&$1,$9,$3,$4,$7,$10,nullptr);
1048 _p->popLabelInfo();
1049 _p->popTypeScope();
1050 _p->onCompleteLabelScope(true);}
1051 | non_empty_user_attributes
1052 method_modifiers function_loc
1053 is_reference hh_name_with_typevar { $5.setText(_p->nsDecl($5.text()));
1054 _p->onNewLabelScope(true);
1055 _p->onFunctionStart($5);
1056 _p->pushLabelInfo();}
1057 '(' parameter_list ')'
1058 hh_opt_return_type
1059 function_body { _p->onFunction($$,&$2,$10,$4,$5,$8,$11,&$1);
1060 _p->popLabelInfo();
1061 _p->popTypeScope();
1062 _p->onCompleteLabelScope(true);}
1065 enum_declaration_statement:
1066 T_ENUM
1067 ident { $2.setText(_p->nsDecl($2.text()));
1068 _p->onClassStart(T_ENUM,$2);}
1069 ':' hh_type
1070 hh_opt_constraint
1071 '{' enum_statement_list '}' { _p->onEnum($$,$2,$5,$8,0); }
1073 | non_empty_user_attributes
1074 T_ENUM
1075 ident { $3.setText(_p->nsDecl($3.text()));
1076 _p->onClassStart(T_ENUM,$3);}
1077 ':' hh_type
1078 hh_opt_constraint
1079 '{' enum_statement_list '}' { _p->onEnum($$,$3,$6,$9,&$1); }
1083 class_declaration_statement:
1084 class_entry_type
1085 class_decl_name { $2.setText(_p->nsDecl($2.text()));
1086 _p->onClassStart($1.num(),$2);}
1087 extends_from implements_list '{'
1088 class_statement_list '}' { Token stmts;
1089 if (_p->peekClass()) {
1090 xhp_collect_attributes(_p,stmts,$7);
1091 } else {
1092 stmts = $7;
1094 _p->onClass($$,$1.num(),$2,$4,$5,
1095 stmts,0,nullptr);
1096 if (_p->peekClass()) {
1097 _p->xhpResetAttributes();
1099 _p->popClass();
1100 _p->popTypeScope();}
1101 | non_empty_user_attributes
1102 class_entry_type
1103 class_decl_name { $3.setText(_p->nsDecl($3.text()));
1104 _p->onClassStart($2.num(),$3);}
1105 extends_from implements_list '{'
1106 class_statement_list '}' { Token stmts;
1107 if (_p->peekClass()) {
1108 xhp_collect_attributes(_p,stmts,$8);
1109 } else {
1110 stmts = $8;
1112 _p->onClass($$,$2.num(),$3,$5,$6,
1113 stmts,&$1,nullptr);
1114 if (_p->peekClass()) {
1115 _p->xhpResetAttributes();
1117 _p->popClass();
1118 _p->popTypeScope();}
1119 | T_INTERFACE
1120 interface_decl_name { $2.setText(_p->nsDecl($2.text()));
1121 _p->onClassStart(T_INTERFACE,$2);}
1122 interface_extends_list '{'
1123 class_statement_list '}' { _p->onInterface($$,$2,$4,$6,0);
1124 _p->popClass();
1125 _p->popTypeScope();}
1126 | non_empty_user_attributes
1127 T_INTERFACE
1128 interface_decl_name { $3.setText(_p->nsDecl($3.text()));
1129 _p->onClassStart(T_INTERFACE,$3);}
1130 interface_extends_list '{'
1131 class_statement_list '}' { _p->onInterface($$,$3,$5,$7,&$1);
1132 _p->popClass();
1133 _p->popTypeScope();}
1136 trait_declaration_statement:
1137 T_TRAIT
1138 trait_decl_name { $2.setText(_p->nsDecl($2.text()));
1139 _p->onClassStart(T_TRAIT, $2);}
1140 implements_list
1141 '{' class_statement_list '}' { Token t_ext;
1142 t_ext.reset();
1143 _p->onClass($$,T_TRAIT,$2,t_ext,$4,
1144 $6, 0, nullptr);
1145 _p->popClass();
1146 _p->popTypeScope();}
1147 | non_empty_user_attributes
1148 T_TRAIT
1149 trait_decl_name { $3.setText(_p->nsDecl($3.text()));
1150 _p->onClassStart(T_TRAIT, $3);}
1151 implements_list
1152 '{' class_statement_list '}' { Token t_ext;
1153 t_ext.reset();
1154 _p->onClass($$,T_TRAIT,$3,t_ext,$5,
1155 $7, &$1, nullptr);
1156 _p->popClass();
1157 _p->popTypeScope();}
1159 class_decl_name:
1160 hh_name_with_typevar { _p->pushClass(false); $$ = $1;}
1161 | T_XHP_LABEL { $1.xhpLabel(); _p->pushTypeScope();
1162 _p->pushClass(true); $$ = $1;}
1164 interface_decl_name:
1165 hh_name_with_typevar { _p->pushClass(false); $$ = $1;}
1167 trait_decl_name:
1168 hh_name_with_typevar { _p->pushClass(false); $$ = $1;}
1170 class_entry_type:
1171 T_CLASS { $$ = T_CLASS;}
1172 | T_ABSTRACT T_CLASS { $$ = T_ABSTRACT; }
1173 | T_ABSTRACT T_FINAL T_CLASS { only_in_hh_syntax(_p);
1174 /* hacky, but transforming to a single token is quite convenient */
1175 $$ = T_STATIC; }
1176 | T_FINAL T_ABSTRACT T_CLASS { only_in_hh_syntax(_p); $$ = T_STATIC; }
1177 | T_FINAL T_CLASS { $$ = T_FINAL;}
1179 extends_from:
1180 T_EXTENDS
1181 fully_qualified_class_name { $$ = $2;}
1182 | { $$.reset();}
1184 implements_list:
1185 T_IMPLEMENTS interface_list { $$ = $2;}
1186 | { $$.reset();}
1188 interface_extends_list:
1189 T_EXTENDS interface_list { $$ = $2;}
1190 | { $$.reset();}
1192 interface_list:
1193 fully_qualified_class_name { _p->onInterfaceName($$, NULL, $1);}
1194 | interface_list ','
1195 fully_qualified_class_name { _p->onInterfaceName($$, &$1, $3);}
1197 trait_list:
1198 fully_qualified_class_name { _p->onTraitName($$, NULL, $1);}
1199 | trait_list ','
1200 fully_qualified_class_name { _p->onTraitName($$, &$1, $3);}
1203 foreach_optional_arg:
1204 T_DOUBLE_ARROW foreach_variable { $$ = $2;}
1205 | { $$.reset();}
1207 foreach_variable:
1208 variable { $$ = $1; $$ = 0;}
1209 | '&' variable { $$ = $2; $$ = 1;}
1210 | T_LIST '(' assignment_list ')' { _p->onListAssignment($$, $3, NULL);}
1213 for_statement:
1214 statement { $$ = $1;}
1215 | ':' inner_statement_list
1216 T_ENDFOR ';' { $$ = $2;}
1218 foreach_statement:
1219 statement { $$ = $1;}
1220 | ':' inner_statement_list
1221 T_ENDFOREACH ';' { $$ = $2;}
1223 while_statement:
1224 statement { $$ = $1;}
1225 | ':' inner_statement_list
1226 T_ENDWHILE ';' { $$ = $2;}
1228 declare_statement:
1229 statement { $$ = $1;}
1230 | ':' inner_statement_list
1231 T_ENDDECLARE ';' { $$ = $2;}
1234 declare_list:
1235 ident '=' static_expr
1236 | declare_list ','
1237 ident '=' static_expr
1240 switch_case_list:
1241 '{' case_list '}' { $$ = $2;}
1242 | '{' ';' case_list '}' { $$ = $3;}
1243 | ':' case_list T_ENDSWITCH ';' { $$ = $2;}
1244 | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3;}
1246 case_list:
1247 case_list T_CASE expr
1248 case_separator
1249 inner_statement_list { _p->onCase($$,$1,&$3,$5);}
1250 | case_list T_DEFAULT case_separator
1251 inner_statement_list { _p->onCase($$,$1,NULL,$4);}
1252 | { $$.reset();}
1254 case_separator:
1255 ':' { $$.reset();}
1256 | ';' { $$.reset();}
1259 elseif_list:
1260 elseif_list T_ELSEIF parenthesis_expr
1261 statement { _p->onElseIf($$,$1,$3,$4);}
1262 | { $$.reset();}
1264 new_elseif_list:
1265 new_elseif_list T_ELSEIF
1266 parenthesis_expr ':'
1267 inner_statement_list { _p->onElseIf($$,$1,$3,$5);}
1268 | { $$.reset();}
1270 else_single:
1271 T_ELSE statement { $$ = $2;}
1272 | { $$.reset();}
1274 new_else_single:
1275 T_ELSE ':' inner_statement_list { $$ = $3;}
1276 | { $$.reset();}
1279 method_parameter_list:
1280 non_empty_method_parameter_list ','
1281 optional_user_attributes
1282 parameter_modifiers
1283 hh_type_opt "..." T_VARIABLE
1284 { _p->onVariadicParam($$,&$1,$5,$7,false,
1285 &$3,&$4); }
1286 | non_empty_method_parameter_list ','
1287 optional_user_attributes
1288 parameter_modifiers
1289 hh_type_opt '&' "..." T_VARIABLE
1290 { _p->onVariadicParam($$,&$1,$5,$8,true,
1291 &$3,&$4); }
1292 | non_empty_method_parameter_list ','
1293 optional_user_attributes
1294 parameter_modifiers
1295 hh_type_opt "..."
1296 { validate_hh_variadic_variant(
1297 _p, $3, $5, &$4);
1298 $$ = $1; }
1299 | non_empty_method_parameter_list
1300 hh_possible_comma { $$ = $1;}
1301 | optional_user_attributes
1302 parameter_modifiers
1303 hh_type_opt "..." T_VARIABLE
1304 { _p->onVariadicParam($$,NULL,$3,$5,false,
1305 &$1,&$2); }
1306 | optional_user_attributes
1307 parameter_modifiers
1308 hh_type_opt '&' "..." T_VARIABLE
1309 { _p->onVariadicParam($$,NULL,$3,$6,true,
1310 &$1,&$2); }
1311 | optional_user_attributes
1312 parameter_modifiers
1313 hh_type_opt "..."
1314 { validate_hh_variadic_variant(
1315 _p, $1, $3, &$2);
1316 $$.reset(); }
1317 | { $$.reset(); }
1320 non_empty_method_parameter_list:
1321 optional_user_attributes
1322 parameter_modifiers
1323 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$3,$4,0,
1324 NULL,&$1,&$2);}
1325 | optional_user_attributes
1326 parameter_modifiers
1327 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$3,$5,1,
1328 NULL,&$1,&$2);}
1329 | optional_user_attributes
1330 parameter_modifiers
1331 hh_type_opt '&' T_VARIABLE
1332 '=' expr { _p->onParam($$,NULL,$3,$5,1,
1333 &$7,&$1,&$2);}
1334 | optional_user_attributes
1335 parameter_modifiers
1336 hh_type_opt T_VARIABLE
1337 '=' expr { _p->onParam($$,NULL,$3,$4,0,
1338 &$6,&$1,&$2);}
1339 | non_empty_method_parameter_list ','
1340 optional_user_attributes
1341 parameter_modifiers
1342 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$5,$6,0,
1343 NULL,&$3,&$4);}
1344 | non_empty_method_parameter_list ','
1345 optional_user_attributes
1346 parameter_modifiers
1347 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$5,$7,1,
1348 NULL,&$3,&$4);}
1349 | non_empty_method_parameter_list ','
1350 optional_user_attributes
1351 parameter_modifiers
1352 hh_type_opt '&' T_VARIABLE
1353 '=' expr { _p->onParam($$,&$1,$5,$7,1,
1354 &$9,&$3,&$4);}
1355 | non_empty_method_parameter_list ','
1356 optional_user_attributes
1357 parameter_modifiers
1358 hh_type_opt T_VARIABLE
1359 '=' expr { _p->onParam($$,&$1,$5,$6,0,
1360 &$8,&$3,&$4);}
1363 parameter_list:
1364 non_empty_parameter_list ','
1365 optional_user_attributes
1366 hh_type_opt "..." T_VARIABLE
1367 { _p->onVariadicParam($$,&$1,$4,$6,
1368 false,&$3,NULL); }
1369 | non_empty_parameter_list ','
1370 optional_user_attributes
1371 hh_type_opt '&' "..." T_VARIABLE
1372 { _p->onVariadicParam($$,&$1,$4,$7,
1373 true,&$3,NULL); }
1374 | non_empty_parameter_list ','
1375 optional_user_attributes
1376 hh_type_opt "..."
1377 { validate_hh_variadic_variant(
1378 _p, $3, $4, NULL);
1379 $$ = $1; }
1380 | non_empty_parameter_list
1381 hh_possible_comma { $$ = $1;}
1382 | optional_user_attributes
1383 hh_type_opt "..." T_VARIABLE
1384 { _p->onVariadicParam($$,NULL,$2,$4,
1385 false,&$1,NULL); }
1386 | optional_user_attributes
1387 hh_type_opt '&' "..." T_VARIABLE
1388 { _p->onVariadicParam($$,NULL,$2,$5,
1389 true,&$1,NULL); }
1390 | optional_user_attributes
1391 hh_type_opt "..."
1392 { validate_hh_variadic_variant(
1393 _p, $1, $2, NULL);
1394 $$.reset(); }
1395 | { $$.reset();}
1398 non_empty_parameter_list:
1399 optional_user_attributes
1400 hh_type_opt T_VARIABLE { _p->onParam($$,NULL,$2,$3,false,
1401 NULL,&$1,NULL); }
1402 | optional_user_attributes
1403 hh_type_opt '&' T_VARIABLE { _p->onParam($$,NULL,$2,$4,true,
1404 NULL,&$1,NULL); }
1405 | optional_user_attributes
1406 hh_type_opt '&' T_VARIABLE
1407 '=' expr { _p->onParam($$,NULL,$2,$4,true,
1408 &$6,&$1,NULL); }
1409 | optional_user_attributes
1410 hh_type_opt T_VARIABLE
1411 '=' expr { _p->onParam($$,NULL,$2,$3,false,
1412 &$5,&$1,NULL); }
1413 | non_empty_parameter_list ','
1414 optional_user_attributes
1415 hh_type_opt T_VARIABLE { _p->onParam($$,&$1,$4,$5,false,
1416 NULL,&$3,NULL); }
1417 | non_empty_parameter_list ','
1418 optional_user_attributes
1419 hh_type_opt '&' T_VARIABLE { _p->onParam($$,&$1,$4,$6,true,
1420 NULL,&$3,NULL); }
1421 | non_empty_parameter_list ','
1422 optional_user_attributes
1423 hh_type_opt '&' T_VARIABLE
1424 '=' expr { _p->onParam($$,&$1,$4,$6,true,
1425 &$8,&$3,NULL); }
1426 | non_empty_parameter_list ','
1427 optional_user_attributes
1428 hh_type_opt T_VARIABLE
1429 '=' expr { _p->onParam($$,&$1,$4,$5,false,
1430 &$7,&$3,NULL); }
1433 function_call_parameter_list:
1434 non_empty_fcall_parameter_list
1435 hh_possible_comma { $$ = $1;}
1436 | { $$.reset();}
1438 non_empty_fcall_parameter_list:
1439 expr { _p->onCallParam($$,NULL,$1,false,false);}
1440 | '&' variable { _p->onCallParam($$,NULL,$2,true,false);}
1441 | "..." expr { _p->onCallParam($$,NULL,$2,false,true);}
1442 | non_empty_fcall_parameter_list
1443 ',' expr { _p->onCallParam($$,&$1,$3,false, false);}
1444 | non_empty_fcall_parameter_list
1445 ',' "..." expr { _p->onCallParam($$,&$1,$4,false,true);}
1446 | non_empty_fcall_parameter_list
1447 ',' '&' variable { _p->onCallParam($$,&$1,$4,true, false);}
1450 global_var_list:
1451 global_var_list ',' global_var { _p->onGlobalVar($$, &$1, $3);}
1452 | global_var { _p->onGlobalVar($$, NULL, $1);}
1454 global_var:
1455 T_VARIABLE { $$ = $1;}
1456 | '$' variable { $$ = $2; $$ = 1;}
1457 | '$' '{' expr '}' { $$ = $3; $$ = 1;}
1460 static_var_list:
1461 static_var_list ',' T_VARIABLE { _p->onStaticVariable($$,&$1,$3,0);}
1462 | static_var_list ',' T_VARIABLE
1463 '=' static_expr { _p->onStaticVariable($$,&$1,$3,&$5);}
1464 | T_VARIABLE { _p->onStaticVariable($$,0,$1,0);}
1465 | T_VARIABLE '=' static_expr { _p->onStaticVariable($$,0,$1,&$3);}
1468 enum_statement_list:
1469 enum_statement_list
1470 enum_statement { _p->onClassStatement($$, $1, $2);}
1471 | { $$.reset();}
1473 enum_statement:
1474 enum_constant_declaration ';' { _p->onClassVariableStart
1475 ($$,NULL,$1,NULL);}
1477 enum_constant_declaration:
1478 hh_name_with_type '='
1479 static_expr { _p->onClassConstant($$,0,$1,$3);}
1483 class_statement_list:
1484 class_statement_list
1485 class_statement { _p->onClassStatement($$, $1, $2);}
1486 | { $$.reset();}
1488 class_statement:
1489 variable_modifiers { _p->onClassVariableModifer($1);}
1490 class_variable_declaration ';' { _p->onClassVariableStart
1491 ($$,&$1,$3,NULL);}
1492 | non_empty_member_modifiers
1493 hh_type { _p->onClassVariableModifer($1);}
1494 class_variable_declaration ';' { _p->onClassVariableStart
1495 ($$,&$1,$4,&$2);}
1496 | class_constant_declaration ';' { _p->onClassVariableStart
1497 ($$,NULL,$1,NULL);}
1498 | method_modifiers function_loc
1499 is_reference hh_name_with_typevar '('
1500 { _p->onNewLabelScope(true);
1501 _p->onMethodStart($4, $1);
1502 _p->pushLabelInfo();}
1503 method_parameter_list ')'
1504 hh_opt_return_type
1505 method_body
1506 { _p->onMethod($$,$1,$9,$3,$4,$7,$10,nullptr);
1507 _p->popLabelInfo();
1508 _p->popTypeScope();
1509 _p->onCompleteLabelScope(true);}
1510 | non_empty_user_attributes
1511 method_modifiers function_loc
1512 is_reference hh_name_with_typevar '('
1513 { _p->onNewLabelScope(true);
1514 _p->onMethodStart($5, $2);
1515 _p->pushLabelInfo();}
1516 method_parameter_list ')'
1517 hh_opt_return_type
1518 method_body
1519 { _p->onMethod($$,$2,$10,$4,$5,$8,$11,&$1);
1520 _p->popLabelInfo();
1521 _p->popTypeScope();
1522 _p->onCompleteLabelScope(true);}
1523 | T_XHP_ATTRIBUTE
1524 xhp_attribute_stmt ';' { _p->xhpSetAttributes($2);}
1525 | T_XHP_CATEGORY
1526 xhp_category_stmt ';' { xhp_category_stmt(_p,$$,$2);}
1527 | T_XHP_CHILDREN
1528 xhp_children_stmt ';' { xhp_children_stmt(_p,$$,$2);}
1529 | T_REQUIRE T_EXTENDS fully_qualified_class_name ';'
1530 { _p->onClassRequire($$, $3, true); }
1531 | T_REQUIRE T_IMPLEMENTS fully_qualified_class_name ';'
1532 { _p->onClassRequire($$, $3, false); }
1533 | T_USE trait_list ';' { Token t; t.reset();
1534 _p->onTraitUse($$,$2,t); }
1535 | T_USE trait_list '{'
1536 trait_rules '}' { _p->onTraitUse($$,$2,$4); }
1538 trait_rules:
1539 trait_rules trait_precedence_rule { _p->onTraitRule($$,$1,$2); }
1540 | trait_rules trait_alias_rule { _p->onTraitRule($$,$1,$2); }
1541 | /* empty */ { $$.reset(); }
1543 trait_precedence_rule:
1544 class_namespace_string_typeargs
1545 T_DOUBLE_COLON
1546 ident
1547 T_INSTEADOF trait_list ';' { _p->onTraitPrecRule($$,$1,$3,$5);}
1549 trait_alias_rule:
1550 trait_alias_rule_method T_AS
1551 method_modifiers ident ';' { _p->onTraitAliasRuleModify($$,$1,$3,
1552 $4);}
1553 | trait_alias_rule_method T_AS
1554 non_empty_member_modifiers ';' { Token t; t.reset();
1555 _p->onTraitAliasRuleModify($$,$1,$3,
1556 t);}
1558 trait_alias_rule_method:
1559 class_namespace_string_typeargs
1560 T_DOUBLE_COLON
1561 ident { _p->onTraitAliasRuleStart($$,$1,$3);}
1562 | ident { Token t; t.reset();
1563 _p->onTraitAliasRuleStart($$,t,$1);}
1566 xhp_attribute_stmt:
1567 xhp_attribute_decl { xhp_attribute_list(_p,$$,
1568 _p->xhpGetAttributes(),$1);}
1569 | xhp_attribute_stmt ','
1570 xhp_attribute_decl { xhp_attribute_list(_p,$$, &$1,$3);}
1573 xhp_attribute_decl:
1574 xhp_attribute_decl_type
1575 xhp_label_ws
1576 xhp_attribute_default
1577 xhp_attribute_is_required { xhp_attribute(_p,$$,$1,$2,$3,$4);
1578 $$ = 1;}
1579 | T_XHP_LABEL { $$ = $1; $$ = 0;}
1582 xhp_attribute_decl_type:
1583 T_ARRAY { $$ = 4;}
1584 | fully_qualified_class_name { /* This case handles all types other
1585 than "array", "var" and "enum".
1586 For now we just use type code 5;
1587 later xhp_attribute() will fix up
1588 the type code as appropriate. */
1589 $$ = 5; $$.setText($1);}
1590 | T_VAR { $$ = 6;}
1591 | T_ENUM '{'
1592 xhp_attribute_enum '}' { $$ = $3; $$ = 7;}
1593 | T_CALLABLE { $$ = 9; }
1596 xhp_attribute_enum:
1597 common_scalar { _p->onArrayPair($$, 0,0,$1,0);}
1598 | xhp_attribute_enum ','
1599 common_scalar { _p->onArrayPair($$,&$1,0,$3,0);}
1602 xhp_attribute_default:
1603 '=' static_expr { $$ = $2;}
1604 | { scalar_null(_p, $$);}
1607 xhp_attribute_is_required:
1608 '@' T_XHP_REQUIRED { scalar_num(_p, $$, "1");}
1609 | { scalar_num(_p, $$, "0");}
1612 xhp_category_stmt:
1613 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1614 _p->onArrayPair($$,0,&$1,t,0);}
1615 | xhp_category_stmt ','
1616 xhp_category_decl { Token t; scalar_num(_p, t, "1");
1617 _p->onArrayPair($$,&$1,&$3,t,0);}
1620 xhp_category_decl:
1621 T_XHP_CATEGORY_LABEL { _p->onScalar($$,
1622 T_CONSTANT_ENCAPSED_STRING, $1);}
1625 xhp_children_stmt:
1626 xhp_children_paren_expr { $$ = $1; $$ = 2;}
1627 | ident { $$ = -1;
1628 if ($1.same("any")) $$ = 1;}
1629 | T_EMPTY { $$ = 0;}
1632 xhp_children_paren_expr:
1633 '(' xhp_children_decl_expr ')' { xhp_children_paren(_p, $$, $2, 0);}
1634 | '(' xhp_children_decl_expr ')' '*' { xhp_children_paren(_p, $$, $2, 1);}
1635 | '(' xhp_children_decl_expr ')' '?' { xhp_children_paren(_p, $$, $2, 2);}
1636 | '(' xhp_children_decl_expr ')' '+' { xhp_children_paren(_p, $$, $2, 3);}
1639 xhp_children_decl_expr:
1640 xhp_children_paren_expr { $$ = $1;}
1641 | xhp_children_decl_tag { xhp_children_decl(_p,$$,$1,0, 0);}
1642 | xhp_children_decl_tag '*' { xhp_children_decl(_p,$$,$1,1, 0);}
1643 | xhp_children_decl_tag '?' { xhp_children_decl(_p,$$,$1,2, 0);}
1644 | xhp_children_decl_tag '+' { xhp_children_decl(_p,$$,$1,3, 0);}
1645 | xhp_children_decl_expr ','
1646 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,4,&$3);}
1647 | xhp_children_decl_expr '|'
1648 xhp_children_decl_expr { xhp_children_decl(_p,$$,$1,5,&$3);}
1651 xhp_children_decl_tag:
1652 ident { $$ = -1;
1653 if ($1.same("any")) $$ = 1; else
1654 if ($1.same("pcdata")) $$ = 2;}
1655 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1; $$ = 3;}
1656 | T_XHP_CATEGORY_LABEL { $1.xhpLabel(0); $$ = $1; $$ = 4;}
1659 function_body:
1660 ';' { $$.reset();}
1661 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1664 method_body:
1665 ';' { $$.reset();}
1666 | '{' inner_statement_list '}' { _p->finishStatement($$, $2); $$ = 1;}
1668 variable_modifiers:
1669 non_empty_member_modifiers { $$ = $1;}
1670 | T_VAR { $$.reset();}
1672 method_modifiers:
1673 non_empty_member_modifiers { $$ = $1;}
1674 | { $$.reset();}
1676 non_empty_member_modifiers:
1677 member_modifier { _p->onMemberModifier($$,NULL,$1);}
1678 | non_empty_member_modifiers
1679 member_modifier { _p->onMemberModifier($$,&$1,$2);}
1681 member_modifier:
1682 T_PUBLIC { $$ = T_PUBLIC;}
1683 | T_PROTECTED { $$ = T_PROTECTED;}
1684 | T_PRIVATE { $$ = T_PRIVATE;}
1685 | T_STATIC { $$ = T_STATIC;}
1686 | T_ABSTRACT { $$ = T_ABSTRACT;}
1687 | T_FINAL { $$ = T_FINAL;}
1688 | T_ASYNC { $$ = T_ASYNC;}
1691 parameter_modifiers:
1692 parameter_modifier { $$ = $1;}
1693 | { $$.reset();}
1695 parameter_modifier:
1696 T_PUBLIC { $$ = T_PUBLIC;}
1697 | T_PROTECTED { $$ = T_PROTECTED;}
1698 | T_PRIVATE { $$ = T_PRIVATE;}
1700 class_variable_declaration:
1701 class_variable_declaration ','
1702 T_VARIABLE { _p->onClassVariable($$,&$1,$3,0);}
1703 | class_variable_declaration ','
1704 T_VARIABLE '=' static_expr { _p->onClassVariable($$,&$1,$3,&$5);}
1705 | T_VARIABLE { _p->onClassVariable($$,0,$1,0);}
1706 | T_VARIABLE '=' static_expr { _p->onClassVariable($$,0,$1,&$3);}
1708 class_constant_declaration:
1709 class_constant_declaration ','
1710 hh_name_with_type '=' static_expr { _p->onClassConstant($$,&$1,$3,$5);}
1711 | T_CONST hh_name_with_type '='
1712 static_expr { _p->onClassConstant($$,0,$2,$4);}
1715 expr_with_parens:
1716 '(' expr_with_parens ')' { $$ = $2;}
1717 | T_NEW class_name_reference
1718 ctor_arguments { _p->onNewObject($$, $2, $3);}
1719 | T_CLONE expr { UEXP($$,$2,T_CLONE,1);}
1720 | xhp_tag { $$ = $1;}
1721 | collection_literal { $$ = $1;}
1723 parenthesis_expr:
1724 '(' expr ')' { $$ = $2;}
1727 expr_list:
1728 expr_list ',' expr { _p->onExprListElem($$, &$1, $3);}
1729 | expr { _p->onExprListElem($$, NULL, $1);}
1732 for_expr:
1733 expr_list { $$ = $1;}
1734 | { $$.reset();}
1737 yield_expr:
1738 T_YIELD { _p->onYield($$, NULL);}
1739 | T_YIELD expr { _p->onYield($$, &$2);}
1740 | T_YIELD expr T_DOUBLE_ARROW expr { _p->onYieldPair($$, &$2, &$4);}
1743 yield_assign_expr:
1744 variable '=' yield_expr { _p->onAssign($$, $1, $3, 0, true);}
1747 yield_list_assign_expr:
1748 T_LIST '(' assignment_list ')'
1749 '=' yield_expr { _p->onListAssignment($$, $3, &$6, true);}
1752 await_expr:
1753 T_AWAIT expr { _p->onAwait($$, $2); }
1756 await_assign_expr:
1757 variable '=' await_expr { _p->onAssign($$, $1, $3, 0, true);}
1760 await_list_assign_expr:
1761 T_LIST '(' assignment_list ')'
1762 '=' await_expr { _p->onListAssignment($$, $3, &$6, true);}
1765 expr:
1766 expr_no_variable { $$ = $1;}
1767 | variable { $$ = $1;}
1768 | expr_with_parens { $$ = $1;}
1769 | lambda_or_closure { $$ = $1;}
1770 | lambda_or_closure_with_parens { $$ = $1;}
1773 expr_no_variable:
1774 T_LIST '(' assignment_list ')'
1775 '=' expr { _p->onListAssignment($$, $3, &$6);}
1776 | variable '=' expr { _p->onAssign($$, $1, $3, 0);}
1777 | variable '=' '&' variable { _p->onAssign($$, $1, $4, 1);}
1778 | variable '=' '&' T_NEW
1779 class_name_reference
1780 ctor_arguments { _p->onAssignNew($$,$1,$5,$6);}
1781 | variable T_PLUS_EQUAL expr { BEXP($$,$1,$3,T_PLUS_EQUAL);}
1782 | variable T_MINUS_EQUAL expr { BEXP($$,$1,$3,T_MINUS_EQUAL);}
1783 | variable T_MUL_EQUAL expr { BEXP($$,$1,$3,T_MUL_EQUAL);}
1784 | variable T_DIV_EQUAL expr { BEXP($$,$1,$3,T_DIV_EQUAL);}
1785 | variable T_CONCAT_EQUAL expr { BEXP($$,$1,$3,T_CONCAT_EQUAL);}
1786 | variable T_MOD_EQUAL expr { BEXP($$,$1,$3,T_MOD_EQUAL);}
1787 | variable T_AND_EQUAL expr { BEXP($$,$1,$3,T_AND_EQUAL);}
1788 | variable T_OR_EQUAL expr { BEXP($$,$1,$3,T_OR_EQUAL);}
1789 | variable T_XOR_EQUAL expr { BEXP($$,$1,$3,T_XOR_EQUAL);}
1790 | variable T_SL_EQUAL expr { BEXP($$,$1,$3,T_SL_EQUAL);}
1791 | variable T_SR_EQUAL expr { BEXP($$,$1,$3,T_SR_EQUAL);}
1792 | variable T_POW_EQUAL expr { BEXP($$,$1,$3,T_POW_EQUAL);}
1793 | variable T_INC { UEXP($$,$1,T_INC,0);}
1794 | T_INC variable { UEXP($$,$2,T_INC,1);}
1795 | variable T_DEC { UEXP($$,$1,T_DEC,0);}
1796 | T_DEC variable { UEXP($$,$2,T_DEC,1);}
1797 | expr T_BOOLEAN_OR expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
1798 | expr T_BOOLEAN_AND expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
1799 | expr T_LOGICAL_OR expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
1800 | expr T_LOGICAL_AND expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
1801 | expr T_LOGICAL_XOR expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
1802 | expr '|' expr { BEXP($$,$1,$3,'|');}
1803 | expr '&' expr { BEXP($$,$1,$3,'&');}
1804 | expr '^' expr { BEXP($$,$1,$3,'^');}
1805 | expr '.' expr { BEXP($$,$1,$3,'.');}
1806 | expr '+' expr { BEXP($$,$1,$3,'+');}
1807 | expr '-' expr { BEXP($$,$1,$3,'-');}
1808 | expr '*' expr { BEXP($$,$1,$3,'*');}
1809 | expr '/' expr { BEXP($$,$1,$3,'/');}
1810 | expr T_POW expr { BEXP($$,$1,$3,T_POW);}
1811 | expr '%' expr { BEXP($$,$1,$3,'%');}
1812 | expr T_SL expr { BEXP($$,$1,$3,T_SL);}
1813 | expr T_SR expr { BEXP($$,$1,$3,T_SR);}
1814 | '+' expr %prec T_INC { UEXP($$,$2,'+',1);}
1815 | '-' expr %prec T_INC { UEXP($$,$2,'-',1);}
1816 | '!' expr { UEXP($$,$2,'!',1);}
1817 | '~' expr { UEXP($$,$2,'~',1);}
1818 | expr T_IS_IDENTICAL expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
1819 | expr T_IS_NOT_IDENTICAL expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
1820 | expr T_IS_EQUAL expr { BEXP($$,$1,$3,T_IS_EQUAL);}
1821 | expr T_IS_NOT_EQUAL expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
1822 | expr '<' expr { BEXP($$,$1,$3,'<');}
1823 | expr T_IS_SMALLER_OR_EQUAL expr { BEXP($$,$1,$3,
1824 T_IS_SMALLER_OR_EQUAL);}
1825 | expr '>' expr { BEXP($$,$1,$3,'>');}
1826 | expr T_IS_GREATER_OR_EQUAL expr { BEXP($$,$1,$3,
1827 T_IS_GREATER_OR_EQUAL);}
1828 | expr T_INSTANCEOF
1829 class_name_reference { BEXP($$,$1,$3,T_INSTANCEOF);}
1830 | '(' expr_no_variable ')' { $$ = $2;}
1831 | expr '?' expr ':' expr { _p->onQOp($$, $1, &$3, $5);}
1832 | expr '?' ':' expr { _p->onQOp($$, $1, 0, $4);}
1833 | internal_functions { $$ = $1;}
1834 | T_INT_CAST expr { UEXP($$,$2,T_INT_CAST,1);}
1835 | T_DOUBLE_CAST expr { UEXP($$,$2,T_DOUBLE_CAST,1);}
1836 | T_STRING_CAST expr { UEXP($$,$2,T_STRING_CAST,1);}
1837 | T_ARRAY_CAST expr { UEXP($$,$2,T_ARRAY_CAST,1);}
1838 | T_OBJECT_CAST expr { UEXP($$,$2,T_OBJECT_CAST,1);}
1839 | T_BOOL_CAST expr { UEXP($$,$2,T_BOOL_CAST,1);}
1840 | T_UNSET_CAST expr { UEXP($$,$2,T_UNSET_CAST,1);}
1841 | T_EXIT exit_expr { UEXP($$,$2,T_EXIT,1);}
1842 | '@' expr { UEXP($$,$2,'@',1);}
1843 | scalar { $$ = $1; }
1844 | array_literal { $$ = $1; }
1845 | shape_literal { $$ = $1; }
1846 | map_array_literal { $$ = $1; }
1847 | varray_literal { $$ = $1; }
1848 | '`' backticks_expr '`' { _p->onEncapsList($$,'`',$2);}
1849 | T_PRINT expr { UEXP($$,$2,T_PRINT,1);}
1850 | dim_expr { $$ = $1;}
1853 lambda_use_vars:
1854 T_USE '('
1855 lexical_var_list
1856 hh_possible_comma
1857 ')' { $$ = $3;}
1858 | { $$.reset();}
1861 closure_expression:
1862 function_loc
1863 is_reference '(' { Token t;
1864 _p->onNewLabelScope(true);
1865 _p->onClosureStart(t);
1866 _p->pushLabelInfo(); }
1867 parameter_list ')'
1868 hh_opt_return_type lambda_use_vars
1869 '{' inner_statement_list '}' { _p->finishStatement($10, $10); $10 = 1;
1870 $$ = _p->onClosure(ClosureType::Long,
1871 nullptr,
1872 $2,$5,$8,$10,$7);
1873 _p->popLabelInfo();
1874 _p->onCompleteLabelScope(true);}
1875 | non_empty_member_modifiers
1876 function_loc
1877 is_reference '(' { Token t;
1878 _p->onNewLabelScope(true);
1879 _p->onClosureStart(t);
1880 _p->pushLabelInfo(); }
1881 parameter_list ')'
1882 hh_opt_return_type lambda_use_vars
1883 '{' inner_statement_list '}' { _p->finishStatement($11, $11); $11 = 1;
1884 $$ = _p->onClosure(ClosureType::Long,
1885 &$1,
1886 $3,$6,$9,$11,$8);
1887 _p->popLabelInfo();
1888 _p->onCompleteLabelScope(true);}
1891 lambda_expression:
1892 T_VARIABLE { _p->pushFuncLocation();
1893 Token t;
1894 _p->onNewLabelScope(true);
1895 _p->onClosureStart(t);
1896 _p->pushLabelInfo();
1897 Token u;
1898 _p->onParam($1,NULL,u,$1,0,
1899 NULL,NULL,NULL);}
1900 lambda_body { Token v; Token w; Token x;
1901 _p->finishStatement($3, $3); $3 = 1;
1902 $$ = _p->onClosure(ClosureType::Short,
1903 nullptr,
1904 v,$1,w,$3,x);
1905 _p->popLabelInfo();
1906 _p->onCompleteLabelScope(true);}
1907 | T_ASYNC
1908 T_VARIABLE { _p->pushFuncLocation();
1909 Token t;
1910 _p->onNewLabelScope(true);
1911 _p->onClosureStart(t);
1912 _p->pushLabelInfo();
1913 Token u;
1914 _p->onParam($2,NULL,u,$2,0,
1915 NULL,NULL,NULL);}
1916 lambda_body { Token v; Token w; Token x;
1917 $1 = T_ASYNC;
1918 _p->onMemberModifier($1, nullptr, $1);
1919 _p->finishStatement($4, $4); $4 = 1;
1920 $$ = _p->onClosure(ClosureType::Short,
1921 &$1,
1922 v,$2,w,$4,x);
1923 _p->popLabelInfo();
1924 _p->onCompleteLabelScope(true);}
1925 | T_LAMBDA_OP { _p->pushFuncLocation();
1926 Token t;
1927 _p->onNewLabelScope(true);
1928 _p->onClosureStart(t);
1929 _p->pushLabelInfo();}
1930 parameter_list
1931 T_LAMBDA_CP
1932 hh_opt_return_type
1933 lambda_body { Token u; Token v;
1934 _p->finishStatement($6, $6); $6 = 1;
1935 $$ = _p->onClosure(ClosureType::Short,
1936 nullptr,
1937 u,$3,v,$6,$5);
1938 _p->popLabelInfo();
1939 _p->onCompleteLabelScope(true);}
1940 | T_ASYNC
1941 T_LAMBDA_OP { _p->pushFuncLocation();
1942 Token t;
1943 _p->onNewLabelScope(true);
1944 _p->onClosureStart(t);
1945 _p->pushLabelInfo();}
1946 parameter_list
1947 T_LAMBDA_CP
1948 hh_opt_return_type
1949 lambda_body { Token u; Token v;
1950 $1 = T_ASYNC;
1951 _p->onMemberModifier($1, nullptr, $1);
1952 _p->finishStatement($7, $7); $7 = 1;
1953 $$ = _p->onClosure(ClosureType::Short,
1954 &$1,
1955 u,$4,v,$7,$6);
1956 _p->popLabelInfo();
1957 _p->onCompleteLabelScope(true);}
1958 | T_ASYNC
1959 '{' { _p->pushFuncLocation();
1960 Token t;
1961 _p->onNewLabelScope(true);
1962 _p->onClosureStart(t);
1963 _p->pushLabelInfo();}
1964 inner_statement_list
1965 '}' { Token u; Token v; Token w; Token x;
1966 Token y;
1967 $1 = T_ASYNC;
1968 _p->onMemberModifier($1, nullptr, $1);
1969 _p->finishStatement($4, $4); $4 = 1;
1970 $$ = _p->onClosure(ClosureType::Short,
1971 &$1,
1972 u,v,w,$4,x);
1973 _p->popLabelInfo();
1974 _p->onCompleteLabelScope(true);
1975 _p->onCall($$,1,$$,y,NULL);}
1978 lambda_body:
1979 T_LAMBDA_ARROW expr { $$ = _p->onExprForLambda($2);}
1980 | T_LAMBDA_ARROW await_expr { $$ = _p->onExprForLambda($2);}
1981 | T_LAMBDA_ARROW
1982 '{' inner_statement_list '}' { $$ = $3; }
1985 shape_keyname:
1986 T_CONSTANT_ENCAPSED_STRING { validate_shape_keyname($1, _p);
1987 _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $1); }
1988 | class_constant { $$ = $1; }
1991 non_empty_shape_pair_list:
1992 non_empty_shape_pair_list ','
1993 shape_keyname
1994 T_DOUBLE_ARROW
1995 expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
1996 | shape_keyname
1997 T_DOUBLE_ARROW
1998 expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2001 non_empty_static_shape_pair_list:
2002 non_empty_static_shape_pair_list ','
2003 shape_keyname
2004 T_DOUBLE_ARROW
2005 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0); }
2006 | shape_keyname
2007 T_DOUBLE_ARROW
2008 static_expr { _p->onArrayPair($$, 0,&$1,$3,0); }
2011 shape_pair_list:
2012 non_empty_shape_pair_list
2013 possible_comma { $$ = $1; }
2014 | { $$.reset(); }
2017 static_shape_pair_list:
2018 non_empty_static_shape_pair_list
2019 possible_comma { $$ = $1; }
2020 | { $$.reset(); }
2023 shape_literal:
2024 T_SHAPE '(' shape_pair_list ')' { _p->onArray($$, $3, T_ARRAY);}
2027 array_literal:
2028 T_ARRAY '(' array_pair_list ')' { _p->onArray($$,$3,T_ARRAY);}
2029 | '[' array_pair_list ']' { _p->onArray($$,$2,T_ARRAY);}
2032 collection_literal:
2033 fully_qualified_class_name
2034 '{' collection_init '}' { Token t;
2035 _p->onName(t,$1,Parser::StringName);
2036 BEXP($$,t,$3,T_COLLECTION);}
2039 map_array_literal:
2040 T_MIARRAY '(' map_array_init ')' { _p->onCheckedArray($$,$3,T_MIARRAY);}
2041 | T_MSARRAY '(' map_array_init ')' { _p->onCheckedArray($$,$3,T_MSARRAY);}
2044 varray_literal:
2045 T_VARRAY '(' varray_init ')' { _p->onCheckedArray($$,$3,T_VARRAY);}
2048 static_map_array_literal:
2049 T_MIARRAY '('
2050 static_map_array_init ')' { _p->onCheckedArray($$,$3,T_MIARRAY);}
2051 | T_MSARRAY '('
2052 static_map_array_init ')' { _p->onCheckedArray($$,$3,T_MSARRAY);}
2055 static_varray_literal:
2056 T_VARRAY '('
2057 static_varray_init ')' { _p->onCheckedArray($$,$3,T_VARRAY);}
2060 static_collection_literal:
2061 fully_qualified_class_name
2062 '{' static_collection_init '}' { Token t;
2063 _p->onName(t,$1,Parser::StringName);
2064 BEXP($$,t,$3,T_COLLECTION);}
2067 dim_expr:
2068 dim_expr
2069 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2070 | dim_expr_base
2071 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2074 dim_expr_base:
2075 array_literal { $$ = $1;}
2076 | class_constant { $$ = $1;}
2077 | lambda_or_closure_with_parens { $$ = $1;}
2078 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2079 T_CONSTANT_ENCAPSED_STRING, $1); }
2080 | '(' expr_no_variable ')' { $$ = $2;}
2083 query_expr:
2084 query_head query_body { _p->onQuery($$, $1, $2); }
2087 query_assign_expr:
2088 variable '=' query_expr { _p->onAssign($$, $1, $3, 0, true);}
2091 query_head:
2092 T_FROM T_VARIABLE T_IN expr { _p->onFromClause($$, $2, $4); }
2095 query_body:
2096 query_body_clauses select_or_group_clause
2097 { _p->onQueryBody($$, &$1, $2, NULL); }
2098 | query_body_clauses select_or_group_clause query_continuation
2099 { _p->onQueryBody($$, &$1, $2, &$3); }
2100 | select_or_group_clause
2101 { _p->onQueryBody($$, NULL, $1, NULL); }
2102 | select_or_group_clause query_continuation
2103 { _p->onQueryBody($$, NULL, $1, &$2); }
2106 query_body_clauses:
2107 query_body_clause { _p->onQueryBodyClause($$, NULL, $1); }
2108 | query_body_clauses query_body_clause
2109 { _p->onQueryBodyClause($$, &$1, $2); }
2112 query_body_clause:
2113 from_clause { $$ = $1;}
2114 | let_clause { $$ = $1;}
2115 | where_clause { $$ = $1;}
2116 | join_clause { $$ = $1;}
2117 | join_into_clause { $$ = $1;}
2118 | orderby_clause { $$ = $1;}
2121 from_clause:
2122 T_FROM T_VARIABLE T_IN expr { _p->onFromClause($$, $2, $4); }
2125 let_clause:
2126 T_LET T_VARIABLE '=' expr { _p->onLetClause($$, $2, $4); }
2129 where_clause:
2130 T_WHERE expr { _p->onWhereClause($$, $2); }
2133 join_clause:
2134 T_JOIN T_VARIABLE T_IN expr T_ON expr T_EQUALS expr
2135 { _p->onJoinClause($$, $2, $4, $6, $8); }
2138 join_into_clause:
2139 T_JOIN T_VARIABLE T_IN expr T_ON expr T_EQUALS expr T_INTO T_VARIABLE
2140 { _p->onJoinIntoClause($$, $2, $4, $6, $8, $10); }
2143 orderby_clause:
2144 T_ORDERBY orderings { _p->onOrderbyClause($$, $2); }
2147 orderings:
2148 ordering { _p->onOrdering($$, NULL, $1); }
2149 | orderings ',' ordering { _p->onOrdering($$, &$1, $3); }
2152 ordering:
2153 expr { _p->onOrderingExpr($$, $1, NULL); }
2154 | expr ordering_direction { _p->onOrderingExpr($$, $1, &$2); }
2157 ordering_direction:
2158 T_ASCENDING { $$ = $1;}
2159 | T_DESCENDING { $$ = $1;}
2162 select_or_group_clause:
2163 select_clause { $$ = $1;}
2164 | group_clause { $$ = $1;}
2167 select_clause:
2168 T_SELECT expr { _p->onSelectClause($$, $2); }
2171 group_clause:
2172 T_GROUP expr T_BY expr { _p->onGroupClause($$, $2, $4); }
2175 query_continuation:
2176 T_INTO T_VARIABLE query_body { _p->onIntoClause($$, $2, $3); }
2179 lexical_var_list:
2180 lexical_var_list ',' T_VARIABLE { _p->onClosureParam($$,&$1,$3,0);}
2181 | lexical_var_list ',' '&'T_VARIABLE { _p->onClosureParam($$,&$1,$4,1);}
2182 | T_VARIABLE { _p->onClosureParam($$, 0,$1,0);}
2183 | '&' T_VARIABLE { _p->onClosureParam($$, 0,$2,1);}
2186 xhp_tag:
2187 T_XHP_TAG_LT
2188 T_XHP_LABEL
2189 xhp_tag_body
2190 T_XHP_TAG_GT { xhp_tag(_p,$$,$2,$3);}
2192 xhp_tag_body:
2193 xhp_attributes '/' { Token t1; _p->onArray(t1,$1);
2194 Token t2; _p->onArray(t2,$2);
2195 Token file; scalar_file(_p, file);
2196 Token line; scalar_line(_p, line);
2197 _p->onCallParam($1,NULL,t1,0,0);
2198 _p->onCallParam($$, &$1,t2,0,0);
2199 _p->onCallParam($1, &$1,file,0,0);
2200 _p->onCallParam($1, &$1,line,0,0);
2201 $$.setText("");}
2202 | xhp_attributes T_XHP_TAG_GT
2203 xhp_children T_XHP_TAG_LT '/'
2204 xhp_opt_end_label { Token file; scalar_file(_p, file);
2205 Token line; scalar_line(_p, line);
2206 _p->onArray($4,$1);
2207 _p->onArray($5,$3);
2208 _p->onCallParam($2,NULL,$4,0,0);
2209 _p->onCallParam($$, &$2,$5,0,0);
2210 _p->onCallParam($2, &$2,file,0,0);
2211 _p->onCallParam($2, &$2,line,0,0);
2212 $$.setText($6.text());}
2214 xhp_opt_end_label:
2215 { $$.reset(); $$.setText("");}
2216 | T_XHP_LABEL { $$.reset(); $$.setText($1);}
2218 xhp_attributes:
2219 xhp_attributes
2220 xhp_attribute_name '='
2221 xhp_attribute_value { _p->onArrayPair($$,&$1,&$2,$4,0);}
2222 | { $$.reset();}
2224 xhp_children:
2225 xhp_children xhp_child { _p->onArrayPair($$,&$1,0,$2,0);}
2226 | { $$.reset();}
2228 xhp_attribute_name:
2229 T_XHP_LABEL { _p->onScalar($$,
2230 T_CONSTANT_ENCAPSED_STRING, $1);}
2232 xhp_attribute_value:
2233 T_XHP_TEXT { $1.xhpDecode();
2234 _p->onScalar($$,
2235 T_CONSTANT_ENCAPSED_STRING, $1);}
2236 | '{' expr '}' { $$ = $2;}
2238 xhp_child:
2239 T_XHP_TEXT { $$.reset();
2240 if ($1.htmlTrim()) {
2241 $1.xhpDecode();
2242 _p->onScalar($$,
2243 T_CONSTANT_ENCAPSED_STRING, $1);
2246 | '{' expr '}' { $$ = $2; }
2247 | xhp_tag { $$ = $1; }
2250 xhp_label_ws:
2251 xhp_bareword { $$ = $1;}
2252 | xhp_label_ws ':'
2253 xhp_bareword { $$ = $1 + ":" + $3;}
2254 | xhp_label_ws '-'
2255 xhp_bareword { $$ = $1 + "-" + $3;}
2257 xhp_bareword:
2258 ident { $$ = $1;}
2259 | T_EXIT { $$ = $1;}
2260 | T_FUNCTION { $$ = $1;}
2261 | T_CONST { $$ = $1;}
2262 | T_RETURN { $$ = $1;}
2263 | T_YIELD { $$ = $1;}
2264 | T_AWAIT { $$ = $1;}
2265 | T_TRY { $$ = $1;}
2266 | T_CATCH { $$ = $1;}
2267 | T_FINALLY { $$ = $1;}
2268 | T_THROW { $$ = $1;}
2269 | T_IF { $$ = $1;}
2270 | T_ELSEIF { $$ = $1;}
2271 | T_ENDIF { $$ = $1;}
2272 | T_ELSE { $$ = $1;}
2273 | T_WHILE { $$ = $1;}
2274 | T_ENDWHILE { $$ = $1;}
2275 | T_DO { $$ = $1;}
2276 | T_FOR { $$ = $1;}
2277 | T_ENDFOR { $$ = $1;}
2278 | T_FOREACH { $$ = $1;}
2279 | T_ENDFOREACH { $$ = $1;}
2280 | T_DECLARE { $$ = $1;}
2281 | T_ENDDECLARE { $$ = $1;}
2282 | T_INSTANCEOF { $$ = $1;}
2283 | T_AS { $$ = $1;}
2284 | T_SWITCH { $$ = $1;}
2285 | T_ENDSWITCH { $$ = $1;}
2286 | T_CASE { $$ = $1;}
2287 | T_DEFAULT { $$ = $1;}
2288 | T_BREAK { $$ = $1;}
2289 | T_CONTINUE { $$ = $1;}
2290 | T_GOTO { $$ = $1;}
2291 | T_ECHO { $$ = $1;}
2292 | T_PRINT { $$ = $1;}
2293 | T_CLASS { $$ = $1;}
2294 | T_INTERFACE { $$ = $1;}
2295 | T_EXTENDS { $$ = $1;}
2296 | T_IMPLEMENTS { $$ = $1;}
2297 | T_NEW { $$ = $1;}
2298 | T_CLONE { $$ = $1;}
2299 | T_VAR { $$ = $1;}
2300 | T_EVAL { $$ = $1;}
2301 | T_INCLUDE { $$ = $1;}
2302 | T_INCLUDE_ONCE { $$ = $1;}
2303 | T_REQUIRE { $$ = $1;}
2304 | T_REQUIRE_ONCE { $$ = $1;}
2305 | T_NAMESPACE { $$ = $1;}
2306 | T_USE { $$ = $1;}
2307 | T_GLOBAL { $$ = $1;}
2308 | T_ISSET { $$ = $1;}
2309 | T_EMPTY { $$ = $1;}
2310 | T_HALT_COMPILER { $$ = $1;}
2311 | T_STATIC { $$ = $1;}
2312 | T_ABSTRACT { $$ = $1;}
2313 | T_FINAL { $$ = $1;}
2314 | T_PRIVATE { $$ = $1;}
2315 | T_PROTECTED { $$ = $1;}
2316 | T_PUBLIC { $$ = $1;}
2317 | T_ASYNC { $$ = $1;}
2318 | T_UNSET { $$ = $1;}
2319 | T_LIST { $$ = $1;}
2320 | T_ARRAY { $$ = $1;}
2321 | T_LOGICAL_OR { $$ = $1;}
2322 | T_LOGICAL_AND { $$ = $1;}
2323 | T_LOGICAL_XOR { $$ = $1;}
2324 | T_CLASS_C { $$ = $1;}
2325 | T_FUNC_C { $$ = $1;}
2326 | T_METHOD_C { $$ = $1;}
2327 | T_LINE { $$ = $1;}
2328 | T_FILE { $$ = $1;}
2329 | T_DIR { $$ = $1;}
2330 | T_NS_C { $$ = $1;}
2331 | T_COMPILER_HALT_OFFSET { $$ = $1;}
2332 | T_TRAIT { $$ = $1;}
2333 | T_TRAIT_C { $$ = $1;}
2334 | T_INSTEADOF { $$ = $1;}
2335 | T_TYPE { $$ = $1;}
2336 | T_NEWTYPE { $$ = $1;}
2337 | T_SHAPE { $$ = $1;}
2340 simple_function_call:
2341 namespace_string_typeargs '('
2342 function_call_parameter_list ')' { _p->onCall($$,0,$1,$3,NULL);}
2345 fully_qualified_class_name:
2346 class_namespace_string_typeargs { $$ = $1;}
2347 | T_XHP_LABEL { $1.xhpLabel(); $$ = $1;}
2349 static_class_name:
2350 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2351 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2352 | reference_variable { _p->onName($$,$1,
2353 Parser::StaticClassExprName);}
2355 class_name_reference:
2356 fully_qualified_class_name { _p->onName($$,$1,Parser::StringName);}
2357 | T_STATIC { _p->onName($$,$1,Parser::StaticName);}
2358 | variable_no_calls { _p->onName($$,$1,Parser::ExprName);}
2361 exit_expr:
2362 '(' ')' { $$.reset();}
2363 | parenthesis_expr { $$ = $1;}
2364 | { $$.reset();}
2367 backticks_expr:
2368 /* empty */ { $$.reset();}
2369 | T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, NULL, $1, 0);}
2370 | encaps_list { $$ = $1;}
2372 ctor_arguments:
2374 function_call_parameter_list ')' { $$ = $2;}
2375 | { $$.reset();}
2378 common_scalar:
2379 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2380 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2381 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2382 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2383 T_CONSTANT_ENCAPSED_STRING, $1);}
2384 | T_LINE { _p->onScalar($$, T_LINE, $1);}
2385 | T_FILE { _p->onScalar($$, T_FILE, $1);}
2386 | T_DIR { _p->onScalar($$, T_DIR, $1);}
2387 | T_CLASS_C { _p->onScalar($$, T_CLASS_C, $1);}
2388 | T_TRAIT_C { _p->onScalar($$, T_TRAIT_C, $1);}
2389 | T_METHOD_C { _p->onScalar($$, T_METHOD_C, $1);}
2390 | T_FUNC_C { _p->onScalar($$, T_FUNC_C, $1);}
2391 | T_NS_C { _p->onScalar($$, T_NS_C, $1);}
2392 | T_COMPILER_HALT_OFFSET { _p->onScalar($$, T_COMPILER_HALT_OFFSET, $1);}
2393 | T_START_HEREDOC
2394 T_ENCAPSED_AND_WHITESPACE
2395 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2396 | T_START_HEREDOC
2397 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2400 static_expr:
2401 common_scalar { $$ = $1;}
2402 | namespace_string { _p->onConstantValue($$, $1);}
2403 | T_ARRAY '('
2404 static_array_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2405 | '[' static_array_pair_list ']' { _p->onArray($$,$2,T_ARRAY); }
2406 | T_SHAPE '('
2407 static_shape_pair_list ')' { _p->onArray($$,$3,T_ARRAY); }
2408 | static_class_constant { $$ = $1;}
2409 | static_collection_literal { $$ = $1;}
2410 | static_map_array_literal { $$ = $1;}
2411 | static_varray_literal { $$ = $1;}
2412 | '(' static_expr ')' { $$ = $2;}
2413 | static_expr T_BOOLEAN_OR
2414 static_expr { BEXP($$,$1,$3,T_BOOLEAN_OR);}
2415 | static_expr T_BOOLEAN_AND
2416 static_expr { BEXP($$,$1,$3,T_BOOLEAN_AND);}
2417 | static_expr T_LOGICAL_OR
2418 static_expr { BEXP($$,$1,$3,T_LOGICAL_OR);}
2419 | static_expr T_LOGICAL_AND
2420 static_expr { BEXP($$,$1,$3,T_LOGICAL_AND);}
2421 | static_expr T_LOGICAL_XOR
2422 static_expr { BEXP($$,$1,$3,T_LOGICAL_XOR);}
2423 | static_expr '|' static_expr { BEXP($$,$1,$3,'|');}
2424 | static_expr '&' static_expr { BEXP($$,$1,$3,'&');}
2425 | static_expr '^' static_expr { BEXP($$,$1,$3,'^');}
2426 | static_expr '.' static_expr { BEXP($$,$1,$3,'.');}
2427 | static_expr '+' static_expr { BEXP($$,$1,$3,'+');}
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 T_SL static_expr { BEXP($$,$1,$3,T_SL);}
2433 | static_expr T_SR static_expr { BEXP($$,$1,$3,T_SR);}
2434 | static_expr T_POW static_expr { BEXP($$,$1,$3,T_POW);}
2435 | '!' static_expr { UEXP($$,$2,'!',1);}
2436 | '~' static_expr { UEXP($$,$2,'~',1);}
2437 | '+' static_expr { UEXP($$,$2,'+',1);}
2438 | '-' static_expr { UEXP($$,$2,'-',1);}
2439 | static_expr T_IS_IDENTICAL
2440 static_expr { BEXP($$,$1,$3,T_IS_IDENTICAL);}
2441 | static_expr T_IS_NOT_IDENTICAL
2442 static_expr { BEXP($$,$1,$3,T_IS_NOT_IDENTICAL);}
2443 | static_expr T_IS_EQUAL
2444 static_expr { BEXP($$,$1,$3,T_IS_EQUAL);}
2445 | static_expr T_IS_NOT_EQUAL
2446 static_expr { BEXP($$,$1,$3,T_IS_NOT_EQUAL);}
2447 | static_expr '<' static_expr { BEXP($$,$1,$3,'<');}
2448 | static_expr T_IS_SMALLER_OR_EQUAL
2449 static_expr { BEXP($$,$1,$3,
2450 T_IS_SMALLER_OR_EQUAL);}
2451 | static_expr '>' static_expr { BEXP($$,$1,$3,'>');}
2452 | static_expr
2453 T_IS_GREATER_OR_EQUAL
2454 static_expr { BEXP($$,$1,$3,
2455 T_IS_GREATER_OR_EQUAL);}
2456 | static_expr '?' static_expr ':'
2457 static_expr { _p->onQOp($$, $1, &$3, $5);}
2458 | static_expr '?' ':' static_expr { _p->onQOp($$, $1, 0, $4);}
2461 static_class_constant:
2462 class_namespace_string_typeargs
2463 T_DOUBLE_COLON
2464 ident { _p->onClassConst($$, $1, $3, 1);}
2465 | T_XHP_LABEL T_DOUBLE_COLON
2466 ident { $1.xhpLabel();
2467 _p->onClassConst($$, $1, $3, 1);}
2468 | class_namespace_string_typeargs
2469 T_DOUBLE_COLON
2470 T_CLASS { _p->onClassClass($$, $1, $3, 1);}
2473 scalar:
2474 namespace_string { _p->onConstantValue($$, $1);}
2475 | T_STRING_VARNAME { _p->onConstantValue($$, $1);}
2476 | class_constant { $$ = $1;}
2477 | common_scalar { $$ = $1;}
2478 | '"' encaps_list '"' { _p->onEncapsList($$,'"',$2);}
2479 | '\'' encaps_list '\'' { _p->onEncapsList($$,'\'',$2);}
2480 | T_START_HEREDOC encaps_list
2481 T_END_HEREDOC { _p->onEncapsList($$,T_START_HEREDOC,
2482 $2);}
2484 static_array_pair_list:
2485 non_empty_static_array_pair_list
2486 possible_comma { $$ = $1;}
2487 | { $$.reset();}
2490 possible_comma:
2491 ',' { $$.reset();}
2492 | { $$.reset();}
2494 hh_possible_comma:
2495 ',' { only_in_hh_syntax(_p); $$.reset();}
2496 | { $$.reset();}
2499 non_empty_static_array_pair_list:
2500 non_empty_static_array_pair_list
2501 ',' static_expr T_DOUBLE_ARROW
2502 static_expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2503 | non_empty_static_array_pair_list
2504 ',' static_expr { _p->onArrayPair($$,&$1, 0,$3,0);}
2505 | static_expr T_DOUBLE_ARROW
2506 static_expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2507 | static_expr { _p->onArrayPair($$, 0, 0,$1,0);}
2510 common_scalar_ae:
2511 T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
2512 | T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
2513 | T_ONUMBER { _p->onScalar($$, T_ONUMBER, $1);}
2514 | T_CONSTANT_ENCAPSED_STRING { _p->onScalar($$,
2515 T_CONSTANT_ENCAPSED_STRING, $1);}
2516 | T_START_HEREDOC
2517 T_ENCAPSED_AND_WHITESPACE
2518 T_END_HEREDOC { _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $2);}
2519 | T_START_HEREDOC
2520 T_END_HEREDOC { $$.setText(""); _p->onScalar($$, T_CONSTANT_ENCAPSED_STRING, $$);}
2522 static_numeric_scalar_ae:
2523 T_LNUMBER { _p->onScalar($$,T_LNUMBER,$1);}
2524 | T_DNUMBER { _p->onScalar($$,T_DNUMBER,$1);}
2525 | T_ONUMBER { _p->onScalar($$,T_ONUMBER,$1);}
2526 | ident { constant_ae(_p,$$,$1);}
2528 static_scalar_ae:
2529 common_scalar_ae { $$ = $1;}
2530 | ident { constant_ae(_p,$$,$1);}
2531 | '+' static_numeric_scalar_ae { UEXP($$,$2,'+',1);}
2532 | '-' static_numeric_scalar_ae { UEXP($$,$2,'-',1);}
2533 | T_ARRAY '('
2534 static_array_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY);}
2535 | '[' static_array_pair_list_ae ']' { _p->onArray($$,$2,T_ARRAY);}
2536 | T_SHAPE '('
2537 static_shape_pair_list_ae ')' { _p->onArray($$,$3,T_ARRAY); }
2540 static_array_pair_list_ae:
2541 non_empty_static_array_pair_list_ae
2542 possible_comma { $$ = $1;}
2543 | { $$.reset();}
2545 non_empty_static_array_pair_list_ae:
2546 non_empty_static_array_pair_list_ae
2547 ',' static_scalar_ae T_DOUBLE_ARROW
2548 static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0);}
2549 | non_empty_static_array_pair_list_ae
2550 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2551 | static_scalar_ae T_DOUBLE_ARROW
2552 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0);}
2553 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2555 non_empty_static_scalar_list_ae:
2556 non_empty_static_scalar_list_ae
2557 ',' static_scalar_ae { _p->onArrayPair($$,&$1, 0,$3,0);}
2558 | static_scalar_ae { _p->onArrayPair($$, 0, 0,$1,0);}
2561 static_shape_pair_list_ae:
2562 non_empty_static_shape_pair_list_ae
2563 possible_comma { $$ = $1; }
2564 | { $$.reset(); }
2566 non_empty_static_shape_pair_list_ae:
2567 non_empty_static_shape_pair_list_ae
2568 ',' shape_keyname
2569 T_DOUBLE_ARROW static_scalar_ae { _p->onArrayPair($$,&$1,&$3,$5,0); }
2570 | shape_keyname
2571 T_DOUBLE_ARROW
2572 static_scalar_ae { _p->onArrayPair($$, 0,&$1,$3,0); }
2575 static_scalar_list_ae:
2576 non_empty_static_scalar_list_ae
2577 possible_comma { $$ = $1;}
2578 | { $$.reset();}
2580 attribute_static_scalar_list:
2581 '(' static_scalar_list_ae ')' { _p->onArray($$,$2,T_ARRAY);}
2582 | { Token t; t.reset();
2583 _p->onArray($$,t,T_ARRAY);}
2586 non_empty_user_attribute_list:
2587 non_empty_user_attribute_list
2588 ',' ident
2589 attribute_static_scalar_list { _p->onUserAttribute($$,&$1,$3,$4);}
2590 | ident
2591 attribute_static_scalar_list { _p->onUserAttribute($$, 0,$1,$2);}
2593 user_attribute_list:
2594 { only_in_hh_syntax(_p);}
2595 non_empty_user_attribute_list
2596 possible_comma { $$ = $2;}
2598 non_empty_user_attributes:
2599 T_SL user_attribute_list T_SR { $$ = $2;}
2601 optional_user_attributes:
2602 non_empty_user_attributes { $$ = $1;}
2603 | { $$.reset();}
2606 object_operator:
2607 T_OBJECT_OPERATOR { $$ = $1; $$ = 0;}
2608 | T_NULLSAFE_OBJECT_OPERATOR { $$ = $1; $$ = 1;}
2611 object_property_name_no_variables:
2612 ident { $$ = $1; $$ = HPHP::ObjPropNormal;}
2613 | T_XHP_LABEL { $$ = $1; $$ = HPHP::ObjPropXhpAttr;}
2614 | '{' expr '}' { $$ = $2; $$ = HPHP::ObjPropNormal;}
2617 object_property_name:
2618 object_property_name_no_variables { $$ = $1;}
2619 | variable_no_objects { $$ = $1; $$ = HPHP::ObjPropNormal;}
2622 object_method_name_no_variables:
2623 ident { $$ = $1;}
2624 | '{' expr '}' { $$ = $2;}
2627 object_method_name:
2628 object_method_name_no_variables { $$ = $1;}
2629 | variable_no_objects { $$ = $1;}
2632 array_access:
2633 '[' dim_offset ']' { $$ = $2;}
2634 | '{' expr '}' { $$ = $2;}
2637 dimmable_variable_access:
2638 dimmable_variable array_access { _p->onRefDim($$, $1, $2);}
2639 | '(' expr_with_parens ')'
2640 array_access { _p->onRefDim($$, $2, $4);}
2643 dimmable_variable_no_calls_access:
2644 dimmable_variable_no_calls
2645 array_access { _p->onRefDim($$, $1, $2);}
2646 | '(' expr_with_parens ')'
2647 array_access { _p->onRefDim($$, $2, $4);}
2650 variable:
2651 variable_no_objects { $$ = $1;}
2652 | simple_function_call { $$ = $1;}
2653 | object_method_call { $$ = $1;}
2654 | class_method_call { $$ = $1;}
2655 | dimmable_variable_access { $$ = $1;}
2656 | variable object_operator
2657 object_property_name { _p->onObjectProperty($$,$1,$2.num(),$3);}
2658 | '(' expr_with_parens ')'
2659 object_operator
2660 object_property_name { _p->onObjectProperty($$,$2,$4.num(),$5);}
2661 | static_class_name
2662 T_DOUBLE_COLON
2663 variable_no_objects { _p->onStaticMember($$,$1,$3);}
2664 | callable_variable '('
2665 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2666 | lambda_or_closure_with_parens '('
2667 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2668 | '(' variable ')' { $$ = $2;}
2671 dimmable_variable:
2672 simple_function_call { $$ = $1;}
2673 | object_method_call { $$ = $1;}
2674 | class_method_call { $$ = $1;}
2675 | dimmable_variable_access { $$ = $1;}
2676 | variable object_operator
2677 object_property_name_no_variables
2678 { _p->onObjectProperty($$,$1,$2.num(),$3);}
2679 | '(' expr_with_parens ')'
2680 object_operator
2681 object_property_name_no_variables
2682 { _p->onObjectProperty($$,$2,$4.num(),$5);}
2683 | callable_variable '('
2684 function_call_parameter_list ')' { _p->onCall($$,1,$1,$3,NULL);}
2685 | '(' variable ')' { $$ = $2;}
2688 callable_variable:
2689 variable_no_objects { $$ = $1;}
2690 | dimmable_variable_access { $$ = $1;}
2691 | '(' variable ')' { $$ = $2;}
2694 lambda_or_closure_with_parens:
2695 '(' lambda_or_closure ')' { $$ = $2;}
2698 lambda_or_closure:
2699 closure_expression { $$ = $1;}
2700 | lambda_expression { $$ = $1;}
2703 object_method_call:
2704 variable object_operator
2705 object_method_name hh_typeargs_opt '('
2706 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$1,$2.num(),$3,$6);}
2707 | '(' expr_with_parens ')'
2708 object_operator
2709 object_method_name hh_typeargs_opt '('
2710 function_call_parameter_list ')' { _p->onObjectMethodCall($$,$2,$4.num(),$5,$8);}
2713 class_method_call:
2714 static_class_name
2715 T_DOUBLE_COLON
2716 ident hh_typeargs_opt '('
2717 function_call_parameter_list ')' { _p->onCall($$,0,$3,$6,&$1);}
2718 | static_class_name
2719 T_DOUBLE_COLON
2720 variable_no_objects '('
2721 function_call_parameter_list ')' { _p->onCall($$,1,$3,$5,&$1);}
2722 | static_class_name
2723 T_DOUBLE_COLON
2724 '{' expr '}' '('
2725 function_call_parameter_list ')' { _p->onCall($$,1,$4,$7,&$1);}
2728 variable_no_objects:
2729 reference_variable { $$ = $1;}
2730 | simple_indirect_reference
2731 reference_variable { _p->onIndirectRef($$,$1,$2);}
2734 reference_variable:
2735 reference_variable
2736 '[' dim_offset ']' { _p->onRefDim($$, $1, $3);}
2737 | reference_variable '{' expr '}' { _p->onRefDim($$, $1, $3);}
2738 | compound_variable { $$ = $1;}
2740 compound_variable:
2741 T_VARIABLE { _p->onSimpleVariable($$, $1);}
2742 | '$' '{' expr '}' { _p->onDynamicVariable($$, $3, 0);}
2744 dim_offset:
2745 expr { $$ = $1;}
2746 | { $$.reset();}
2749 simple_indirect_reference:
2750 '$' { $$ = 1;}
2751 | simple_indirect_reference '$' { $$++;}
2754 variable_no_calls:
2755 variable_no_objects { $$ = $1;}
2756 | dimmable_variable_no_calls_access { $$ = $1;}
2757 | variable_no_calls
2758 object_operator
2759 object_property_name { _p->onObjectProperty($$,$1,$2.num(),$3);}
2760 | '(' expr_with_parens ')'
2761 object_operator
2762 object_property_name { _p->onObjectProperty($$,$2,$4.num(),$5);}
2763 | static_class_name
2764 T_DOUBLE_COLON
2765 variable_no_objects { _p->onStaticMember($$,$1,$3);}
2766 | '(' variable ')' { $$ = $2;}
2769 dimmable_variable_no_calls:
2770 | dimmable_variable_no_calls_access { $$ = $1;}
2771 | variable_no_calls object_operator
2772 object_property_name_no_variables
2773 { _p->onObjectProperty($$,$1,$2.num(),$3);}
2774 | '(' expr_with_parens ')'
2775 object_operator
2776 object_property_name_no_variables
2777 { _p->onObjectProperty($$,$2,$4.num(),$5);}
2778 | '(' variable ')' { $$ = $2;}
2781 assignment_list:
2782 assignment_list ',' { _p->onAListVar($$,&$1,NULL);}
2783 | assignment_list ',' variable { _p->onAListVar($$,&$1,&$3);}
2784 | assignment_list ','
2785 T_LIST '(' assignment_list ')' { _p->onAListSub($$,&$1,$5);}
2786 | { _p->onAListVar($$,NULL,NULL);}
2787 | variable { _p->onAListVar($$,NULL,&$1);}
2788 | T_LIST '(' assignment_list ')' { _p->onAListSub($$,NULL,$3);}
2791 array_pair_list:
2792 non_empty_array_pair_list
2793 possible_comma { $$ = $1;}
2794 | { $$.reset();}
2796 non_empty_array_pair_list:
2797 non_empty_array_pair_list
2798 ',' expr T_DOUBLE_ARROW expr { _p->onArrayPair($$,&$1,&$3,$5,0);}
2799 | non_empty_array_pair_list ',' expr { _p->onArrayPair($$,&$1, 0,$3,0);}
2800 | expr T_DOUBLE_ARROW expr { _p->onArrayPair($$, 0,&$1,$3,0);}
2801 | expr { _p->onArrayPair($$, 0, 0,$1,0);}
2802 | non_empty_array_pair_list
2803 ',' expr T_DOUBLE_ARROW
2804 '&' variable { _p->onArrayPair($$,&$1,&$3,$6,1);}
2805 | non_empty_array_pair_list ','
2806 '&' variable { _p->onArrayPair($$,&$1, 0,$4,1);}
2807 | expr T_DOUBLE_ARROW '&' variable { _p->onArrayPair($$, 0,&$1,$4,1);}
2808 | '&' variable { _p->onArrayPair($$, 0, 0,$2,1);}
2811 collection_init:
2812 non_empty_collection_init
2813 possible_comma { $$ = $1;}
2814 | { _p->onEmptyCollection($$);}
2816 non_empty_collection_init:
2817 non_empty_collection_init
2818 ',' expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$,&$1,&$3,$5);}
2819 | non_empty_collection_init ',' expr { _p->onCollectionPair($$,&$1, 0,$3);}
2820 | expr T_DOUBLE_ARROW expr { _p->onCollectionPair($$, 0,&$1,$3);}
2821 | expr { _p->onCollectionPair($$, 0, 0,$1);}
2824 static_collection_init:
2825 non_empty_static_collection_init
2826 possible_comma { $$ = $1;}
2827 | { _p->onEmptyCollection($$);}
2829 non_empty_static_collection_init:
2830 non_empty_static_collection_init
2831 ',' static_expr T_DOUBLE_ARROW
2832 static_expr { _p->onCollectionPair($$,&$1,&$3,$5);}
2833 | non_empty_static_collection_init
2834 ',' static_expr { _p->onCollectionPair($$,&$1, 0,$3);}
2835 | static_expr T_DOUBLE_ARROW
2836 static_expr { _p->onCollectionPair($$, 0,&$1,$3);}
2837 | static_expr { _p->onCollectionPair($$, 0, 0,$1);}
2840 map_array_init:
2841 non_empty_map_array_init
2842 possible_comma { $$ = $1;}
2843 | { _p->onEmptyCheckedArray($$);}
2845 varray_init:
2846 non_empty_varray_init
2847 possible_comma { $$ = $1;}
2848 | { _p->onEmptyCheckedArray($$);}
2850 non_empty_map_array_init:
2851 non_empty_map_array_init
2852 ',' expr T_DOUBLE_ARROW expr { _p->onCheckedArrayPair($$,&$1,&$3,$5);}
2853 | expr T_DOUBLE_ARROW expr { _p->onCheckedArrayPair($$, 0,&$1,$3);}
2855 non_empty_varray_init:
2856 non_empty_varray_init ',' expr { _p->onCheckedArrayPair($$,&$1, 0,$3);}
2857 | expr { _p->onCheckedArrayPair($$, 0, 0,$1);}
2860 static_map_array_init:
2861 non_empty_static_map_array_init
2862 possible_comma { $$ = $1;}
2863 | { _p->onEmptyCheckedArray($$);}
2865 static_varray_init:
2866 non_empty_static_varray_init
2867 possible_comma { $$ = $1;}
2868 | { _p->onEmptyCheckedArray($$);}
2870 non_empty_static_map_array_init:
2871 non_empty_static_map_array_init
2872 ',' static_expr T_DOUBLE_ARROW
2873 static_expr { _p->onCheckedArrayPair($$,&$1,&$3,$5);}
2874 | static_expr T_DOUBLE_ARROW
2875 static_expr { _p->onCheckedArrayPair($$, 0,&$1,$3);}
2877 non_empty_static_varray_init:
2878 non_empty_static_varray_init
2879 ',' static_expr { _p->onCheckedArrayPair($$,&$1, 0,$3);}
2880 | static_expr { _p->onCheckedArrayPair($$, 0, 0,$1);}
2883 encaps_list:
2884 encaps_list encaps_var { _p->addEncap($$, &$1, $2, -1);}
2885 | encaps_list
2886 T_ENCAPSED_AND_WHITESPACE { _p->addEncap($$, &$1, $2, 0);}
2887 | encaps_var { _p->addEncap($$, NULL, $1, -1);}
2888 | T_ENCAPSED_AND_WHITESPACE
2889 encaps_var { _p->addEncap($$, NULL, $1, 0);
2890 _p->addEncap($$, &$$, $2, -1); }
2893 encaps_var:
2894 T_VARIABLE { _p->onSimpleVariable($$, $1);}
2895 | T_VARIABLE '['
2896 encaps_var_offset ']' { _p->encapRefDim($$, $1, $3);}
2897 | T_VARIABLE object_operator
2898 ident { _p->encapObjProp($$, $1, $2.num(), $3);}
2899 | T_DOLLAR_OPEN_CURLY_BRACES
2900 expr '}' { _p->onDynamicVariable($$, $2, 1);}
2901 | T_DOLLAR_OPEN_CURLY_BRACES
2902 T_STRING_VARNAME '[' expr ']' '}' { _p->encapArray($$, $2, $4);}
2903 | T_CURLY_OPEN variable '}' { $$ = $2;}
2905 encaps_var_offset:
2906 ident { $$ = $1; $$ = T_STRING;}
2907 | T_NUM_STRING { $$ = $1; $$ = T_NUM_STRING;}
2908 | T_VARIABLE { $$ = $1; $$ = T_VARIABLE;}
2911 internal_functions:
2912 T_ISSET '(' variable_list ')' { UEXP($$,$3,T_ISSET,1);}
2913 | T_EMPTY '(' variable ')' { UEXP($$,$3,T_EMPTY,1);}
2914 | T_EMPTY '(' expr_no_variable ')' { UEXP($$,$3,'!',1);}
2915 | T_EMPTY '(' lambda_or_closure ')' { UEXP($$,$3,'!',1);}
2916 | T_EMPTY '(' lambda_or_closure_with_parens ')' { UEXP($$,$3,'!',1);}
2917 | T_EMPTY '(' expr_with_parens ')' { UEXP($$,$3,'!',1);}
2918 | T_INCLUDE expr { UEXP($$,$2,T_INCLUDE,1);}
2919 | T_INCLUDE_ONCE expr { UEXP($$,$2,T_INCLUDE_ONCE,1);}
2920 | T_EVAL '(' expr ')' { UEXP($$,$3,T_EVAL,1);}
2921 | T_REQUIRE expr { UEXP($$,$2,T_REQUIRE,1);}
2922 | T_REQUIRE_ONCE expr { UEXP($$,$2,T_REQUIRE_ONCE,1);}
2925 variable_list:
2926 variable { _p->onExprListElem($$, NULL, $1);}
2927 | variable_list ',' variable { _p->onExprListElem($$, &$1, $3);}
2930 class_constant:
2931 static_class_name
2932 T_DOUBLE_COLON ident { _p->onClassConst($$, $1, $3, 0);}
2933 | static_class_name
2934 T_DOUBLE_COLON T_CLASS { _p->onClassClass($$, $1, $3, 0);}
2937 /* hack productions -- these allow some extra stuff in hack
2938 * mode, but simplify down to the original thing
2941 hh_opt_constraint:
2942 /* empty */
2943 | T_AS hh_type
2946 hh_type_alias_statement:
2947 T_TYPE hh_name_with_typevar
2948 '=' hh_type ';' { $2.setText(_p->nsDecl($2.text()));
2949 _p->onTypedef($$, $2, $4);
2950 _p->popTypeScope(); }
2951 | T_NEWTYPE hh_name_with_typevar
2952 hh_opt_constraint '=' hh_type ';' { $2.setText(_p->nsDecl($2.text()));
2953 _p->onTypedef($$, $2, $5);
2954 _p->popTypeScope(); }
2957 hh_name_with_type: /* foo -> int foo */
2958 ident { $$ = $1; }
2959 | hh_type ident { only_in_hh_syntax(_p); $$ = $2; }
2962 hh_name_with_typevar: /* foo -> foo<X,Y>; this adds a typevar scope
2963 * and must be followed by a call to
2964 * popTypeScope() */
2965 ident { _p->pushTypeScope(); $$ = $1; }
2966 | ident
2967 T_TYPELIST_LT
2968 hh_typevar_list
2969 T_TYPELIST_GT { _p->pushTypeScope(); $$ = $1; }
2972 hh_typeargs_opt:
2973 T_TYPELIST_LT
2974 hh_type_list
2975 T_TYPELIST_GT { $$ = $2; }
2976 | { $$.reset(); }
2979 hh_non_empty_type_list:
2980 hh_type { Token t; t.reset();
2981 _p->onTypeList($1, t);
2982 $$ = $1; }
2983 | hh_non_empty_type_list ',' hh_type { _p->onTypeList($1, $3);
2984 $$ = $1; }
2987 hh_type_list:
2988 hh_non_empty_type_list
2989 possible_comma { $$ = $1; }
2992 hh_func_type_list:
2993 hh_non_empty_type_list
2994 ',' T_ELLIPSIS { $$ = $1; }
2995 | hh_type_list { $$ = $1; }
2996 | T_ELLIPSIS { $$.reset(); }
2997 | { $$.reset(); }
3000 hh_opt_return_type:
3001 { $$.reset(); }
3002 | ':' hh_type { only_in_hh_syntax(_p); $$ = $2; }
3005 hh_typevar_list:
3006 hh_typevar_list ','
3007 hh_typevar_variance ident { _p->addTypeVar($4.text()); }
3008 | hh_typevar_variance ident { _p->addTypeVar($2.text()); }
3009 | hh_typevar_list ','
3010 hh_typevar_variance ident
3011 T_AS hh_type { _p->addTypeVar($4.text()); }
3012 | hh_typevar_variance ident
3013 T_AS hh_type { _p->addTypeVar($2.text()); }
3016 hh_typevar_variance:
3017 '+' {}
3018 | '-' {}
3019 | /* empty */ {}
3022 hh_shape_member_type:
3023 T_CONSTANT_ENCAPSED_STRING
3024 T_DOUBLE_ARROW
3025 hh_type { validate_shape_keyname($1, _p); }
3026 | class_namespace_string_typeargs
3027 T_DOUBLE_COLON
3028 ident
3029 T_DOUBLE_ARROW
3030 hh_type { }
3034 hh_non_empty_shape_member_list:
3035 hh_non_empty_shape_member_list ','
3036 hh_shape_member_type
3037 | hh_shape_member_type
3040 hh_shape_member_list:
3041 hh_non_empty_shape_member_list
3042 possible_comma { $$ = $1; }
3043 | /* empty */
3046 hh_shape_type:
3047 T_SHAPE
3048 '(' hh_shape_member_list ')' { $$.setText("array"); }
3051 /* extends non_empty_type_decl with some more types */
3052 hh_type:
3053 /* double-optional types will be rejected by the typechecker; we
3054 * already allow plenty of nonsense types anyway */
3055 '?' hh_type { only_in_hh_syntax(_p);
3056 _p->onTypeSpecialization($2, '?');
3057 $$ = $2; }
3058 | '@' hh_type { only_in_hh_syntax(_p);
3059 _p->onTypeSpecialization($2, '@');
3060 $$ = $2; }
3061 | class_namespace_string_typeargs { $$ = $1; }
3062 | T_ARRAY { Token t; t.reset();
3063 $1.setText("array");
3064 _p->onTypeAnnotation($$, $1, t); }
3065 | T_CALLABLE { Token t; t.reset();
3066 $1.setText("callable");
3067 _p->onTypeAnnotation($$, $1, t); }
3068 | hh_shape_type { $$ = $1; }
3069 | T_ARRAY T_TYPELIST_LT hh_type
3070 T_TYPELIST_GT { $1.setText("array");
3071 _p->onTypeAnnotation($$, $1, $3); }
3072 | T_ARRAY T_TYPELIST_LT hh_type ','
3073 hh_type T_TYPELIST_GT { _p->onTypeList($3, $5);
3074 $1.setText("array");
3075 _p->onTypeAnnotation($$, $1, $3); }
3076 | T_XHP_LABEL { $1.xhpLabel();
3077 Token t; t.reset();
3078 _p->onTypeAnnotation($$, $1, t);
3079 _p->onTypeSpecialization($$, 'x'); }
3080 | '(' T_FUNCTION
3081 '(' hh_func_type_list ')'
3082 ':' hh_type ')' { only_in_hh_syntax(_p);
3083 _p->onTypeList($7, $4);
3084 _p->onTypeAnnotation($$, $2, $7);
3085 _p->onTypeSpecialization($$, 'f'); }
3086 | '(' hh_type ','
3087 hh_non_empty_type_list
3088 possible_comma ')' { only_in_hh_syntax(_p);
3089 _p->onTypeList($2, $4);
3090 Token t; t.reset(); t.setText("array");
3091 _p->onTypeAnnotation($$, t, $2);
3092 _p->onTypeSpecialization($$, 't'); }
3095 hh_type_opt:
3096 hh_type { $$ = $1; }
3097 | { $$.reset(); }
3101 bool Parser::parseImpl() {
3102 return yyparse(this) == 0;