diff options
Diffstat (limited to 'Zend/zend_language_parser.y')
-rw-r--r-- | Zend/zend_language_parser.y | 127 |
1 files changed, 69 insertions, 58 deletions
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 9f99453cd4..957d657909 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -43,7 +43,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %} -%pure_parser +%pure-parser %expect 0 %code requires { @@ -241,21 +241,22 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name %type <ast> variable_class_name dereferencable_scalar constant dereferencable %type <ast> callable_expr callable_variable static_member new_variable -%type <ast> assignment_list_element array_pair encaps_var encaps_var_offset isset_variables +%type <ast> encaps_var encaps_var_offset isset_variables %type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt %type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list -%type <ast> echo_expr_list unset_variables catch_list parameter_list class_statement_list +%type <ast> echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list %type <ast> implements_list case_list if_stmt_without_else %type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list %type <ast> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs %type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars -%type <ast> lexical_var_list encaps_list array_pair_list non_empty_array_pair_list -%type <ast> assignment_list isset_variable type return_type +%type <ast> lexical_var_list encaps_list +%type <ast> array_pair non_empty_array_pair_list array_pair_list possible_array_pair +%type <ast> isset_variable type return_type type_expr %type <ast> identifier %type <num> returns_ref function is_reference is_variadic variable_modifiers %type <num> method_modifiers non_empty_member_modifiers member_modifier -%type <num> class_modifiers class_modifier use_type +%type <num> class_modifiers class_modifier use_type backup_fn_flags %type <str> backup_doc_comment @@ -454,10 +455,15 @@ statement: catch_list: /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); } - | catch_list T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}' + | catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); } ; +catch_name_list: + name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); } + | catch_name_list '|' name { $$ = zend_ast_list_add($1, $3); } +; + finally_statement: /* empty */ { $$ = NULL; } | T_FINALLY '{' inner_statement_list '}' { $$ = $3; } @@ -474,9 +480,9 @@ unset_variable: function_declaration_statement: function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type - '{' inner_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2, $1, $4, - zend_ast_get_str($3), $6, NULL, $10, $8); } + backup_fn_flags '{' inner_statement_list '}' backup_fn_flags + { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4, + zend_ast_get_str($3), $6, NULL, $11, $8); CG(extra_fn_flags) = $9; } ; is_reference: @@ -538,7 +544,8 @@ implements_list: foreach_variable: variable { $$ = $1; } | '&' variable { $$ = zend_ast_create(ZEND_AST_REF, $2); } - | T_LIST '(' assignment_list ')' { $$ = $3; } + | T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; } + | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; } ; for_statement: @@ -637,7 +644,12 @@ parameter: optional_type: /* empty */ { $$ = NULL; } - | type { $$ = $1; } + | type_expr { $$ = $1; } +; + +type_expr: + type { $$ = $1; } + | '?' type { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; } ; type: @@ -648,7 +660,7 @@ type: return_type: /* empty */ { $$ = NULL; } - | ':' type { $$ = $2; } + | ':' type_expr { $$ = $2; } ; argument_list: @@ -701,14 +713,14 @@ class_statement_list: class_statement: variable_modifiers property_list ';' { $$ = $2; $$->attr = $1; } - | T_CONST class_const_list ';' - { $$ = $2; RESET_DOC_COMMENT(); } + | method_modifiers T_CONST class_const_list ';' + { $$ = $3; $$->attr = $1; } | T_USE name_list trait_adaptations { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); } | method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')' - return_type method_body - { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1, $2, $5, - zend_ast_get_str($4), $7, NULL, $10, $9); } + return_type backup_fn_flags method_body backup_fn_flags + { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5, + zend_ast_get_str($4), $7, NULL, $11, $9); CG(extra_fn_flags) = $10; } ; name_list: @@ -810,11 +822,11 @@ class_const_list: ; class_const_decl: - identifier '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); } + identifier '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } ; const_decl: - T_STRING '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); } + T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } ; echo_expr_list: @@ -853,8 +865,10 @@ new_expr: ; expr_without_variable: - T_LIST '(' assignment_list ')' '=' expr - { $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); } + T_LIST '(' array_pair_list ')' '=' expr + { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); } + | '[' array_pair_list ']' '=' expr + { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); } | variable '=' expr { $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); } | variable '=' '&' variable @@ -955,20 +969,20 @@ expr_without_variable: | scalar { $$ = $1; } | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); } | T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); } - | T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); } - | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); } - | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); } - | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); } + | T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } | function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type - '{' inner_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2, $1, $3, + backup_fn_flags '{' inner_statement_list '}' backup_fn_flags + { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), - $5, $7, $10, $8); } + $5, $7, $11, $8); CG(extra_fn_flags) = $9; } | T_STATIC function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars - return_type '{' inner_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | ZEND_ACC_STATIC, $2, $4, + return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags + { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | $14 | ZEND_ACC_STATIC, $2, $4, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), - $6, $8, $11, $9); } + $6, $8, $12, $9); CG(extra_fn_flags) = $10; } ; function: @@ -979,6 +993,10 @@ backup_doc_comment: /* empty */ { $$ = CG(doc_comment); CG(doc_comment) = NULL; } ; +backup_fn_flags: + /* empty */ { $$ = CG(extra_fn_flags); CG(extra_fn_flags) = 0; } +; + returns_ref: /* empty */ { $$ = 0; } | '&' { $$ = ZEND_ACC_RETURN_REFERENCE; } @@ -1012,7 +1030,7 @@ function_call: class_name: T_STATIC - { zval zv; ZVAL_STRINGL(&zv, "static", sizeof("static")-1); + { zval zv; ZVAL_INTERNED_STR(&zv, CG(known_strings)[ZEND_STR_STATIC]); $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); } | name { $$ = $1; } ; @@ -1042,8 +1060,8 @@ ctor_arguments: dereferencable_scalar: - T_ARRAY '(' array_pair_list ')' { $$ = $3; } - | '[' array_pair_list ']' { $$ = $2; } + T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; } + | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; } | T_CONSTANT_ENCAPSED_STRING { $$ = $1; } ; @@ -1075,11 +1093,6 @@ constant: { $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $3); } ; -possible_comma: - /* empty */ - | ',' -; - expr: variable { $$ = $1; } | expr_without_variable { $$ = $1; } @@ -1169,40 +1182,38 @@ property_name: | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); } ; -assignment_list: - assignment_list ',' assignment_list_element - { $$ = zend_ast_list_add($1, $3); } - | assignment_list_element - { $$ = zend_ast_create_list(1, ZEND_AST_LIST, $1); } -; - -assignment_list_element: - variable { $$ = $1; } - | T_LIST '(' assignment_list ')' { $$ = $3; } - | /* empty */ { $$ = NULL; } +array_pair_list: + non_empty_array_pair_list + { /* allow single trailing comma */ $$ = zend_ast_list_rtrim($1); } ; - -array_pair_list: - /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_ARRAY); } - | non_empty_array_pair_list possible_comma { $$ = $1; } +possible_array_pair: + /* empty */ { $$ = NULL; } + | array_pair { $$ = $1; } ; non_empty_array_pair_list: - non_empty_array_pair_list ',' array_pair + non_empty_array_pair_list ',' possible_array_pair { $$ = zend_ast_list_add($1, $3); } - | array_pair + | possible_array_pair { $$ = zend_ast_create_list(1, ZEND_AST_ARRAY, $1); } ; array_pair: expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); } - | expr { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); } + | expr + { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); } | expr T_DOUBLE_ARROW '&' variable { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $4, $1); } | '&' variable { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); } + | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')' + { $5->attr = ZEND_ARRAY_SYNTAX_LIST; + $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); } + | T_LIST '(' array_pair_list ')' + { $3->attr = ZEND_ARRAY_SYNTAX_LIST; + $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); } ; encaps_list: |