Skip to content

Commit c211319

Browse files
committed
Fix parse error message for "&"
1 parent d04ae8d commit c211319

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

Zend/tests/type_declarations/intersection_types/invalid_types/invalid_nullable_type.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ function foo(): ?Countable&Iterator {}
77

88
?>
99
--EXPECTF--
10-
Parse error: syntax error, unexpected token "&'", expecting "{" in %s on line %d
10+
Parse error: syntax error, unexpected token "&", expecting "{" in %s on line %d
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
Parse error for & not followed by var or vararg
3+
--FILE--
4+
<?php
5+
+&
6+
?>
7+
--EXPECTF--
8+
Parse error: syntax error, unexpected token "&" in %s on line %d

Zend/zend_language_parser.y

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,13 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
231231
%token T_COALESCE "'??'"
232232
%token T_POW "'**'"
233233
%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. */
236237
%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"
239241
%token T_BAD_CHARACTER "invalid character"
240242

241243
/* Token used to force a parse error from the lexer */
@@ -1568,6 +1570,14 @@ static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
15681570
return sizeof("token \"\\\"")-1;
15691571
}
15701572

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+
15711581
/* Avoid unreadable """ */
15721582
/* "'" would theoretically be just as bad, but is never currently parsed as a separate token */
15731583
if (strcmp(toktype, "'\"'") == 0) {

0 commit comments

Comments
 (0)