summaryrefslogtreecommitdiff
path: root/Zend/zend_language_parser.y
diff options
context:
space:
mode:
authorFelipe Pena <felipe@php.net>2011-11-06 13:25:45 +0000
committerFelipe Pena <felipe@php.net>2011-11-06 13:25:45 +0000
commitff48763f4b0fee906293815b42fe3e2a167702c8 (patch)
tree5145b265d5d4bae41479bb424f3d224d73953212 /Zend/zend_language_parser.y
parent7888715e73201f896d8793a715255d1faf59e1e1 (diff)
downloadphp-git-ff48763f4b0fee906293815b42fe3e2a167702c8.tar.gz
- Added class member access on instantiation (e.g. (new foo)->bar()) support
Diffstat (limited to 'Zend/zend_language_parser.y')
-rw-r--r--Zend/zend_language_parser.y31
1 files changed, 29 insertions, 2 deletions
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 906242fb48..a0c671b34c 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -50,7 +50,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%}
%pure_parser
-%expect 2
+%expect 3
%token END 0 "end of file"
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
@@ -694,12 +694,37 @@ non_empty_for_expr:
| expr { $$ = $1; }
;
+chaining_method_or_property:
+ chaining_method_or_property variable_property { $$.EA = $2.EA; }
+ | variable_property { $$.EA = $1.EA; }
+;
+
+chaining_dereference:
+ chaining_dereference '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+ | '[' dim_offset ']' { zend_do_pop_object(&$1 TSRMLS_CC); fetch_array_dim(&$$, &$1, &$2 TSRMLS_CC); }
+;
+
+chaining_instance_call:
+ chaining_dereference { zend_do_push_object(&$1 TSRMLS_CC); } chaining_method_or_property { $$ = $3; }
+ | chaining_dereference { zend_do_push_object(&$1 TSRMLS_CC); $$ = $1; }
+ | chaining_method_or_property { $$ = $1; }
+;
+
+instance_call:
+ /* empty */ { $$ = $0; }
+ | { zend_do_push_object(&$0 TSRMLS_CC); zend_do_begin_variable_parse(TSRMLS_C); }
+ chaining_instance_call { zend_do_pop_object(&$$ TSRMLS_CC); zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); }
+;
+
+new_expr:
+ T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+;
+
expr_without_variable:
T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
| variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
| variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
| variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $3.EA = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
- | T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
| variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
| variable T_MINUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); }
@@ -746,6 +771,8 @@ expr_without_variable:
| expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); }
| expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
| '(' expr ')' { $$ = $2; }
+ | new_expr { $$ = $1; }
+ | '(' new_expr ')' { $$ = $2; } instance_call { $$ = $5; }
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); }
expr { zend_do_qm_false(&$$, &$7, &$2, &$5 TSRMLS_CC); }