@@ -231,11 +231,13 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
231
231
%token T_COALESCE " '??'"
232
232
%token T_POW " '**'"
233
233
%token T_POW_EQUAL " '**='"
234
- /* We need to split the & token in two because otherwise Bison somehow lands
235
- * in a shift/reduce conflict for parameter intersection types */
234
+ /* We need to split the & token in two to avoid a shift/reduce conflict. For T1&$v and T1&T2,
235
+ * with only one token lookahead, bison does not know whether to reduce T1 as a complete type,
236
+ * or shift to continue parsing an intersection type. */
236
237
%token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG " '&'"
237
- // TODO Fix parse error message
238
- %token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG " '&''"
238
+ /* Bison warns on duplicate token literals, so use a different dummy value here.
239
+ * It will be fixed up by zend_yytnamerr() later. */
240
+ %token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG " amp"
239
241
%token T_BAD_CHARACTER " invalid character"
240
242
241
243
/* Token used to force a parse error from the lexer */
@@ -1568,6 +1570,14 @@ static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
1568
1570
return sizeof (" token \"\\\" " )-1 ;
1569
1571
}
1570
1572
1573
+ /* We used "amp" as a dummy label to avoid a duplicate token literal warning. */
1574
+ if (strcmp (toktype, " \" amp\" " ) == 0 ) {
1575
+ if (yyres) {
1576
+ yystpcpy (yyres, " token \" &\" " );
1577
+ }
1578
+ return sizeof (" token \" &\" " )-1 ;
1579
+ }
1580
+
1571
1581
/* Avoid unreadable """ */
1572
1582
/* "'" would theoretically be just as bad, but is never currently parsed as a separate token */
1573
1583
if (strcmp (toktype, " '\" '" ) == 0 ) {
0 commit comments