1 %require "3.0" 2 /* 3 +----------------------------------------------------------------------+ 4 | Zend Engine | 5 +----------------------------------------------------------------------+ 6 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | 7 +----------------------------------------------------------------------+ 8 | This source file is subject to version 2.00 of the Zend license, | 9 | that is bundled with this package in the file LICENSE, and is | 10 | available through the world-wide-web at the following url: | 11 | http://www.zend.com/license/2_00.txt. | 12 | If you did not receive a copy of the Zend license and are unable to | 13 | obtain it through the world-wide-web, please send a note to | 14 | license@zend.com so we can mail you a copy immediately. | 15 +----------------------------------------------------------------------+ 16 | Authors: Andi Gutmans <andi@php.net> | 17 | Zeev Suraski <zeev@php.net> | 18 | Nikita Popov <nikic@php.net> | 19 +----------------------------------------------------------------------+ 20 */ 21 22 %code top { 23 #include "zend.h" 24 #include "zend_list.h" 25 #include "zend_globals.h" 26 #include "zend_API.h" 27 #include "zend_constants.h" 28 #include "zend_language_scanner.h" 29 #include "zend_exceptions.h" 30 31 #define YYSIZE_T size_t 32 #define yytnamerr zend_yytnamerr 33 static YYSIZE_T zend_yytnamerr(char*, const char*); 34 35 #ifdef _MSC_VER 36 #define YYMALLOC malloc 37 #define YYFREE free 38 #endif 39 } 40 41 %code requires { 42 #include "zend_compile.h" 43 } 44 45 %define api.prefix {zend} 46 %define api.pure full 47 %define api.value.type {zend_parser_stack_elem} 48 %define parse.error verbose 49 %expect 0 50 51 %destructor { zend_ast_destroy($$); } <ast> 52 %destructor { if ($$) zend_string_release_ex($$, 0); } <str> 53 54 %precedence T_THROW 55 %precedence PREC_ARROW_FUNCTION 56 %precedence T_INCLUDE T_INCLUDE_ONCE T_REQUIRE T_REQUIRE_ONCE 57 %left T_LOGICAL_OR 58 %left T_LOGICAL_XOR 59 %left T_LOGICAL_AND 60 %precedence T_PRINT 61 %precedence T_YIELD 62 %precedence T_DOUBLE_ARROW 63 %precedence T_YIELD_FROM 64 %precedence '=' 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 T_COALESCE_EQUAL 65 %left '?' ':' 66 %right T_COALESCE 67 %left T_BOOLEAN_OR 68 %left T_BOOLEAN_AND 69 %left '|' 70 %left '^' 71 %left T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 72 %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP 73 %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL 74 %left '.' 75 %left T_SL T_SR 76 %left '+' '-' 77 %left '*' '/' '%' 78 %precedence '!' 79 %precedence T_INSTANCEOF 80 %precedence '~' T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' 81 %right T_POW 82 %precedence T_CLONE 83 84 /* Resolve danging else conflict */ 85 %precedence T_NOELSE 86 %precedence T_ELSEIF 87 %precedence T_ELSE 88 89 %token <ast> T_LNUMBER "integer" 90 %token <ast> T_DNUMBER "floating-point number" 91 %token <ast> T_STRING "identifier" 92 %token <ast> T_NAME_FULLY_QUALIFIED "fully qualified name" 93 %token <ast> T_NAME_RELATIVE "namespace-relative name" 94 %token <ast> T_NAME_QUALIFIED "namespaced name" 95 %token <ast> T_VARIABLE "variable" 96 %token <ast> T_INLINE_HTML 97 %token <ast> T_ENCAPSED_AND_WHITESPACE "string content" 98 %token <ast> T_CONSTANT_ENCAPSED_STRING "quoted string" 99 %token <ast> T_STRING_VARNAME "variable name" 100 %token <ast> T_NUM_STRING "number" 101 102 %token <ident> T_INCLUDE "'include'" 103 %token <ident> T_INCLUDE_ONCE "'include_once'" 104 %token <ident> T_EVAL "'eval'" 105 %token <ident> T_REQUIRE "'require'" 106 %token <ident> T_REQUIRE_ONCE "'require_once'" 107 %token <ident> T_LOGICAL_OR "'or'" 108 %token <ident> T_LOGICAL_XOR "'xor'" 109 %token <ident> T_LOGICAL_AND "'and'" 110 %token <ident> T_PRINT "'print'" 111 %token <ident> T_YIELD "'yield'" 112 %token <ident> T_YIELD_FROM "'yield from'" 113 %token <ident> T_INSTANCEOF "'instanceof'" 114 %token <ident> T_NEW "'new'" 115 %token <ident> T_CLONE "'clone'" 116 %token <ident> T_EXIT "'exit'" 117 %token <ident> T_IF "'if'" 118 %token <ident> T_ELSEIF "'elseif'" 119 %token <ident> T_ELSE "'else'" 120 %token <ident> T_ENDIF "'endif'" 121 %token <ident> T_ECHO "'echo'" 122 %token <ident> T_DO "'do'" 123 %token <ident> T_WHILE "'while'" 124 %token <ident> T_ENDWHILE "'endwhile'" 125 %token <ident> T_FOR "'for'" 126 %token <ident> T_ENDFOR "'endfor'" 127 %token <ident> T_FOREACH "'foreach'" 128 %token <ident> T_ENDFOREACH "'endforeach'" 129 %token <ident> T_DECLARE "'declare'" 130 %token <ident> T_ENDDECLARE "'enddeclare'" 131 %token <ident> T_AS "'as'" 132 %token <ident> T_SWITCH "'switch'" 133 %token <ident> T_ENDSWITCH "'endswitch'" 134 %token <ident> T_CASE "'case'" 135 %token <ident> T_DEFAULT "'default'" 136 %token <ident> T_MATCH "'match'" 137 %token <ident> T_BREAK "'break'" 138 %token <ident> T_CONTINUE "'continue'" 139 %token <ident> T_GOTO "'goto'" 140 %token <ident> T_FUNCTION "'function'" 141 %token <ident> T_FN "'fn'" 142 %token <ident> T_CONST "'const'" 143 %token <ident> T_RETURN "'return'" 144 %token <ident> T_TRY "'try'" 145 %token <ident> T_CATCH "'catch'" 146 %token <ident> T_FINALLY "'finally'" 147 %token <ident> T_THROW "'throw'" 148 %token <ident> T_USE "'use'" 149 %token <ident> T_INSTEADOF "'insteadof'" 150 %token <ident> T_GLOBAL "'global'" 151 %token <ident> T_STATIC "'static'" 152 %token <ident> T_ABSTRACT "'abstract'" 153 %token <ident> T_FINAL "'final'" 154 %token <ident> T_PRIVATE "'private'" 155 %token <ident> T_PROTECTED "'protected'" 156 %token <ident> T_PUBLIC "'public'" 157 %token <ident> T_PRIVATE_SET "'private(set)'" 158 %token <ident> T_PROTECTED_SET "'protected(set)'" 159 %token <ident> T_PUBLIC_SET "'public(set)'" 160 %token <ident> T_READONLY "'readonly'" 161 %token <ident> T_VAR "'var'" 162 %token <ident> T_UNSET "'unset'" 163 %token <ident> T_ISSET "'isset'" 164 %token <ident> T_EMPTY "'empty'" 165 %token <ident> T_HALT_COMPILER "'__halt_compiler'" 166 %token <ident> T_CLASS "'class'" 167 %token <ident> T_TRAIT "'trait'" 168 %token <ident> T_INTERFACE "'interface'" 169 %token <ident> T_ENUM "'enum'" 170 %token <ident> T_EXTENDS "'extends'" 171 %token <ident> T_IMPLEMENTS "'implements'" 172 %token <ident> T_NAMESPACE "'namespace'" 173 %token <ident> T_LIST "'list'" 174 %token <ident> T_ARRAY "'array'" 175 %token <ident> T_CALLABLE "'callable'" 176 %token <ident> T_LINE "'__LINE__'" 177 %token <ident> T_FILE "'__FILE__'" 178 %token <ident> T_DIR "'__DIR__'" 179 %token <ident> T_CLASS_C "'__CLASS__'" 180 %token <ident> T_TRAIT_C "'__TRAIT__'" 181 %token <ident> T_METHOD_C "'__METHOD__'" 182 %token <ident> T_FUNC_C "'__FUNCTION__'" 183 %token <ident> T_PROPERTY_C "'__PROPERTY__'" 184 %token <ident> T_NS_C "'__NAMESPACE__'" 185 186 %token END 0 "end of file" 187 %token T_ATTRIBUTE "'#['" 188 %token T_PLUS_EQUAL "'+='" 189 %token T_MINUS_EQUAL "'-='" 190 %token T_MUL_EQUAL "'*='" 191 %token T_DIV_EQUAL "'/='" 192 %token T_CONCAT_EQUAL "'.='" 193 %token T_MOD_EQUAL "'%='" 194 %token T_AND_EQUAL "'&='" 195 %token T_OR_EQUAL "'|='" 196 %token T_XOR_EQUAL "'^='" 197 %token T_SL_EQUAL "'<<='" 198 %token T_SR_EQUAL "'>>='" 199 %token T_COALESCE_EQUAL "'??='" 200 %token T_BOOLEAN_OR "'||'" 201 %token T_BOOLEAN_AND "'&&'" 202 %token T_IS_EQUAL "'=='" 203 %token T_IS_NOT_EQUAL "'!='" 204 %token T_IS_IDENTICAL "'==='" 205 %token T_IS_NOT_IDENTICAL "'!=='" 206 %token T_IS_SMALLER_OR_EQUAL "'<='" 207 %token T_IS_GREATER_OR_EQUAL "'>='" 208 %token T_SPACESHIP "'<=>'" 209 %token T_SL "'<<'" 210 %token T_SR "'>>'" 211 %token T_INC "'++'" 212 %token T_DEC "'--'" 213 %token T_INT_CAST "'(int)'" 214 %token T_DOUBLE_CAST "'(double)'" 215 %token T_STRING_CAST "'(string)'" 216 %token T_ARRAY_CAST "'(array)'" 217 %token T_OBJECT_CAST "'(object)'" 218 %token T_BOOL_CAST "'(bool)'" 219 %token T_UNSET_CAST "'(unset)'" 220 %token T_OBJECT_OPERATOR "'->'" 221 %token T_NULLSAFE_OBJECT_OPERATOR "'?->'" 222 %token T_DOUBLE_ARROW "'=>'" 223 %token T_COMMENT "comment" 224 %token T_DOC_COMMENT "doc comment" 225 %token T_OPEN_TAG "open tag" 226 %token T_OPEN_TAG_WITH_ECHO "'<?='" 227 %token T_CLOSE_TAG "'?>'" 228 %token T_WHITESPACE "whitespace" 229 %token T_START_HEREDOC "heredoc start" 230 %token T_END_HEREDOC "heredoc end" 231 %token T_DOLLAR_OPEN_CURLY_BRACES "'${'" 232 %token T_CURLY_OPEN "'{$'" 233 %token T_PAAMAYIM_NEKUDOTAYIM "'::'" 234 %token T_NS_SEPARATOR "'\\'" 235 %token T_ELLIPSIS "'...'" 236 %token T_COALESCE "'??'" 237 %token T_POW "'**'" 238 %token T_POW_EQUAL "'**='" 239 /* We need to split the & token in two to avoid a shift/reduce conflict. For T1&$v and T1&T2, 240 * with only one token lookahead, bison does not know whether to reduce T1 as a complete type, 241 * or shift to continue parsing an intersection type. */ 242 %token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'" 243 /* Bison warns on duplicate token literals, so use a different dummy value here. 244 * It will be fixed up by zend_yytnamerr() later. */ 245 %token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp" 246 %token T_BAD_CHARACTER "invalid character" 247 248 /* Token used to force a parse error from the lexer */ 249 %token T_ERROR 250 251 %type <ast> top_statement namespace_name name statement function_declaration_statement 252 %type <ast> class_declaration_statement trait_declaration_statement legacy_namespace_name 253 %type <ast> interface_declaration_statement interface_extends_list 254 %type <ast> group_use_declaration inline_use_declarations inline_use_declaration 255 %type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration 256 %type <ast> unprefixed_use_declarations const_decl inner_statement 257 %type <ast> expr optional_expr while_statement for_statement foreach_variable 258 %type <ast> foreach_statement declare_statement finally_statement unset_variable variable 259 %type <ast> extends_from parameter optional_type_without_static argument global_var 260 %type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias 261 %type <ast> absolute_trait_method_reference trait_method_reference property echo_expr 262 %type <ast> new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable 263 %type <ast> internal_functions_in_yacc 264 %type <ast> scalar backticks_expr lexical_var function_call member_name property_name 265 %type <ast> variable_class_name dereferenceable_scalar constant class_constant 266 %type <ast> fully_dereferenceable array_object_dereferenceable 267 %type <ast> callable_expr callable_variable static_member new_variable 268 %type <ast> encaps_var encaps_var_offset isset_variables 269 %type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt 270 %type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list 271 %type <ast> echo_expr_list unset_variables catch_name_list catch_list optional_variable parameter_list class_statement_list 272 %type <ast> implements_list case_list if_stmt_without_else 273 %type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list 274 %type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs 275 %type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars 276 %type <ast> lexical_var_list encaps_list 277 %type <ast> array_pair non_empty_array_pair_list array_pair_list possible_array_pair 278 %type <ast> isset_variable type return_type type_expr type_without_static 279 %type <ast> identifier type_expr_without_static union_type_without_static_element union_type_without_static intersection_type_without_static 280 %type <ast> inline_function union_type_element union_type intersection_type 281 %type <ast> attributed_statement attributed_class_statement attributed_parameter 282 %type <ast> attribute_decl attribute attributes attribute_group namespace_declaration_name 283 %type <ast> match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list 284 %type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr 285 %type <ast> function_name non_empty_member_modifiers 286 %type <ast> property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body 287 %type <ast> optional_parameter_list 288 289 %type <num> returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers 290 %type <num> method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers 291 %type <num> class_modifiers class_modifier anonymous_class_modifiers anonymous_class_modifiers_optional use_type backup_fn_flags 292 293 %type <ptr> backup_lex_pos 294 %type <str> backup_doc_comment 295 296 %type <ident> reserved_non_modifiers semi_reserved 297 298 %% /* Rules */ 299 300 start: 301 top_statement_list { CG(ast) = $1; (void) zendnerrs; } 302 ; 303 304 reserved_non_modifiers: 305 T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND 306 | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE 307 | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY 308 | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO 309 | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK 310 | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS 311 | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM 312 | T_PROPERTY_C 313 ; 314 315 semi_reserved: 316 reserved_non_modifiers 317 | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY 318 ; 319 320 ampersand: 321 T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 322 | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG 323 ; 324 325 identifier: 326 T_STRING { $$ = $1; } 327 | semi_reserved { 328 zval zv; 329 if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; } 330 $$ = zend_ast_create_zval(&zv); 331 } 332 ; 333 334 top_statement_list: 335 top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); } 336 | %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } 337 ; 338 339 /* Name usable in a namespace declaration. */ 340 namespace_declaration_name: 341 identifier { $$ = $1; } 342 | T_NAME_QUALIFIED { $$ = $1; } 343 ; 344 345 /* Name usable in "use" declarations (leading separator forbidden). */ 346 namespace_name: 347 T_STRING { $$ = $1; } 348 | T_NAME_QUALIFIED { $$ = $1; } 349 ; 350 351 /* Name usable in "use" declarations (leading separator allowed). */ 352 legacy_namespace_name: 353 namespace_name { $$ = $1; } 354 | T_NAME_FULLY_QUALIFIED { $$ = $1; } 355 ; 356 357 name: 358 T_STRING { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; } 359 | T_NAME_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; } 360 | T_NAME_FULLY_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_FQ; } 361 | T_NAME_RELATIVE { $$ = $1; $$->attr = ZEND_NAME_RELATIVE; } 362 ; 363 364 attribute_decl: 365 class_name 366 { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL); } 367 | class_name argument_list 368 { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $2); } 369 ; 370 371 attribute_group: 372 attribute_decl 373 { $$ = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_GROUP, $1); } 374 | attribute_group ',' attribute_decl 375 { $$ = zend_ast_list_add($1, $3); } 376 ; 377 378 attribute: 379 T_ATTRIBUTE attribute_group possible_comma ']' { $$ = $2; } 380 ; 381 382 attributes: 383 attribute { $$ = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_LIST, $1); } 384 | attributes attribute { $$ = zend_ast_list_add($1, $2); } 385 ; 386 387 attributed_statement: 388 function_declaration_statement { $$ = $1; } 389 | class_declaration_statement { $$ = $1; } 390 | trait_declaration_statement { $$ = $1; } 391 | interface_declaration_statement { $$ = $1; } 392 | enum_declaration_statement { $$ = $1; } 393 ; 394 395 top_statement: 396 statement { $$ = $1; } 397 | attributed_statement { $$ = $1; } 398 | attributes attributed_statement { $$ = zend_ast_with_attributes($2, $1); } 399 | T_HALT_COMPILER '(' ')' ';' 400 { $$ = zend_ast_create(ZEND_AST_HALT_COMPILER, 401 zend_ast_create_zval_from_long(zend_get_scanned_file_offset())); 402 zend_stop_lexing(); } 403 | T_NAMESPACE namespace_declaration_name ';' 404 { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, NULL); 405 RESET_DOC_COMMENT(); } 406 | T_NAMESPACE namespace_declaration_name { RESET_DOC_COMMENT(); } 407 '{' top_statement_list '}' 408 { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, $5); } 409 | T_NAMESPACE { RESET_DOC_COMMENT(); } 410 '{' top_statement_list '}' 411 { $$ = zend_ast_create(ZEND_AST_NAMESPACE, NULL, $4); } 412 | T_USE mixed_group_use_declaration ';' { $$ = $2; } 413 | T_USE use_type group_use_declaration ';' { $$ = $3; $$->attr = $2; } 414 | T_USE use_declarations ';' { $$ = $2; $$->attr = ZEND_SYMBOL_CLASS; } 415 | T_USE use_type use_declarations ';' { $$ = $3; $$->attr = $2; } 416 | T_CONST const_list ';' { $$ = $2; } 417 ; 418 419 use_type: 420 T_FUNCTION { $$ = ZEND_SYMBOL_FUNCTION; } 421 | T_CONST { $$ = ZEND_SYMBOL_CONST; } 422 ; 423 424 group_use_declaration: 425 legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}' 426 { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4); } 427 ; 428 429 mixed_group_use_declaration: 430 legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}' 431 { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4);} 432 ; 433 434 possible_comma: 435 %empty 436 | ',' 437 ; 438 439 inline_use_declarations: 440 inline_use_declarations ',' inline_use_declaration 441 { $$ = zend_ast_list_add($1, $3); } 442 | inline_use_declaration 443 { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } 444 ; 445 446 unprefixed_use_declarations: 447 unprefixed_use_declarations ',' unprefixed_use_declaration 448 { $$ = zend_ast_list_add($1, $3); } 449 | unprefixed_use_declaration 450 { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } 451 ; 452 453 use_declarations: 454 use_declarations ',' use_declaration 455 { $$ = zend_ast_list_add($1, $3); } 456 | use_declaration 457 { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } 458 ; 459 460 inline_use_declaration: 461 unprefixed_use_declaration { $$ = $1; $$->attr = ZEND_SYMBOL_CLASS; } 462 | use_type unprefixed_use_declaration { $$ = $2; $$->attr = $1; } 463 ; 464 465 unprefixed_use_declaration: 466 namespace_name 467 { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); } 468 | namespace_name T_AS T_STRING 469 { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); } 470 ; 471 472 use_declaration: 473 legacy_namespace_name 474 { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); } 475 | legacy_namespace_name T_AS T_STRING 476 { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); } 477 ; 478 479 const_list: 480 const_list ',' const_decl { $$ = zend_ast_list_add($1, $3); } 481 | const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CONST_DECL, $1); } 482 ; 483 484 inner_statement_list: 485 inner_statement_list inner_statement 486 { $$ = zend_ast_list_add($1, $2); } 487 | %empty 488 { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } 489 ; 490 491 492 inner_statement: 493 statement { $$ = $1; } 494 | attributed_statement { $$ = $1; } 495 | attributes attributed_statement { $$ = zend_ast_with_attributes($2, $1); } 496 | T_HALT_COMPILER '(' ')' ';' 497 { $$ = NULL; zend_throw_exception(zend_ce_compile_error, 498 "__HALT_COMPILER() can only be used from the outermost scope", 0); YYERROR; } 499 ; 500 501 502 statement: 503 '{' inner_statement_list '}' { $$ = $2; } 504 | if_stmt { $$ = $1; } 505 | alt_if_stmt { $$ = $1; } 506 | T_WHILE '(' expr ')' while_statement 507 { $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); } 508 | T_DO statement T_WHILE '(' expr ')' ';' 509 { $$ = zend_ast_create(ZEND_AST_DO_WHILE, $2, $5); } 510 | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement 511 { $$ = zend_ast_create(ZEND_AST_FOR, $3, $5, $7, $9); } 512 | T_SWITCH '(' expr ')' switch_case_list 513 { $$ = zend_ast_create(ZEND_AST_SWITCH, $3, $5); } 514 | T_BREAK optional_expr ';' { $$ = zend_ast_create(ZEND_AST_BREAK, $2); } 515 | T_CONTINUE optional_expr ';' { $$ = zend_ast_create(ZEND_AST_CONTINUE, $2); } 516 | T_RETURN optional_expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); } 517 | T_GLOBAL global_var_list ';' { $$ = $2; } 518 | T_STATIC static_var_list ';' { $$ = $2; } 519 | T_ECHO echo_expr_list ';' { $$ = $2; } 520 | T_INLINE_HTML { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } 521 | expr ';' { $$ = $1; } 522 | T_UNSET '(' unset_variables possible_comma ')' ';' { $$ = $3; } 523 | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement 524 { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $5, NULL, $7); } 525 | T_FOREACH '(' expr T_AS foreach_variable T_DOUBLE_ARROW foreach_variable ')' 526 foreach_statement 527 { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $7, $5, $9); } 528 | T_DECLARE '(' const_list ')' 529 { if (!zend_handle_encoding_declaration($3)) { YYERROR; } } 530 declare_statement 531 { $$ = zend_ast_create(ZEND_AST_DECLARE, $3, $6); } 532 | ';' /* empty statement */ { $$ = NULL; } 533 | T_TRY '{' inner_statement_list '}' catch_list finally_statement 534 { $$ = zend_ast_create(ZEND_AST_TRY, $3, $5, $6); } 535 | T_GOTO T_STRING ';' { $$ = zend_ast_create(ZEND_AST_GOTO, $2); } 536 | T_STRING ':' { $$ = zend_ast_create(ZEND_AST_LABEL, $1); } 537 ; 538 539 catch_list: 540 %empty 541 { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); } 542 | catch_list T_CATCH '(' catch_name_list optional_variable ')' '{' inner_statement_list '}' 543 { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); } 544 ; 545 546 catch_name_list: 547 class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); } 548 | catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); } 549 ; 550 551 optional_variable: 552 %empty { $$ = NULL; } 553 | T_VARIABLE { $$ = $1; } 554 ; 555 556 finally_statement: 557 %empty { $$ = NULL; } 558 | T_FINALLY '{' inner_statement_list '}' { $$ = $3; } 559 ; 560 561 unset_variables: 562 unset_variable { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } 563 | unset_variables ',' unset_variable { $$ = zend_ast_list_add($1, $3); } 564 ; 565 566 unset_variable: 567 variable { $$ = zend_ast_create(ZEND_AST_UNSET, $1); } 568 ; 569 570 function_name: 571 T_STRING { $$ = $1; } 572 | T_READONLY { 573 zval zv; 574 if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; } 575 $$ = zend_ast_create_zval(&zv); 576 } 577 ; 578 579 function_declaration_statement: 580 function returns_ref function_name backup_doc_comment '(' parameter_list ')' return_type 581 backup_fn_flags '{' inner_statement_list '}' backup_fn_flags 582 { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4, 583 zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; } 584 ; 585 586 is_reference: 587 %empty { $$ = 0; } 588 | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG { $$ = ZEND_PARAM_REF; } 589 ; 590 591 is_variadic: 592 %empty { $$ = 0; } 593 | T_ELLIPSIS { $$ = ZEND_PARAM_VARIADIC; } 594 ; 595 596 class_declaration_statement: 597 class_modifiers T_CLASS { $<num>$ = CG(zend_lineno); } 598 T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' 599 { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>3, $7, zend_ast_get_str($4), $5, $6, $9, NULL, NULL); } 600 | T_CLASS { $<num>$ = CG(zend_lineno); } 601 T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' 602 { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $<num>2, $6, zend_ast_get_str($3), $4, $5, $8, NULL, NULL); } 603 ; 604 605 class_modifiers: 606 class_modifier { $$ = $1; } 607 | class_modifiers class_modifier 608 { $$ = zend_add_class_modifier($1, $2); if (!$$) { YYERROR; } } 609 ; 610 611 anonymous_class_modifiers: 612 class_modifier 613 { $$ = zend_add_anonymous_class_modifier(0, $1); if (!$$) { YYERROR; } } 614 | anonymous_class_modifiers class_modifier 615 { $$ = zend_add_anonymous_class_modifier($1, $2); if (!$$) { YYERROR; } } 616 ; 617 618 anonymous_class_modifiers_optional: 619 %empty { $$ = 0; } 620 | anonymous_class_modifiers { $$ = $1; } 621 ; 622 623 class_modifier: 624 T_ABSTRACT { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; } 625 | T_FINAL { $$ = ZEND_ACC_FINAL; } 626 | T_READONLY { $$ = ZEND_ACC_READONLY_CLASS|ZEND_ACC_NO_DYNAMIC_PROPERTIES; } 627 ; 628 629 trait_declaration_statement: 630 T_TRAIT { $<num>$ = CG(zend_lineno); } 631 T_STRING backup_doc_comment '{' class_statement_list '}' 632 { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $<num>2, $4, zend_ast_get_str($3), NULL, NULL, $6, NULL, NULL); } 633 ; 634 635 interface_declaration_statement: 636 T_INTERFACE { $<num>$ = CG(zend_lineno); } 637 T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}' 638 { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $5, zend_ast_get_str($3), NULL, $4, $7, NULL, NULL); } 639 ; 640 641 enum_declaration_statement: 642 T_ENUM { $<num>$ = CG(zend_lineno); } 643 T_STRING enum_backing_type implements_list backup_doc_comment '{' class_statement_list '}' 644 { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_ENUM|ZEND_ACC_FINAL, $<num>2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4); } 645 ; 646 647 enum_backing_type: 648 %empty { $$ = NULL; } 649 | ':' type_expr { $$ = $2; } 650 ; 651 652 enum_case: 653 T_CASE backup_doc_comment identifier enum_case_expr ';' 654 { $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $3, $4, ($2 ? zend_ast_create_zval_from_str($2) : NULL), NULL); } 655 ; 656 657 enum_case_expr: 658 %empty { $$ = NULL; } 659 | '=' expr { $$ = $2; } 660 ; 661 662 extends_from: 663 %empty { $$ = NULL; } 664 | T_EXTENDS class_name { $$ = $2; } 665 ; 666 667 interface_extends_list: 668 %empty { $$ = NULL; } 669 | T_EXTENDS class_name_list { $$ = $2; } 670 ; 671 672 implements_list: 673 %empty { $$ = NULL; } 674 | T_IMPLEMENTS class_name_list { $$ = $2; } 675 ; 676 677 foreach_variable: 678 variable { $$ = $1; } 679 | ampersand variable { $$ = zend_ast_create(ZEND_AST_REF, $2); } 680 | T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; } 681 | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; } 682 ; 683 684 for_statement: 685 statement { $$ = $1; } 686 | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } 687 ; 688 689 foreach_statement: 690 statement { $$ = $1; } 691 | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } 692 ; 693 694 declare_statement: 695 statement { $$ = $1; } 696 | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } 697 ; 698 699 switch_case_list: 700 '{' case_list '}' { $$ = $2; } 701 | '{' ';' case_list '}' { $$ = $3; } 702 | ':' case_list T_ENDSWITCH ';' { $$ = $2; } 703 | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } 704 ; 705 706 case_list: 707 %empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } 708 | case_list T_CASE expr case_separator inner_statement_list 709 { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); } 710 | case_list T_DEFAULT case_separator inner_statement_list 711 { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); } 712 ; 713 714 case_separator: 715 ':' 716 | ';' 717 ; 718 719 720 match: 721 T_MATCH '(' expr ')' '{' match_arm_list '}' 722 { $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); }; 723 ; 724 725 match_arm_list: 726 %empty { $$ = zend_ast_create_list(0, ZEND_AST_MATCH_ARM_LIST); } 727 | non_empty_match_arm_list possible_comma { $$ = $1; } 728 ; 729 730 non_empty_match_arm_list: 731 match_arm { $$ = zend_ast_create_list(1, ZEND_AST_MATCH_ARM_LIST, $1); } 732 | non_empty_match_arm_list ',' match_arm { $$ = zend_ast_list_add($1, $3); } 733 ; 734 735 match_arm: 736 match_arm_cond_list possible_comma T_DOUBLE_ARROW expr 737 { $$ = zend_ast_create(ZEND_AST_MATCH_ARM, $1, $4); } 738 | T_DEFAULT possible_comma T_DOUBLE_ARROW expr 739 { $$ = zend_ast_create(ZEND_AST_MATCH_ARM, NULL, $4); } 740 ; 741 742 match_arm_cond_list: 743 expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); } 744 | match_arm_cond_list ',' expr { $$ = zend_ast_list_add($1, $3); } 745 ; 746 747 748 while_statement: 749 statement { $$ = $1; } 750 | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } 751 ; 752 753 754 if_stmt_without_else: 755 T_IF '(' expr ')' statement 756 { $$ = zend_ast_create_list(1, ZEND_AST_IF, 757 zend_ast_create(ZEND_AST_IF_ELEM, $3, $5)); } 758 | if_stmt_without_else T_ELSEIF '(' expr ')' statement 759 { $$ = zend_ast_list_add($1, 760 zend_ast_create(ZEND_AST_IF_ELEM, $4, $6)); } 761 ; 762 763 if_stmt: 764 if_stmt_without_else %prec T_NOELSE { $$ = $1; } 765 | if_stmt_without_else T_ELSE statement 766 { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_IF_ELEM, NULL, $3)); } 767 ; 768 769 alt_if_stmt_without_else: 770 T_IF '(' expr ')' ':' inner_statement_list 771 { $$ = zend_ast_create_list(1, ZEND_AST_IF, 772 zend_ast_create(ZEND_AST_IF_ELEM, $3, $6)); } 773 | alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list 774 { $$ = zend_ast_list_add($1, 775 zend_ast_create(ZEND_AST_IF_ELEM, $4, $7)); } 776 ; 777 778 alt_if_stmt: 779 alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; } 780 | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';' 781 { $$ = zend_ast_list_add($1, 782 zend_ast_create(ZEND_AST_IF_ELEM, NULL, $4)); } 783 ; 784 785 parameter_list: 786 non_empty_parameter_list possible_comma { $$ = $1; } 787 | %empty { $$ = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); } 788 ; 789 790 791 non_empty_parameter_list: 792 attributed_parameter 793 { $$ = zend_ast_create_list(1, ZEND_AST_PARAM_LIST, $1); } 794 | non_empty_parameter_list ',' attributed_parameter 795 { $$ = zend_ast_list_add($1, $3); } 796 ; 797 798 attributed_parameter: 799 attributes parameter { $$ = zend_ast_with_attributes($2, $1); } 800 | parameter { $$ = $1; } 801 ; 802 803 optional_cpp_modifiers: 804 %empty 805 { $$ = 0; } 806 | non_empty_member_modifiers 807 { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_CPP, $1); 808 if (!$$) { YYERROR; } } 809 ; 810 811 parameter: 812 optional_cpp_modifiers optional_type_without_static 813 is_reference is_variadic T_VARIABLE backup_doc_comment optional_property_hook_list 814 { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, NULL, 815 NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $7); } 816 | optional_cpp_modifiers optional_type_without_static 817 is_reference is_variadic T_VARIABLE backup_doc_comment '=' expr optional_property_hook_list 818 { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $8, 819 NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $9); } 820 ; 821 822 optional_type_without_static: 823 %empty { $$ = NULL; } 824 | type_expr_without_static { $$ = $1; } 825 ; 826 827 type_expr: 828 type { $$ = $1; } 829 | '?' type { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; } 830 | union_type { $$ = $1; } 831 | intersection_type { $$ = $1; } 832 ; 833 834 type: 835 type_without_static { $$ = $1; } 836 | T_STATIC { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC); } 837 ; 838 839 union_type_element: 840 type { $$ = $1; } 841 | '(' intersection_type ')' { $$ = $2; } 842 ; 843 844 union_type: 845 union_type_element '|' union_type_element 846 { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_UNION, $1, $3); } 847 | union_type '|' union_type_element 848 { $$ = zend_ast_list_add($1, $3); } 849 ; 850 851 intersection_type: 852 type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_INTERSECTION, $1, $3); } 853 | intersection_type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type { $$ = zend_ast_list_add($1, $3); } 854 ; 855 856 /* Duplicate the type rules without "static", 857 * to avoid conflicts with "static" modifier for properties. */ 858 859 type_expr_without_static: 860 type_without_static { $$ = $1; } 861 | '?' type_without_static { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; } 862 | union_type_without_static { $$ = $1; } 863 | intersection_type_without_static { $$ = $1; } 864 ; 865 866 type_without_static: 867 T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); } 868 | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); } 869 | name { $$ = $1; } 870 ; 871 872 union_type_without_static_element: 873 type_without_static { $$ = $1; } 874 | '(' intersection_type_without_static ')' { $$ = $2; } 875 ; 876 877 union_type_without_static: 878 union_type_without_static_element '|' union_type_without_static_element 879 { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_UNION, $1, $3); } 880 | union_type_without_static '|' union_type_without_static_element 881 { $$ = zend_ast_list_add($1, $3); } 882 ; 883 884 intersection_type_without_static: 885 type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static 886 { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_INTERSECTION, $1, $3); } 887 | intersection_type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static 888 { $$ = zend_ast_list_add($1, $3); } 889 ; 890 891 return_type: 892 %empty { $$ = NULL; } 893 | ':' type_expr { $$ = $2; } 894 ; 895 896 argument_list: 897 '(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } 898 | '(' non_empty_argument_list possible_comma ')' { $$ = $2; } 899 | '(' T_ELLIPSIS ')' { $$ = zend_ast_create(ZEND_AST_CALLABLE_CONVERT); } 900 ; 901 902 non_empty_argument_list: 903 argument 904 { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); } 905 | non_empty_argument_list ',' argument 906 { $$ = zend_ast_list_add($1, $3); } 907 ; 908 909 argument: 910 expr { $$ = $1; } 911 | identifier ':' expr 912 { $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); } 913 | T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); } 914 ; 915 916 global_var_list: 917 global_var_list ',' global_var { $$ = zend_ast_list_add($1, $3); } 918 | global_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } 919 ; 920 921 global_var: 922 simple_variable 923 { $$ = zend_ast_create(ZEND_AST_GLOBAL, zend_ast_create(ZEND_AST_VAR, $1)); } 924 ; 925 926 927 static_var_list: 928 static_var_list ',' static_var { $$ = zend_ast_list_add($1, $3); } 929 | static_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } 930 ; 931 932 static_var: 933 T_VARIABLE { $$ = zend_ast_create(ZEND_AST_STATIC, $1, NULL); } 934 | T_VARIABLE '=' expr { $$ = zend_ast_create(ZEND_AST_STATIC, $1, $3); } 935 ; 936 937 class_statement_list: 938 class_statement_list class_statement 939 { $$ = zend_ast_list_add($1, $2); } 940 | %empty 941 { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } 942 ; 943 944 945 attributed_class_statement: 946 property_modifiers optional_type_without_static property_list ';' 947 { $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, $3, NULL); 948 $$->attr = $1; } 949 | property_modifiers optional_type_without_static hooked_property 950 { $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, zend_ast_create_list(1, ZEND_AST_PROP_DECL, $3), NULL); 951 $$->attr = $1; } 952 | class_const_modifiers T_CONST class_const_list ';' 953 { $$ = zend_ast_create(ZEND_AST_CLASS_CONST_GROUP, $3, NULL, NULL); 954 $$->attr = $1; } 955 | class_const_modifiers T_CONST type_expr class_const_list ';' 956 { $$ = zend_ast_create(ZEND_AST_CLASS_CONST_GROUP, $4, NULL, $3); 957 $$->attr = $1; } 958 | method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')' 959 return_type backup_fn_flags method_body backup_fn_flags 960 { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5, 961 zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; } 962 | enum_case { $$ = $1; } 963 ; 964 965 class_statement: 966 attributed_class_statement { $$ = $1; } 967 | attributes attributed_class_statement { $$ = zend_ast_with_attributes($2, $1); } 968 | T_USE class_name_list trait_adaptations 969 { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); } 970 ; 971 972 class_name_list: 973 class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); } 974 | class_name_list ',' class_name { $$ = zend_ast_list_add($1, $3); } 975 ; 976 977 trait_adaptations: 978 ';' { $$ = NULL; } 979 | '{' '}' { $$ = NULL; } 980 | '{' trait_adaptation_list '}' { $$ = $2; } 981 ; 982 983 trait_adaptation_list: 984 trait_adaptation 985 { $$ = zend_ast_create_list(1, ZEND_AST_TRAIT_ADAPTATIONS, $1); } 986 | trait_adaptation_list trait_adaptation 987 { $$ = zend_ast_list_add($1, $2); } 988 ; 989 990 trait_adaptation: 991 trait_precedence ';' { $$ = $1; } 992 | trait_alias ';' { $$ = $1; } 993 ; 994 995 trait_precedence: 996 absolute_trait_method_reference T_INSTEADOF class_name_list 997 { $$ = zend_ast_create(ZEND_AST_TRAIT_PRECEDENCE, $1, $3); } 998 ; 999 1000 trait_alias: 1001 trait_method_reference T_AS T_STRING 1002 { $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, $3); } 1003 | trait_method_reference T_AS reserved_non_modifiers 1004 { zval zv; 1005 if (zend_lex_tstring(&zv, $3) == FAILURE) { YYABORT; } 1006 $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&zv)); } 1007 | trait_method_reference T_AS member_modifier identifier 1008 { uint32_t modifiers = zend_modifier_token_to_flag(ZEND_MODIFIER_TARGET_METHOD, $3); 1009 $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, modifiers, $1, $4); 1010 /* identifier nonterminal can cause allocations, so we need to free the node */ 1011 if (!modifiers) { zend_ast_destroy($$); YYERROR; } } 1012 | trait_method_reference T_AS member_modifier 1013 { uint32_t modifiers = zend_modifier_token_to_flag(ZEND_MODIFIER_TARGET_METHOD, $3); 1014 $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, modifiers, $1, NULL); 1015 /* identifier nonterminal can cause allocations, so we need to free the node */ 1016 if (!modifiers) { zend_ast_destroy($$); YYERROR; } } 1017 ; 1018 1019 trait_method_reference: 1020 identifier 1021 { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); } 1022 | absolute_trait_method_reference { $$ = $1; } 1023 ; 1024 1025 absolute_trait_method_reference: 1026 class_name T_PAAMAYIM_NEKUDOTAYIM identifier 1027 { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); } 1028 ; 1029 1030 method_body: 1031 ';' /* abstract method */ { $$ = NULL; } 1032 | '{' inner_statement_list '}' { $$ = $2; } 1033 ; 1034 1035 property_modifiers: 1036 non_empty_member_modifiers 1037 { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_PROPERTY, $1); 1038 if (!$$) { YYERROR; } } 1039 | T_VAR 1040 { $$ = ZEND_ACC_PUBLIC; } 1041 ; 1042 1043 method_modifiers: 1044 %empty 1045 { $$ = ZEND_ACC_PUBLIC; } 1046 | non_empty_member_modifiers 1047 { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_METHOD, $1); 1048 if (!$$) { YYERROR; } 1049 if (!($$ & ZEND_ACC_PPP_MASK)) { $$ |= ZEND_ACC_PUBLIC; } } 1050 ; 1051 1052 class_const_modifiers: 1053 %empty 1054 { $$ = ZEND_ACC_PUBLIC; } 1055 | non_empty_member_modifiers 1056 { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_CONSTANT, $1); 1057 if (!$$) { YYERROR; } 1058 if (!($$ & ZEND_ACC_PPP_MASK)) { $$ |= ZEND_ACC_PUBLIC; } } 1059 ; 1060 1061 non_empty_member_modifiers: 1062 member_modifier 1063 { $$ = zend_ast_create_list(1, ZEND_AST_MODIFIER_LIST, zend_ast_create_zval_from_long($1)); } 1064 | non_empty_member_modifiers member_modifier 1065 { $$ = zend_ast_list_add($1, zend_ast_create_zval_from_long($2)); } 1066 ; 1067 1068 member_modifier: 1069 T_PUBLIC { $$ = T_PUBLIC; } 1070 | T_PROTECTED { $$ = T_PROTECTED; } 1071 | T_PRIVATE { $$ = T_PRIVATE; } 1072 | T_PUBLIC_SET { $$ = T_PUBLIC_SET; } 1073 | T_PROTECTED_SET { $$ = T_PROTECTED_SET; } 1074 | T_PRIVATE_SET { $$ = T_PRIVATE_SET; } 1075 | T_STATIC { $$ = T_STATIC; } 1076 | T_ABSTRACT { $$ = T_ABSTRACT; } 1077 | T_FINAL { $$ = T_FINAL; } 1078 | T_READONLY { $$ = T_READONLY; } 1079 ; 1080 1081 property_list: 1082 property_list ',' property { $$ = zend_ast_list_add($1, $3); } 1083 | property { $$ = zend_ast_create_list(1, ZEND_AST_PROP_DECL, $1); } 1084 ; 1085 1086 property: 1087 T_VARIABLE backup_doc_comment 1088 { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str($2) : NULL), NULL); } 1089 | T_VARIABLE '=' expr backup_doc_comment 1090 { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL), NULL); } 1091 ; 1092 1093 hooked_property: 1094 T_VARIABLE backup_doc_comment '{' property_hook_list '}' 1095 { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str($2) : NULL), $4); } 1096 | T_VARIABLE '=' expr backup_doc_comment '{' property_hook_list '}' 1097 { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL), $6); } 1098 ; 1099 1100 property_hook_list: 1101 %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } 1102 | property_hook_list property_hook { $$ = zend_ast_list_add($1, $2); } 1103 | property_hook_list attributes property_hook { 1104 $$ = zend_ast_list_add($1, zend_ast_with_attributes($3, $2)); 1105 } 1106 ; 1107 1108 optional_property_hook_list: 1109 %empty { $$ = NULL; } 1110 | '{' property_hook_list '}' { $$ = $2; } 1111 ; 1112 1113 property_hook_modifiers: 1114 %empty { $$ = 0; } 1115 | non_empty_member_modifiers { 1116 $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_PROPERTY_HOOK, $1); 1117 if (!$$) { YYERROR; } 1118 } 1119 ; 1120 1121 property_hook: 1122 property_hook_modifiers returns_ref T_STRING 1123 backup_doc_comment { $<num>$ = CG(zend_lineno); } 1124 optional_parameter_list backup_fn_flags property_hook_body backup_fn_flags { 1125 $$ = zend_ast_create_decl( 1126 ZEND_AST_PROPERTY_HOOK, $1 | $2 | $9, $<num>5, $4, zend_ast_get_str($3), 1127 $6, NULL, $8, NULL, NULL); 1128 CG(extra_fn_flags) = $7; 1129 } 1130 ; 1131 1132 property_hook_body: 1133 ';' { $$ = NULL; } 1134 | '{' inner_statement_list '}' { $$ = $2; } 1135 | T_DOUBLE_ARROW expr ';' 1136 { $$ = zend_ast_create(ZEND_AST_PROPERTY_HOOK_SHORT_BODY, $2); } 1137 ; 1138 1139 optional_parameter_list: 1140 %empty { $$ = NULL; } 1141 | '(' parameter_list ')' { $$ = $2; } 1142 ; 1143 1144 class_const_list: 1145 class_const_list ',' class_const_decl { $$ = zend_ast_list_add($1, $3); } 1146 | class_const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); } 1147 ; 1148 1149 class_const_decl: 1150 T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } 1151 | semi_reserved '=' expr backup_doc_comment { 1152 zval zv; 1153 if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; } 1154 $$ = zend_ast_create(ZEND_AST_CONST_ELEM, zend_ast_create_zval(&zv), $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); 1155 } 1156 ; 1157 1158 const_decl: 1159 T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } 1160 ; 1161 1162 echo_expr_list: 1163 echo_expr_list ',' echo_expr { $$ = zend_ast_list_add($1, $3); } 1164 | echo_expr { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } 1165 ; 1166 echo_expr: 1167 expr { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } 1168 ; 1169 1170 for_exprs: 1171 %empty { $$ = NULL; } 1172 | non_empty_for_exprs { $$ = $1; } 1173 ; 1174 1175 non_empty_for_exprs: 1176 non_empty_for_exprs ',' expr { $$ = zend_ast_list_add($1, $3); } 1177 | expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); } 1178 ; 1179 1180 anonymous_class: 1181 anonymous_class_modifiers_optional T_CLASS { $<num>$ = CG(zend_lineno); } ctor_arguments 1182 extends_from implements_list backup_doc_comment '{' class_statement_list '}' { 1183 zend_ast *decl = zend_ast_create_decl( 1184 ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS | $1, $<num>3, $7, NULL, 1185 $5, $6, $9, NULL, NULL); 1186 $$ = zend_ast_create(ZEND_AST_NEW, decl, $4); 1187 } 1188 ; 1189 1190 new_dereferenceable: 1191 T_NEW class_name_reference argument_list 1192 { $$ = zend_ast_create(ZEND_AST_NEW, $2, $3); } 1193 | T_NEW anonymous_class 1194 { $$ = $2; } 1195 | T_NEW attributes anonymous_class 1196 { zend_ast_with_attributes($3->child[0], $2); $$ = $3; } 1197 ; 1198 1199 new_non_dereferenceable: 1200 T_NEW class_name_reference 1201 { $$ = zend_ast_create(ZEND_AST_NEW, $2, zend_ast_create_list(0, ZEND_AST_ARG_LIST)); } 1202 ; 1203 1204 expr: 1205 variable 1206 { $$ = $1; } 1207 | T_LIST '(' array_pair_list ')' '=' expr 1208 { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); } 1209 | '[' array_pair_list ']' '=' expr 1210 { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); } 1211 | variable '=' expr 1212 { $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); } 1213 | variable '=' ampersand variable 1214 { $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); } 1215 | T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); } 1216 | variable T_PLUS_EQUAL expr 1217 { $$ = zend_ast_create_assign_op(ZEND_ADD, $1, $3); } 1218 | variable T_MINUS_EQUAL expr 1219 { $$ = zend_ast_create_assign_op(ZEND_SUB, $1, $3); } 1220 | variable T_MUL_EQUAL expr 1221 { $$ = zend_ast_create_assign_op(ZEND_MUL, $1, $3); } 1222 | variable T_POW_EQUAL expr 1223 { $$ = zend_ast_create_assign_op(ZEND_POW, $1, $3); } 1224 | variable T_DIV_EQUAL expr 1225 { $$ = zend_ast_create_assign_op(ZEND_DIV, $1, $3); } 1226 | variable T_CONCAT_EQUAL expr 1227 { $$ = zend_ast_create_assign_op(ZEND_CONCAT, $1, $3); } 1228 | variable T_MOD_EQUAL expr 1229 { $$ = zend_ast_create_assign_op(ZEND_MOD, $1, $3); } 1230 | variable T_AND_EQUAL expr 1231 { $$ = zend_ast_create_assign_op(ZEND_BW_AND, $1, $3); } 1232 | variable T_OR_EQUAL expr 1233 { $$ = zend_ast_create_assign_op(ZEND_BW_OR, $1, $3); } 1234 | variable T_XOR_EQUAL expr 1235 { $$ = zend_ast_create_assign_op(ZEND_BW_XOR, $1, $3); } 1236 | variable T_SL_EQUAL expr 1237 { $$ = zend_ast_create_assign_op(ZEND_SL, $1, $3); } 1238 | variable T_SR_EQUAL expr 1239 { $$ = zend_ast_create_assign_op(ZEND_SR, $1, $3); } 1240 | variable T_COALESCE_EQUAL expr 1241 { $$ = zend_ast_create(ZEND_AST_ASSIGN_COALESCE, $1, $3); } 1242 | variable T_INC { $$ = zend_ast_create(ZEND_AST_POST_INC, $1); } 1243 | T_INC variable { $$ = zend_ast_create(ZEND_AST_PRE_INC, $2); } 1244 | variable T_DEC { $$ = zend_ast_create(ZEND_AST_POST_DEC, $1); } 1245 | T_DEC variable { $$ = zend_ast_create(ZEND_AST_PRE_DEC, $2); } 1246 | expr T_BOOLEAN_OR expr 1247 { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); } 1248 | expr T_BOOLEAN_AND expr 1249 { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } 1250 | expr T_LOGICAL_OR expr 1251 { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); } 1252 | expr T_LOGICAL_AND expr 1253 { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } 1254 | expr T_LOGICAL_XOR expr 1255 { $$ = zend_ast_create_binary_op(ZEND_BOOL_XOR, $1, $3); } 1256 | expr '|' expr { $$ = zend_ast_create_binary_op(ZEND_BW_OR, $1, $3); } 1257 | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } 1258 | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } 1259 | expr '^' expr { $$ = zend_ast_create_binary_op(ZEND_BW_XOR, $1, $3); } 1260 | expr '.' expr { $$ = zend_ast_create_concat_op($1, $3); } 1261 | expr '+' expr { $$ = zend_ast_create_binary_op(ZEND_ADD, $1, $3); } 1262 | expr '-' expr { $$ = zend_ast_create_binary_op(ZEND_SUB, $1, $3); } 1263 | expr '*' expr { $$ = zend_ast_create_binary_op(ZEND_MUL, $1, $3); } 1264 | expr T_POW expr { $$ = zend_ast_create_binary_op(ZEND_POW, $1, $3); } 1265 | expr '/' expr { $$ = zend_ast_create_binary_op(ZEND_DIV, $1, $3); } 1266 | expr '%' expr { $$ = zend_ast_create_binary_op(ZEND_MOD, $1, $3); } 1267 | expr T_SL expr { $$ = zend_ast_create_binary_op(ZEND_SL, $1, $3); } 1268 | expr T_SR expr { $$ = zend_ast_create_binary_op(ZEND_SR, $1, $3); } 1269 | '+' expr %prec '~' { $$ = zend_ast_create(ZEND_AST_UNARY_PLUS, $2); } 1270 | '-' expr %prec '~' { $$ = zend_ast_create(ZEND_AST_UNARY_MINUS, $2); } 1271 | '!' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, $2); } 1272 | '~' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BW_NOT, $2); } 1273 | expr T_IS_IDENTICAL expr 1274 { $$ = zend_ast_create_binary_op(ZEND_IS_IDENTICAL, $1, $3); } 1275 | expr T_IS_NOT_IDENTICAL expr 1276 { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_IDENTICAL, $1, $3); } 1277 | expr T_IS_EQUAL expr 1278 { $$ = zend_ast_create_binary_op(ZEND_IS_EQUAL, $1, $3); } 1279 | expr T_IS_NOT_EQUAL expr 1280 { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_EQUAL, $1, $3); } 1281 | expr '<' expr 1282 { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER, $1, $3); } 1283 | expr T_IS_SMALLER_OR_EQUAL expr 1284 { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER_OR_EQUAL, $1, $3); } 1285 | expr '>' expr 1286 { $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); } 1287 | expr T_IS_GREATER_OR_EQUAL expr 1288 { $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); } 1289 | expr T_SPACESHIP expr 1290 { $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); } 1291 | expr T_INSTANCEOF class_name_reference 1292 { $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); } 1293 | '(' expr ')' { 1294 $$ = $2; 1295 if ($$->kind == ZEND_AST_CONDITIONAL) $$->attr = ZEND_PARENTHESIZED_CONDITIONAL; 1296 } 1297 | new_dereferenceable { $$ = $1; } 1298 | new_non_dereferenceable { $$ = $1; } 1299 | expr '?' expr ':' expr 1300 { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); } 1301 | expr '?' ':' expr 1302 { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, NULL, $4); } 1303 | expr T_COALESCE expr 1304 { $$ = zend_ast_create(ZEND_AST_COALESCE, $1, $3); } 1305 | internal_functions_in_yacc { $$ = $1; } 1306 | T_INT_CAST expr { $$ = zend_ast_create_cast(IS_LONG, $2); } 1307 | T_DOUBLE_CAST expr { $$ = zend_ast_create_cast(IS_DOUBLE, $2); } 1308 | T_STRING_CAST expr { $$ = zend_ast_create_cast(IS_STRING, $2); } 1309 | T_ARRAY_CAST expr { $$ = zend_ast_create_cast(IS_ARRAY, $2); } 1310 | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); } 1311 | T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); } 1312 | T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); } 1313 | T_EXIT ctor_arguments { 1314 zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_EXIT)); 1315 name->attr = ZEND_NAME_FQ; 1316 $$ = zend_ast_create(ZEND_AST_CALL, name, $2); 1317 } 1318 | '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); } 1319 | scalar { $$ = $1; } 1320 | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); } 1321 | T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); } 1322 | T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } 1323 | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } 1324 | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } 1325 | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } 1326 | T_THROW expr { $$ = zend_ast_create(ZEND_AST_THROW, $2); } 1327 | inline_function { $$ = $1; } 1328 | attributes inline_function { $$ = zend_ast_with_attributes($2, $1); } 1329 | T_STATIC inline_function { $$ = $2; ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; } 1330 | attributes T_STATIC inline_function 1331 { $$ = zend_ast_with_attributes($3, $1); ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; } 1332 | match { $$ = $1; } 1333 ; 1334 1335 1336 inline_function: 1337 function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type 1338 backup_fn_flags '{' inner_statement_list '}' backup_fn_flags 1339 { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3, 1340 NULL, 1341 $5, $7, $11, $8, NULL); CG(extra_fn_flags) = $9; } 1342 | fn returns_ref backup_doc_comment '(' parameter_list ')' return_type 1343 T_DOUBLE_ARROW backup_fn_flags backup_lex_pos expr backup_fn_flags 1344 { $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $12, $1, $3, 1345 NULL, $5, NULL, $11, $7, NULL); 1346 CG(extra_fn_flags) = $9; } 1347 ; 1348 1349 fn: 1350 T_FN { $$ = CG(zend_lineno); } 1351 ; 1352 1353 function: 1354 T_FUNCTION { $$ = CG(zend_lineno); } 1355 ; 1356 1357 backup_doc_comment: 1358 %empty { $$ = CG(doc_comment); CG(doc_comment) = NULL; } 1359 ; 1360 1361 backup_fn_flags: 1362 %prec PREC_ARROW_FUNCTION %empty { $$ = CG(extra_fn_flags); CG(extra_fn_flags) = 0; } 1363 ; 1364 1365 backup_lex_pos: 1366 %empty { $$ = LANG_SCNG(yy_text); } 1367 ; 1368 1369 returns_ref: 1370 %empty { $$ = 0; } 1371 | ampersand { $$ = ZEND_ACC_RETURN_REFERENCE; } 1372 ; 1373 1374 lexical_vars: 1375 %empty { $$ = NULL; } 1376 | T_USE '(' lexical_var_list possible_comma ')' { $$ = $3; } 1377 ; 1378 1379 lexical_var_list: 1380 lexical_var_list ',' lexical_var { $$ = zend_ast_list_add($1, $3); } 1381 | lexical_var { $$ = zend_ast_create_list(1, ZEND_AST_CLOSURE_USES, $1); } 1382 ; 1383 1384 lexical_var: 1385 T_VARIABLE { $$ = $1; } 1386 | ampersand T_VARIABLE { $$ = $2; $$->attr = ZEND_BIND_REF; } 1387 ; 1388 1389 function_call: 1390 name argument_list 1391 { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); } 1392 | T_READONLY argument_list { 1393 zval zv; 1394 if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; } 1395 $$ = zend_ast_create(ZEND_AST_CALL, zend_ast_create_zval(&zv), $2); 1396 } 1397 | class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list 1398 { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); } 1399 | variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list 1400 { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); } 1401 | callable_expr { $<num>$ = CG(zend_lineno); } argument_list { 1402 $$ = zend_ast_create(ZEND_AST_CALL, $1, $3); 1403 $$->lineno = $<num>2; 1404 } 1405 ; 1406 1407 class_name: 1408 T_STATIC 1409 { zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_STATIC)); 1410 $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); } 1411 | name { $$ = $1; } 1412 ; 1413 1414 class_name_reference: 1415 class_name { $$ = $1; } 1416 | new_variable { $$ = $1; } 1417 | '(' expr ')' { $$ = $2; } 1418 ; 1419 1420 backticks_expr: 1421 %empty 1422 { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } 1423 | T_ENCAPSED_AND_WHITESPACE { $$ = $1; } 1424 | encaps_list { $$ = $1; } 1425 ; 1426 1427 1428 ctor_arguments: 1429 %empty { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } 1430 | argument_list { $$ = $1; } 1431 ; 1432 1433 1434 dereferenceable_scalar: 1435 T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; } 1436 | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; } 1437 | T_CONSTANT_ENCAPSED_STRING { $$ = $1; } 1438 | '"' encaps_list '"' { $$ = $2; } 1439 ; 1440 1441 scalar: 1442 T_LNUMBER { $$ = $1; } 1443 | T_DNUMBER { $$ = $1; } 1444 | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; } 1445 | T_START_HEREDOC T_END_HEREDOC 1446 { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } 1447 | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; } 1448 | dereferenceable_scalar { $$ = $1; } 1449 | constant { $$ = $1; } 1450 | class_constant { $$ = $1; } 1451 ; 1452 1453 constant: 1454 name { $$ = zend_ast_create(ZEND_AST_CONST, $1); } 1455 | T_LINE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_LINE); } 1456 | T_FILE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FILE); } 1457 | T_DIR { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_DIR); } 1458 | T_TRAIT_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_TRAIT_C); } 1459 | T_METHOD_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_METHOD_C); } 1460 | T_FUNC_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FUNC_C); } 1461 | T_PROPERTY_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_PROPERTY_C); } 1462 | T_NS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_NS_C); } 1463 | T_CLASS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_CLASS_C); } 1464 ; 1465 1466 class_constant: 1467 class_name T_PAAMAYIM_NEKUDOTAYIM identifier 1468 { $$ = zend_ast_create_class_const_or_name($1, $3); } 1469 | variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier 1470 { $$ = zend_ast_create_class_const_or_name($1, $3); } 1471 | class_name T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' 1472 { $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $4); } 1473 | variable_class_name T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' 1474 { $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $4); } 1475 ; 1476 1477 optional_expr: 1478 %empty { $$ = NULL; } 1479 | expr { $$ = $1; } 1480 ; 1481 1482 variable_class_name: 1483 fully_dereferenceable { $$ = $1; } 1484 ; 1485 1486 fully_dereferenceable: 1487 variable { $$ = $1; } 1488 | '(' expr ')' { 1489 $$ = $2; 1490 if ($$->kind == ZEND_AST_STATIC_PROP) $$->attr = ZEND_PARENTHESIZED_STATIC_PROP; 1491 } 1492 | dereferenceable_scalar { $$ = $1; } 1493 | class_constant { $$ = $1; } 1494 | new_dereferenceable { $$ = $1; } 1495 ; 1496 1497 array_object_dereferenceable: 1498 fully_dereferenceable { $$ = $1; } 1499 | constant { $$ = $1; } 1500 ; 1501 1502 callable_expr: 1503 callable_variable { $$ = $1; } 1504 | '(' expr ')' { $$ = $2; } 1505 | dereferenceable_scalar { $$ = $1; } 1506 | new_dereferenceable { $$ = $1; } 1507 ; 1508 1509 callable_variable: 1510 simple_variable 1511 { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1512 | array_object_dereferenceable '[' optional_expr ']' 1513 { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } 1514 | array_object_dereferenceable T_OBJECT_OPERATOR property_name argument_list 1515 { $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); } 1516 | array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list 1517 { $$ = zend_ast_create(ZEND_AST_NULLSAFE_METHOD_CALL, $1, $3, $4); } 1518 | function_call { $$ = $1; } 1519 ; 1520 1521 variable: 1522 callable_variable 1523 { $$ = $1; } 1524 | static_member 1525 { $$ = $1; } 1526 | array_object_dereferenceable T_OBJECT_OPERATOR property_name 1527 { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); } 1528 | array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name 1529 { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP, $1, $3); } 1530 ; 1531 1532 simple_variable: 1533 T_VARIABLE { $$ = $1; } 1534 | '$' '{' expr '}' { $$ = $3; } 1535 | '$' simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $2); } 1536 ; 1537 1538 static_member: 1539 class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable 1540 { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } 1541 | variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable 1542 { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } 1543 ; 1544 1545 new_variable: 1546 simple_variable 1547 { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1548 | new_variable '[' optional_expr ']' 1549 { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } 1550 | new_variable T_OBJECT_OPERATOR property_name 1551 { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); } 1552 | new_variable T_NULLSAFE_OBJECT_OPERATOR property_name 1553 { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP, $1, $3); } 1554 | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable 1555 { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } 1556 | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable 1557 { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } 1558 ; 1559 1560 member_name: 1561 identifier { $$ = $1; } 1562 | '{' expr '}' { $$ = $2; } 1563 | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1564 ; 1565 1566 property_name: 1567 T_STRING { $$ = $1; } 1568 | '{' expr '}' { $$ = $2; } 1569 | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1570 ; 1571 1572 array_pair_list: 1573 non_empty_array_pair_list 1574 { /* allow single trailing comma */ $$ = zend_ast_list_rtrim($1); } 1575 ; 1576 1577 possible_array_pair: 1578 %empty { $$ = NULL; } 1579 | array_pair { $$ = $1; } 1580 ; 1581 1582 non_empty_array_pair_list: 1583 non_empty_array_pair_list ',' possible_array_pair 1584 { $$ = zend_ast_list_add($1, $3); } 1585 | possible_array_pair 1586 { $$ = zend_ast_create_list(1, ZEND_AST_ARRAY, $1); } 1587 ; 1588 1589 array_pair: 1590 expr T_DOUBLE_ARROW expr 1591 { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); } 1592 | expr 1593 { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); } 1594 | expr T_DOUBLE_ARROW ampersand variable 1595 { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $4, $1); } 1596 | ampersand variable 1597 { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); } 1598 | T_ELLIPSIS expr 1599 { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); } 1600 | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')' 1601 { $5->attr = ZEND_ARRAY_SYNTAX_LIST; 1602 $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); } 1603 | T_LIST '(' array_pair_list ')' 1604 { $3->attr = ZEND_ARRAY_SYNTAX_LIST; 1605 $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); } 1606 ; 1607 1608 encaps_list: 1609 encaps_list encaps_var 1610 { $$ = zend_ast_list_add($1, $2); } 1611 | encaps_list T_ENCAPSED_AND_WHITESPACE 1612 { $$ = zend_ast_list_add($1, $2); } 1613 | encaps_var 1614 { $$ = zend_ast_create_list(1, ZEND_AST_ENCAPS_LIST, $1); } 1615 | T_ENCAPSED_AND_WHITESPACE encaps_var 1616 { $$ = zend_ast_create_list(2, ZEND_AST_ENCAPS_LIST, $1, $2); } 1617 ; 1618 1619 encaps_var: 1620 T_VARIABLE 1621 { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1622 | T_VARIABLE '[' encaps_var_offset ']' 1623 { $$ = zend_ast_create(ZEND_AST_DIM, 1624 zend_ast_create(ZEND_AST_VAR, $1), $3); } 1625 | T_VARIABLE T_OBJECT_OPERATOR T_STRING 1626 { $$ = zend_ast_create(ZEND_AST_PROP, 1627 zend_ast_create(ZEND_AST_VAR, $1), $3); } 1628 | T_VARIABLE T_NULLSAFE_OBJECT_OPERATOR T_STRING 1629 { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP, 1630 zend_ast_create(ZEND_AST_VAR, $1), $3); } 1631 | T_DOLLAR_OPEN_CURLY_BRACES expr '}' 1632 { $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR, $2); } 1633 | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' 1634 { $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY, $2); } 1635 | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' 1636 { $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_ENCAPS_VAR_DOLLAR_CURLY, 1637 zend_ast_create(ZEND_AST_VAR, $2), $4); } 1638 | T_CURLY_OPEN variable '}' { $$ = $2; } 1639 ; 1640 1641 encaps_var_offset: 1642 T_STRING { $$ = $1; } 1643 | T_NUM_STRING { $$ = $1; } 1644 | '-' T_NUM_STRING { $$ = zend_negate_num_string($2); } 1645 | T_VARIABLE { $$ = zend_ast_create(ZEND_AST_VAR, $1); } 1646 ; 1647 1648 1649 internal_functions_in_yacc: 1650 T_ISSET '(' isset_variables possible_comma ')' { $$ = $3; } 1651 | T_EMPTY '(' expr ')' { $$ = zend_ast_create(ZEND_AST_EMPTY, $3); } 1652 | T_INCLUDE expr 1653 { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2); } 1654 | T_INCLUDE_ONCE expr 1655 { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2); } 1656 | T_EVAL '(' expr ')' 1657 { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_EVAL, $3); } 1658 | T_REQUIRE expr 1659 { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2); } 1660 | T_REQUIRE_ONCE expr 1661 { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2); } 1662 ; 1663 1664 isset_variables: 1665 isset_variable { $$ = $1; } 1666 | isset_variables ',' isset_variable 1667 { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } 1668 ; 1669 1670 isset_variable: 1671 expr { $$ = zend_ast_create(ZEND_AST_ISSET, $1); } 1672 ; 1673 1674 %% 1675 1676 /* Over-ride Bison formatting routine to give better token descriptions. 1677 Copy to YYRES the contents of YYSTR for use in yyerror. 1678 YYSTR is taken from yytname, from the %token declaration. 1679 If YYRES is null, do not copy; instead, return the length of what 1680 the result would have been. */ 1681 static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr) 1682 { 1683 const char *toktype = yystr; 1684 size_t toktype_len = strlen(toktype); 1685 1686 /* CG(parse_error) states: 1687 * 0 => yyres = NULL, yystr is the unexpected token 1688 * 1 => yyres = NULL, yystr is one of the expected tokens 1689 * 2 => yyres != NULL, yystr is the unexpected token 1690 * 3 => yyres != NULL, yystr is one of the expected tokens 1691 */ 1692 if (yyres && CG(parse_error) < 2) { 1693 CG(parse_error) = 2; 1694 } 1695 1696 if (CG(parse_error) % 2 == 0) { 1697 /* The unexpected token */ 1698 char buffer[120]; 1699 const unsigned char *tokcontent, *tokcontent_end; 1700 size_t tokcontent_len; 1701 1702 CG(parse_error)++; 1703 1704 if (LANG_SCNG(yy_text)[0] == 0 && 1705 LANG_SCNG(yy_leng) == 1 && 1706 strcmp(toktype, "\"end of file\"") == 0) { 1707 if (yyres) { 1708 yystpcpy(yyres, "end of file"); 1709 } 1710 return sizeof("end of file")-1; 1711 } 1712 1713 /* Prevent the backslash getting doubled in the output (eugh) */ 1714 if (strcmp(toktype, "\"'\\\\'\"") == 0) { 1715 if (yyres) { 1716 yystpcpy(yyres, "token \"\\\""); 1717 } 1718 return sizeof("token \"\\\"")-1; 1719 } 1720 1721 /* We used "amp" as a dummy label to avoid a duplicate token literal warning. */ 1722 if (strcmp(toktype, "\"amp\"") == 0) { 1723 if (yyres) { 1724 yystpcpy(yyres, "token \"&\""); 1725 } 1726 return sizeof("token \"&\"")-1; 1727 } 1728 1729 /* Avoid unreadable """ */ 1730 /* "'" would theoretically be just as bad, but is never currently parsed as a separate token */ 1731 if (strcmp(toktype, "'\"'") == 0) { 1732 if (yyres) { 1733 yystpcpy(yyres, "double-quote mark"); 1734 } 1735 return sizeof("double-quote mark")-1; 1736 } 1737 1738 /* Strip off the outer quote marks */ 1739 if (toktype_len >= 2 && *toktype == '"') { 1740 toktype++; 1741 toktype_len -= 2; 1742 } 1743 1744 /* If the token always has one form, the %token line should have a single-quoted name */ 1745 /* The parser rules also include single-character un-named tokens which will be single-quoted here */ 1746 /* We re-format this with double quotes here to ensure everything's consistent */ 1747 if (toktype_len > 0 && *toktype == '\'') { 1748 if (yyres) { 1749 snprintf(buffer, sizeof(buffer), "token \"%.*s\"", (int)toktype_len-2, toktype+1); 1750 yystpcpy(yyres, buffer); 1751 } 1752 return toktype_len + sizeof("token ")-1; 1753 } 1754 1755 /* Fetch the content of the last seen token from global lexer state */ 1756 tokcontent = LANG_SCNG(yy_text); 1757 tokcontent_len = LANG_SCNG(yy_leng); 1758 1759 /* For T_BAD_CHARACTER, the content probably won't be a printable char */ 1760 /* Also, "unexpected invalid character" sounds a bit redundant */ 1761 if (tokcontent_len == 1 && strcmp(yystr, "\"invalid character\"") == 0) { 1762 if (yyres) { 1763 snprintf(buffer, sizeof(buffer), "character 0x%02hhX", *tokcontent); 1764 yystpcpy(yyres, buffer); 1765 } 1766 return sizeof("character 0x00")-1; 1767 } 1768 1769 /* Truncate at line end to avoid messing up log formats */ 1770 tokcontent_end = memchr(tokcontent, '\n', tokcontent_len); 1771 if (tokcontent_end != NULL) { 1772 tokcontent_len = (tokcontent_end - tokcontent); 1773 } 1774 1775 /* Try to be helpful about what kind of string was found, before stripping the quotes */ 1776 if (tokcontent_len > 0 && strcmp(yystr, "\"quoted string\"") == 0) { 1777 if (*tokcontent == '"') { 1778 toktype = "double-quoted string"; 1779 toktype_len = sizeof("double-quoted string")-1; 1780 } 1781 else if (*tokcontent == '\'') { 1782 toktype = "single-quoted string"; 1783 toktype_len = sizeof("single-quoted string")-1; 1784 } 1785 } 1786 1787 /* For quoted strings, strip off another layer of quotes to avoid putting quotes inside quotes */ 1788 if (tokcontent_len > 0 && (*tokcontent == '\'' || *tokcontent=='"')) { 1789 tokcontent++; 1790 tokcontent_len--; 1791 } 1792 if (tokcontent_len > 0 && (tokcontent[tokcontent_len-1] == '\'' || tokcontent[tokcontent_len-1] == '"')) { 1793 tokcontent_len--; 1794 } 1795 1796 /* Truncate to 30 characters and add a ... */ 1797 if (tokcontent_len > 30 + sizeof("...")-1) { 1798 if (yyres) { 1799 snprintf(buffer, sizeof(buffer), "%.*s \"%.*s...\"", (int)toktype_len, toktype, 30, tokcontent); 1800 yystpcpy(yyres, buffer); 1801 } 1802 return toktype_len + 30 + sizeof(" \"...\"")-1; 1803 } 1804 1805 if (yyres) { 1806 snprintf(buffer, sizeof(buffer), "%.*s \"%.*s\"", (int)toktype_len, toktype, (int)tokcontent_len, tokcontent); 1807 yystpcpy(yyres, buffer); 1808 } 1809 return toktype_len + tokcontent_len + sizeof(" \"\"")-1; 1810 } 1811 1812 /* One of the expected tokens */ 1813 1814 /* Prevent the backslash getting doubled in the output (eugh) */ 1815 if (strcmp(toktype, "\"'\\\\'\"") == 0) { 1816 if (yyres) { 1817 yystpcpy(yyres, "\"\\\""); 1818 } 1819 return sizeof("\"\\\"")-1; 1820 } 1821 1822 /* Strip off the outer quote marks */ 1823 if (toktype_len >= 2 && *toktype == '"') { 1824 toktype++; 1825 toktype_len -= 2; 1826 } 1827 1828 if (yyres) { 1829 YYSIZE_T yyn = 0; 1830 1831 for (; yyn < toktype_len; ++yyn) { 1832 /* Replace single quotes with double for consistency */ 1833 if (toktype[yyn] == '\'') { 1834 yyres[yyn] = '"'; 1835 } 1836 else { 1837 yyres[yyn] = toktype[yyn]; 1838 } 1839 } 1840 yyres[toktype_len] = '\0'; 1841 } 1842 1843 return toktype_len; 1844 } 1845