Skip to content

Commit b12309a

Browse files
TimWollailuuu1994
andcommitted
zend_language_scanner: Lex clone as identifier when followed by (
This greatly simplifies the parser to support `clone()` as a function and effectively reverts php#18938. Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
1 parent c9249e2 commit b12309a

File tree

2 files changed

+10
-39
lines changed

2 files changed

+10
-39
lines changed

‎Zend/zend_language_parser.y

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
259259
%type <ast> unprefixed_use_declarations const_decl inner_statement
260260
%type <ast> expr optional_expr while_statement for_statement foreach_variable
261261
%type <ast> foreach_statement declare_statement finally_statement unset_variable variable
262-
%type <ast> extends_from parameter optional_type_without_static argument argument_no_expr global_var
262+
%type <ast> extends_from parameter optional_type_without_static argument global_var
263263
%type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias
264264
%type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
265265
%type <ast> new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable
@@ -287,7 +287,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
287287
%type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr
288288
%type <ast> function_name non_empty_member_modifiers
289289
%type <ast> property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body
290-
%type <ast> optional_parameter_list clone_argument_list non_empty_clone_argument_list
290+
%type <ast> optional_parameter_list
291291

292292
%type <num> returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers
293293
%type <num> method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers
@@ -914,42 +914,13 @@ non_empty_argument_list:
914914
{ $$ = zend_ast_list_add($1, $3); }
915915
;
916916

917-
/* `clone_argument_list` is necessary to resolve a parser ambiguity (shift-reduce conflict)
918-
* of `clone($expr)`, which could either be parsed as a function call with `$expr` as the first
919-
* argument or as a use of the `clone` language construct with an expression with useless
920-
* parenthesis. Both would be valid and result in the same AST / the same semantics.
921-
* `clone_argument_list` is defined in a way that an `expr` in the first position needs to
922-
* be followed by a `,` which is not valid syntax for a parenthesized `expr`, ensuring
923-
* that calling `clone()` with a single unnamed parameter is handled by the language construct
924-
* syntax.
925-
*/
926-
clone_argument_list:
927-
'(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
928-
| '(' non_empty_clone_argument_list possible_comma ')' { $$ = $2; }
929-
| '(' expr ',' ')' { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $2); }
930-
| '(' T_ELLIPSIS ')' { $$ = zend_ast_create_fcc(); }
931-
;
932-
933-
non_empty_clone_argument_list:
934-
expr ',' argument
935-
{ $$ = zend_ast_create_list(2, ZEND_AST_ARG_LIST, $1, $3); }
936-
| argument_no_expr
937-
{ $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
938-
| non_empty_clone_argument_list ',' argument
939-
{ $$ = zend_ast_list_add($1, $3); }
940-
;
941-
942-
argument_no_expr:
943-
identifier ':' expr
917+
argument:
918+
expr { $$ = $1; }
919+
| identifier ':' expr
944920
{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
945921
| T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
946922
;
947923

948-
argument:
949-
expr { $$ = $1; }
950-
| argument_no_expr { $$ = $1; }
951-
;
952-
953924
global_var_list:
954925
global_var_list ',' global_var { $$ = zend_ast_list_add($1, $3); }
955926
| global_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); }
@@ -1257,11 +1228,6 @@ expr:
12571228
{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
12581229
| variable '=' ampersand variable
12591230
{ $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
1260-
| T_CLONE clone_argument_list {
1261-
zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE));
1262-
name->attr = ZEND_NAME_FQ;
1263-
$$ = zend_ast_create(ZEND_AST_CALL, name, $2);
1264-
}
12651231
| T_CLONE expr {
12661232
zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE));
12671233
name->attr = ZEND_NAME_FQ;

‎Zend/zend_language_scanner.l

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,11 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
16131613
RETURN_TOKEN_WITH_IDENT(T_NEW);
16141614
}
16151615

1616+
<ST_IN_SCRIPTING>"clone"{OPTIONAL_WHITESPACE_OR_COMMENTS}"(" {
1617+
yyless(5);
1618+
RETURN_TOKEN_WITH_STR(T_NAME_FULLY_QUALIFIED, 0);
1619+
}
1620+
16161621
<ST_IN_SCRIPTING>"clone" {
16171622
RETURN_TOKEN_WITH_IDENT(T_CLONE);
16181623
}

0 commit comments

Comments
 (0)