6565%right BITWISE_NOT .
6666%right PARENTHESES_CLOSE .
6767%right SBRACKET_OPEN .
68- %right ARROW .
68+ %left ARROW .
6969
7070// The following text is included near the beginning of the C source
7171// code file that implements the parser.
@@ -1401,6 +1401,10 @@ xx_for_statement(R) ::= FOR IDENTIFIER(K) COMMA IDENTIFIER(V) IN REVERSE xx_comm
14011401 xx_ret_for_statement(&R, &E, K, V, 1, &L, status->scanner_state);
14021402}
14031403
1404+ xx_for_statement(R) ::= FOR IDENTIFIER(K) COMMA IDENTIFIER(V) IN REVERSE xx_common_expr(E) BRACKET_OPEN BRACKET_CLOSE . {
1405+ xx_ret_for_statement(&R, &E, K, V, 1, NULL, status->scanner_state);
1406+ }
1407+
14041408xx_for_statement(R) ::= FOR PARENTHESES_OPEN IDENTIFIER(V) IN xx_common_expr(E) PARENTHESES_CLOSE BRACKET_OPEN xx_statement_list(L) BRACKET_CLOSE . {
14051409 xx_ret_for_statement(&R, &E, NULL, V, 0, &L, status->scanner_state);
14061410}
@@ -1522,15 +1526,39 @@ xx_let_assignment(R) ::= IDENTIFIER(D) ARROW IDENTIFIER(I) SBRACKET_OPEN SBRACKE
15221526 xx_ret_let_assignment(&R, "object-property-append", &O, D, I, NULL, &E, status->scanner_state);
15231527}
15241528
1525- /* y->x[z][] = {expr} */
1529+ /* y->x[z] = {expr} */
15261530xx_let_assignment(R) ::= IDENTIFIER(D) ARROW IDENTIFIER(I) xx_array_offset_list(X) xx_assignment_operator(O) xx_assign_expr(E) . {
15271531 xx_ret_let_assignment(&R, "object-property-array-index", &O, D, I, &X, &E, status->scanner_state);
15281532}
15291533
1534+ /* y->x[z][] = {expr} */
15301535xx_let_assignment(R) ::= IDENTIFIER(D) ARROW IDENTIFIER(I) xx_array_offset_list(X) SBRACKET_OPEN SBRACKET_CLOSE xx_assignment_operator(O) xx_assign_expr(E) . {
15311536 xx_ret_let_assignment(&R, "object-property-array-index-append", &O, D, I, &X, &E, status->scanner_state);
15321537}
15331538
1539+ /* Nested property-access receiver chain (builds a property-access expression chain) */
1540+ xx_let_nested_recv(R) ::= IDENTIFIER(D) ARROW IDENTIFIER(I) . {
1541+ {
1542+ zval id1, id2;
1543+ xx_ret_literal(&id1, XX_T_IDENTIFIER, D, status->scanner_state);
1544+ xx_ret_literal(&id2, XX_T_IDENTIFIER, I, status->scanner_state);
1545+ xx_ret_expr(&R, "property-access", &id1, &id2, NULL, status->scanner_state);
1546+ }
1547+ }
1548+
1549+ xx_let_nested_recv(R) ::= xx_let_nested_recv(L) ARROW IDENTIFIER(I) . {
1550+ {
1551+ zval identifier;
1552+ xx_ret_literal(&identifier, XX_T_IDENTIFIER, I, status->scanner_state);
1553+ xx_ret_expr(&R, "property-access", &L, &identifier, NULL, status->scanner_state);
1554+ }
1555+ }
1556+
1557+ /* {receiver}->prop = {expr} (nested property access assignment, 2+ levels deep) */
1558+ xx_let_assignment(R) ::= xx_let_nested_recv(V) ARROW IDENTIFIER(I) xx_assignment_operator(O) xx_assign_expr(E) . {
1559+ xx_ret_let_property_access_assignment(&R, &O, &V, I, &E, status->scanner_state);
1560+ }
1561+
15341562/* y::x = {expr} */
15351563xx_let_assignment(R) ::= IDENTIFIER(D) DOUBLECOLON IDENTIFIER(I) xx_assignment_operator(O) xx_assign_expr(E) . {
15361564 xx_ret_let_assignment(&R, "static-property", &O, D, I, NULL, &E, status->scanner_state);
@@ -1886,7 +1914,7 @@ xx_common_expr(R) ::= xx_common_expr(V) ARROW BRACKET_OPEN STRING(S) BRACKET_CLO
18861914 }
18871915}
18881916
1889- xx_common_expr(R) ::= IDENTIFIER(V) DOUBLECOLON IDENTIFIER(I) . {
1917+ xx_common_expr(R) ::= IDENTIFIER(V) DOUBLECOLON IDENTIFIER(I) . [COMMA] {
18901918 {
18911919 zval identifier, identifier2;
18921920 xx_ret_literal(&identifier, XX_T_IDENTIFIER, V, status->scanner_state);
@@ -1994,11 +2022,11 @@ xx_common_expr(R) ::= xx_common_expr(O1) EXCLUSIVE_RANGE xx_common_expr(O2) . {
19942022}
19952023
19962024/* y = fetch x, z[k] */
1997- xx_fetch_expr(R) ::= FETCH IDENTIFIER(O1) COMMA xx_common_expr(O2 ) . {
2025+ xx_fetch_expr(R) ::= FETCH IDENTIFIER(O1) COMMA xx_common_expr(E2 ) . {
19982026 {
19992027 zval identifier;
20002028 xx_ret_literal(&identifier, XX_T_IDENTIFIER, O1, status->scanner_state);
2001- xx_ret_expr(&R, "fetch", &identifier, &O2 , NULL, status->scanner_state);
2029+ xx_ret_expr(&R, "fetch", &identifier, &E2 , NULL, status->scanner_state);
20022030 }
20032031}
20042032
@@ -2013,7 +2041,7 @@ xx_common_expr(R) ::= TYPEOF xx_common_expr(O1) . {
20132041}
20142042
20152043/* y = x */
2016- xx_common_expr(R) ::= IDENTIFIER(I) . {
2044+ xx_common_expr(R) ::= IDENTIFIER(I) . [COMMA] {
20172045 xx_ret_literal(&R, XX_T_IDENTIFIER, I, status->scanner_state);
20182046}
20192047
0 commit comments