Skip to content

Commit 3af8fdc

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

6 files changed

+41
-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: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,9 +1412,13 @@ 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+
RETURN_TOKEN_WITH_IDENT(T_FROM);
14181422
}
14191423

14201424
<ST_IN_SCRIPTING>"yield" {
@@ -1580,7 +1584,7 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
15801584
RETURN_TOKEN(T_NULLSAFE_OBJECT_OPERATOR);
15811585
}
15821586

1583-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
1587+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>{WHITESPACE}+ {
15841588
goto return_whitespace;
15851589
}
15861590

@@ -2383,7 +2387,7 @@ inline_char_handler:
23832387
}
23842388
23852389
2386-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>"#"|"//" {
2390+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>"#"|"//" {
23872391
while (YYCURSOR < YYLIMIT) {
23882392
switch (*YYCURSOR++) {
23892393
case '\r':
@@ -2407,7 +2411,7 @@ inline_char_handler:
24072411
RETURN_OR_SKIP_TOKEN(T_COMMENT);
24082412
}
24092413

2410-
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>"/*"|"/**"{WHITESPACE} {
2414+
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>"/*"|"/**"{WHITESPACE} {
24112415
int doc_com;
24122416

24132417
if (yyleng > 2) {
@@ -2443,7 +2447,7 @@ inline_char_handler:
24432447
RETURN_OR_SKIP_TOKEN(T_COMMENT);
24442448
}
24452449

2446-
<ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
2450+
<ST_LOOKING_FOR_PROPERTY,ST_LOOKING_FOR_FROM>{ANY_CHAR} {
24472451
yyless(0);
24482452
yy_pop_state();
24492453
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)