Skip to content

Commit 49b4e12

Browse files
committed
Add backup_doc_comment production
Bison can't detect the type of a mid-rule action, even if it accesses $<str>$, so need to create a separate rule for this.
1 parent b7876e7 commit 49b4e12

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
eval() parse error on function with doc comment
3+
--FILE--
4+
<?php
5+
6+
eval(
7+
<<<EOC
8+
/** doc comment */
9+
function f() {
10+
EOC
11+
);
12+
13+
?>
14+
--EXPECTF--
15+
Parse error: syntax error, unexpected end of file in %s(%d) : eval()'d code on line %d

Zend/zend_language_parser.y

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
5757

5858
%destructor { zend_ast_destroy($$); } <ast>
5959
%destructor { zend_ast_destroy((zend_ast *) $$); } <list>
60-
%destructor { if ($$) STR_RELEASE($$); } <str>
60+
%destructor { if ($$) zend_string_release($$); } <str>
6161

6262
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
6363
%left ','
@@ -254,6 +254,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
254254
%type <num> returns_ref function is_reference is_variadic class_type variable_modifiers
255255
%type <num> method_modifiers trait_modifiers non_empty_member_modifiers member_modifier
256256

257+
%type <str> backup_doc_comment
257258

258259
%% /* Rules */
259260

@@ -411,10 +412,9 @@ unset_variable:
411412
;
412413

413414
function_declaration_statement:
414-
function returns_ref T_STRING '(' parameter_list ')'
415-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
415+
function returns_ref T_STRING '(' parameter_list ')' backup_doc_comment
416416
'{' inner_statement_list '}'
417-
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2, $1, $<str>7,
417+
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2, $1, $7,
418418
zend_ast_get_str($3), $<ast>5, NULL, $<ast>9); }
419419
;
420420

@@ -429,19 +429,13 @@ is_variadic:
429429
;
430430

431431
class_declaration_statement:
432-
class_type
433-
{ $<num>$ = CG(zend_lineno); }
434-
T_STRING extends_from implements_list
435-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
436-
'{' class_statement_list '}'
437-
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>2, $<str>6,
432+
class_type { $<num>$ = CG(zend_lineno); }
433+
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
434+
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>2, $6,
438435
zend_ast_get_str($3), $4, $<ast>5, $<ast>8); }
439-
| T_INTERFACE
440-
{ $<num>$ = CG(zend_lineno); }
441-
T_STRING interface_extends_list
442-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
443-
'{' class_statement_list '}'
444-
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $<str>5,
436+
| T_INTERFACE { $<num>$ = CG(zend_lineno); }
437+
T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
438+
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $5,
445439
zend_ast_get_str($3), NULL, $<ast>4, $<ast>7); }
446440
;
447441

@@ -630,10 +624,9 @@ class_statement:
630624
{ $$ = $<ast>2; RESET_DOC_COMMENT(); }
631625
| T_USE name_list trait_adaptations
632626
{ $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
633-
| method_modifiers function returns_ref T_STRING '(' parameter_list ')'
634-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
627+
| method_modifiers function returns_ref T_STRING '(' parameter_list ')' backup_doc_comment
635628
method_body
636-
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1, $2, $<str>8,
629+
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1, $2, $8,
637630
zend_ast_get_str($4), $<ast>6, NULL, $<ast>9); }
638631
;
639632

@@ -876,24 +869,26 @@ expr_without_variable:
876869
| T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); }
877870
| T_YIELD expr T_DOUBLE_ARROW expr
878871
{ $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); }
879-
| function returns_ref '(' parameter_list ')' lexical_vars
880-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
872+
| function returns_ref '(' parameter_list ')' lexical_vars backup_doc_comment
881873
'{' inner_statement_list '}'
882-
{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2, $1, $<str>7,
874+
{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2, $1, $7,
883875
zend_string_init("{closure}", sizeof("{closure}") - 1, 0),
884876
$<ast>4, $<ast>6, $<ast>9); }
885-
| T_STATIC function returns_ref '(' parameter_list ')' lexical_vars
886-
{ $<str>$ = CG(doc_comment); CG(doc_comment) = NULL; }
877+
| T_STATIC function returns_ref '(' parameter_list ')' lexical_vars backup_doc_comment
887878
'{' inner_statement_list '}'
888-
{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | ZEND_ACC_STATIC, $2,
889-
$<str>8, zend_string_init("{closure}", sizeof("{closure}") - 1, 0),
879+
{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | ZEND_ACC_STATIC, $2, $8,
880+
zend_string_init("{closure}", sizeof("{closure}") - 1, 0),
890881
$<ast>5, $<ast>7, $<ast>10); }
891882
;
892883

893884
function:
894885
T_FUNCTION { $$ = CG(zend_lineno); }
895886
;
896887

888+
backup_doc_comment:
889+
/* empty */ { $$ = CG(doc_comment); CG(doc_comment) = NULL; }
890+
;
891+
897892
returns_ref:
898893
/* empty */ { $$ = 0; }
899894
| '&' { $$ = ZEND_ACC_RETURN_REFERENCE; }

0 commit comments

Comments
 (0)