Skip to content

Commit 7b6dc02

Browse files
committed
Fixed comments parsing
1 parent 42b0568 commit 7b6dc02

File tree

6 files changed

+195
-29
lines changed

6 files changed

+195
-29
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1515
- Corrected behavior on parse an empty file. Now an empty
1616
[IR](https://en.wikipedia.org/wiki/Intermediate_representation)
1717
(as an array) will be returned
18+
- Fixed language scanner and parser so that it is possible to parse files
19+
containing empty docblocks or files contains comments only
1820

1921
### Removed
2022
- PHP 5.x no longer supported. PHP 5.x users should use previous releases

parser/base.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,12 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
603603

604604
if (status != FAILURE) {
605605
if (parser_status->status == XX_PARSING_OK) {
606-
ZVAL_ZVAL(return_value, &parser_status->ret, 1, 1);
606+
// In case the `program' contained only XX_T_IGNORE
607+
if (Z_TYPE_P(&parser_status->ret) == IS_UNDEF) {
608+
array_init(return_value);
609+
} else {
610+
ZVAL_ZVAL(return_value, &parser_status->ret, 1, 1);
611+
}
607612
}
608613
}
609614

parser/parser.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8539,6 +8539,15 @@ void xx_(
85398539
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
85408540
return;
85418541
}
8542+
/* base.c
8543+
*
8544+
* This file is part of the Zephir Parser.
8545+
*
8546+
* (c) Zephir Team <[email protected]>
8547+
*
8548+
* For the full copyright and license information, please view
8549+
* the LICENSE file that was distributed with this source code.
8550+
*/
85428551

85438552
const xx_token_names xx_tokens[] =
85448553
{
@@ -9135,7 +9144,12 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
91359144

91369145
if (status != FAILURE) {
91379146
if (parser_status->status == XX_PARSING_OK) {
9138-
ZVAL_ZVAL(return_value, &parser_status->ret, 1, 1);
9147+
// In case the `program' contained only XX_T_IGNORE
9148+
if (Z_TYPE_P(&parser_status->ret) == IS_UNDEF) {
9149+
array_init(return_value);
9150+
} else {
9151+
ZVAL_ZVAL(return_value, &parser_status->ret, 1, 1);
9152+
}
91399153
}
91409154
}
91419155

parser/scanner.re

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -511,33 +511,35 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) {
511511
return 0;
512512
}
513513

514-
DCOMMENT = ("/**"([^*]+|[*]+[^/*])*[*]*"*/");
515-
DCOMMENT {
516-
start++;
517-
token->opcode = XX_T_COMMENT;
518-
token->value = estrndup(start, YYCURSOR - start - 1);
519-
token->len = YYCURSOR - start - 1;
520-
{
521-
int k, ch = s->active_char;
522-
for (k = 0; k < (token->len - 1); k++) {
523-
if (token->value[k] == '\n') {
524-
ch = 1;
525-
s->active_line++;
526-
} else {
527-
ch++;
528-
}
529-
}
530-
s->active_char = ch;
514+
COMMENT = ("/*" ([^*]+|[*]+[^/*])* [*]* "*/");
515+
COMMENT {
516+
int has_data = 0;
517+
if (YYCURSOR - start == 5) {
518+
// Empty dockblocks like /***/
519+
token->opcode = XX_T_COMMENT;
520+
} else if (YYCURSOR - start == 4) {
521+
// Empty comment like /**/
522+
token->opcode = XX_T_IGNORE;
523+
} else if (start[2] == '*' && start[YYCURSOR - start - 2] == '*') {
524+
token->opcode = XX_T_COMMENT;
525+
} else {
526+
// C comments like /* ... */
527+
token->opcode = XX_T_IGNORE;
531528
}
532-
return 0;
533-
}
534529
535-
COMMENT = ("/*"([^*]+|[*]+[^/*])*[*]*"*/");
536-
COMMENT {
537-
token->opcode = XX_T_IGNORE;
538-
token->value = estrndup(start, YYCURSOR - start - 1);
539-
token->len = YYCURSOR - start - 1;
540-
{
530+
if (token->opcode == XX_T_COMMENT && YYCURSOR - start > 5) {
531+
has_data = 1;
532+
start++;
533+
}
534+
535+
if (token->opcode == XX_T_IGNORE && YYCURSOR - start > 4) {
536+
has_data = 1;
537+
}
538+
539+
if (has_data == 1) {
540+
token->value = estrndup(start, YYCURSOR - start - 1);
541+
token->len = YYCURSOR - start - 1;
542+
541543
int k, ch = s->active_char;
542544
for (k = 0; k < (token->len - 1); k++) {
543545
if (token->value[k] == '\n') {
@@ -547,10 +549,20 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) {
547549
ch++;
548550
}
549551
}
552+
550553
s->active_char = ch;
554+
} else if (token->opcode == XX_T_COMMENT) {
555+
start++;
556+
token->value = estrndup(start, YYCURSOR - start - 1);
557+
token->len = YYCURSOR - start - 1;
558+
}
559+
560+
if (token->opcode == XX_T_IGNORE) {
561+
// Ignore data for C comments
562+
efree(token->value);
563+
token->len = 0;
551564
}
552-
efree(token->value);
553-
token->len = 0;
565+
554566
return 0;
555567
}
556568

tests/comments/dockblocks/empty.phpt

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
--TEST--
2+
Tests for empty dockblock
3+
--SKIPIF--
4+
<?php include(__DIR__ . '/../skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
var_dump(zephir_parse_file("/***/", '(eval code)'));
8+
var_dump(zephir_parse_file("/** */", '(eval code)'));
9+
var_dump(zephir_parse_file("/** */\n/***/", '(eval code)'));
10+
var_dump(zephir_parse_file("/**\n*/", '(eval code)'));
11+
var_dump(zephir_parse_file("/**//**\n*/", '(eval code)'));
12+
var_dump(zephir_parse_file("/*\n**//***/", '(eval code)'));
13+
?>
14+
--EXPECT--
15+
array(1) {
16+
[0]=>
17+
array(5) {
18+
["type"]=>
19+
string(7) "comment"
20+
["value"]=>
21+
string(3) "***"
22+
["file"]=>
23+
string(11) "(eval code)"
24+
["line"]=>
25+
int(1)
26+
["char"]=>
27+
int(1)
28+
}
29+
}
30+
array(1) {
31+
[0]=>
32+
array(5) {
33+
["type"]=>
34+
string(7) "comment"
35+
["value"]=>
36+
string(4) "** *"
37+
["file"]=>
38+
string(11) "(eval code)"
39+
["line"]=>
40+
int(1)
41+
["char"]=>
42+
int(4)
43+
}
44+
}
45+
array(2) {
46+
[0]=>
47+
array(5) {
48+
["type"]=>
49+
string(7) "comment"
50+
["value"]=>
51+
string(4) "** *"
52+
["file"]=>
53+
string(11) "(eval code)"
54+
["line"]=>
55+
int(2)
56+
["char"]=>
57+
int(0)
58+
}
59+
[1]=>
60+
array(5) {
61+
["type"]=>
62+
string(7) "comment"
63+
["value"]=>
64+
string(3) "***"
65+
["file"]=>
66+
string(11) "(eval code)"
67+
["line"]=>
68+
int(2)
69+
["char"]=>
70+
int(0)
71+
}
72+
}
73+
array(1) {
74+
[0]=>
75+
array(5) {
76+
["type"]=>
77+
string(7) "comment"
78+
["value"]=>
79+
string(4) "**
80+
*"
81+
["file"]=>
82+
string(11) "(eval code)"
83+
["line"]=>
84+
int(2)
85+
["char"]=>
86+
int(1)
87+
}
88+
}
89+
array(1) {
90+
[0]=>
91+
array(5) {
92+
["type"]=>
93+
string(7) "comment"
94+
["value"]=>
95+
string(4) "**
96+
*"
97+
["file"]=>
98+
string(11) "(eval code)"
99+
["line"]=>
100+
int(2)
101+
["char"]=>
102+
int(1)
103+
}
104+
}
105+
array(1) {
106+
[0]=>
107+
array(5) {
108+
["type"]=>
109+
string(7) "comment"
110+
["value"]=>
111+
string(3) "***"
112+
["file"]=>
113+
string(11) "(eval code)"
114+
["line"]=>
115+
int(2)
116+
["char"]=>
117+
int(2)
118+
}
119+
}

tests/comments/empty.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Tests for empty dockblock
3+
--SKIPIF--
4+
<?php include(__DIR__ . '/../skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
var_dump(zephir_parse_file("/**/", '(eval code)'));
8+
var_dump(zephir_parse_file("/**/\n\t \n/**/", '(eval code)'));
9+
?>
10+
--EXPECT--
11+
array(0) {
12+
}
13+
array(0) {
14+
}

0 commit comments

Comments
 (0)