Skip to content

Commit 42e9f66

Browse files
Tokenize yield from as T_YIELD+T_FROM
Fixes GH-14926.
1 parent 68ae477 commit 42e9f66

6 files changed

+42
-15
lines changed

Zend/tests/gh14926.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
yield from is tokenized separately
3+
--FILE--
4+
<?php
5+
6+
function tokens($str) {
7+
$t = token_get_all("<?php $str");
8+
array_shift($t);
9+
foreach ($t as $t) {
10+
echo is_array($t) ? $t[1] : $t, "|";
11+
}
12+
print "\n";
13+
}
14+
15+
tokens("yield from \$foo;");
16+
tokens("yield # comment\n/* other comment */ from \$foo;");
17+
18+
?>
19+
--EXPECT--
20+
yield| |from| |$foo|;|
21+
yield| |# comment|
22+
|/* other comment */| |from| |$foo|;|

Zend/zend_language_parser.y

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
6060
%precedence T_PRINT
6161
%precedence T_YIELD
6262
%precedence T_DOUBLE_ARROW
63-
%precedence T_YIELD_FROM
63+
%precedence T_FROM
6464
%precedence '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL
6565
%left '?' ':'
6666
%right T_COALESCE
@@ -109,7 +109,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
109109
%token <ident> T_LOGICAL_AND "'and'"
110110
%token <ident> T_PRINT "'print'"
111111
%token <ident> T_YIELD "'yield'"
112-
%token <ident> T_YIELD_FROM "'yield from'"
112+
%token <ident> T_FROM "'from'"
113113
%token <ident> T_INSTANCEOF "'instanceof'"
114114
%token <ident> T_NEW "'new'"
115115
%token <ident> T_CLONE "'clone'"
@@ -1312,7 +1312,7 @@ expr:
13121312
| T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
13131313
| T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
13141314
| T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
1315-
| T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
1315+
| T_YIELD T_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $3); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
13161316
| T_THROW expr { $$ = zend_ast_create(ZEND_AST_THROW, $2); }
13171317
| inline_function { $$ = $1; }
13181318
| attributes inline_function { $$ = zend_ast_with_attributes($2, $1); }

Zend/zend_language_scanner.l

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,9 +1412,14 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
14121412
}
14131413

14141414
<ST_IN_SCRIPTING>"yield"{WHITESPACE_OR_COMMENTS}"from"[^a-zA-Z0-9_\x80-\xff] {
1415-
yyless(yyleng - 1);
1416-
HANDLE_NEWLINES(yytext, yyleng);
1417-
RETURN_TOKEN_WITH_IDENT(T_YIELD_FROM);
1415+
yyless(5);
1416+
yy_push_state(ST_LOOKING_FOR_FROM);
1417+
RETURN_TOKEN_WITH_IDENT(T_YIELD);
1418+
}
1419+
1420+
<ST_LOOKING_FOR_FROM>"from" {
1421+
yy_pop_state();
1422+
RETURN_TOKEN_WITH_IDENT(T_FROM);
14181423
}
14191424

14201425
<ST_IN_SCRIPTING>"yield" {
@@ -1580,7 +1585,7 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
15801585
RETURN_TOKEN(T_NULLSAFE_OBJECT_OPERATOR);
15811586
}
15821587

1583-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
1588+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>{WHITESPACE}+ {
15841589
goto return_whitespace;
15851590
}
15861591

@@ -2383,7 +2388,7 @@ inline_char_handler:
23832388
}
23842389
23852390
2386-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>"#"|"//" {
2391+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>"#"|"//" {
23872392
while (YYCURSOR < YYLIMIT) {
23882393
switch (*YYCURSOR++) {
23892394
case '\r':
@@ -2407,7 +2412,7 @@ inline_char_handler:
24072412
RETURN_OR_SKIP_TOKEN(T_COMMENT);
24082413
}
24092414

2410-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>"/*"|"/**"{WHITESPACE} {
2415+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>"/*"|"/**"{WHITESPACE} {
24112416
int doc_com;
24122417

24132418
if (yyleng > 2) {
@@ -2443,7 +2448,7 @@ inline_char_handler:
24432448
RETURN_OR_SKIP_TOKEN(T_COMMENT);
24442449
}
24452450

2446-
<ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
2451+
<ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>{ANY_CHAR} {
24472452
yyless(0);
24482453
yy_pop_state();
24492454
goto restart;

ext/tokenizer/tokenizer_data.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/tokenizer/tokenizer_data.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@
114114
const T_YIELD = UNKNOWN;
115115
/**
116116
* @var int
117-
* @cvalue T_YIELD_FROM
117+
* @cvalue T_FROM
118118
*/
119-
const T_YIELD_FROM = UNKNOWN;
119+
const T_FROM = UNKNOWN;
120120
/**
121121
* @var int
122122
* @cvalue T_INSTANCEOF

ext/tokenizer/tokenizer_data_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)