Browse Source

Added NEWDOC

PECL
Dmitry Stogov 18 years ago
parent
commit
ddcf7a2f49
  1. 1
      NEWS
  2. 23
      Zend/tests/heredoc_001.phpt
  3. 23
      Zend/tests/heredoc_002.phpt
  4. 23
      Zend/tests/heredoc_003.phpt
  5. 23
      Zend/tests/heredoc_004.phpt
  6. 22
      Zend/tests/heredoc_005.phpt
  7. 23
      Zend/tests/heredoc_006.phpt
  8. 23
      Zend/tests/heredoc_007.phpt
  9. 17
      Zend/tests/heredoc_008.phpt
  10. 42
      Zend/tests/heredoc_009.phpt
  11. 32
      Zend/tests/heredoc_010.phpt
  12. 20
      Zend/tests/heredoc_011.phpt
  13. 11
      Zend/tests/nowdoc.inc
  14. 24
      Zend/tests/nowdoc_001.phpt
  15. 23
      Zend/tests/nowdoc_002.phpt
  16. 23
      Zend/tests/nowdoc_003.phpt
  17. 23
      Zend/tests/nowdoc_004.phpt
  18. 23
      Zend/tests/nowdoc_005.phpt
  19. 23
      Zend/tests/nowdoc_006.phpt
  20. 23
      Zend/tests/nowdoc_007.phpt
  21. 17
      Zend/tests/nowdoc_008.phpt
  22. 40
      Zend/tests/nowdoc_009.phpt
  23. 33
      Zend/tests/nowdoc_010.phpt
  24. 20
      Zend/tests/nowdoc_011.phpt
  25. 25
      Zend/tests/nowdoc_012.phpt
  26. 26
      Zend/tests/nowdoc_013.phpt
  27. 25
      Zend/tests/nowdoc_014.phpt
  28. 74
      Zend/tests/nowdoc_015.phpt
  29. 1
      Zend/zend_compile.c
  30. 4
      Zend/zend_highlight.c
  31. 3
      Zend/zend_language_parser.y
  32. 101
      Zend/zend_language_scanner.l

1
NEWS

@ -2,6 +2,7 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 20??, PHP 5.3.0
- Added and improved PHP syntax and semantics:
. Added NOWDOC. (Gwynne Raskind, Stas, Dmitry)
. Added "?:" operator. (Marcus)
. Added support for namespaces. (Dmitry, Stas, Gregory)
. Added support for Late Static Binding. (Dmitry, Etienne Kneuss)

23
Zend/tests/heredoc_001.phpt

@ -0,0 +1,23 @@
--TEST--
basic heredoc syntax
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is a heredoc test.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is another heredoc test.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is a heredoc test.
This is another heredoc test.

23
Zend/tests/heredoc_002.phpt

@ -0,0 +1,23 @@
--TEST--
basic binary heredoc syntax
--FILE--
<?php
require_once 'nowdoc.inc';
print b<<<ENDOFHEREDOC
This is a heredoc test.
ENDOFHEREDOC;
$x = b<<<ENDOFHEREDOC
This is another heredoc test.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is a heredoc test.
This is another heredoc test.

23
Zend/tests/heredoc_003.phpt

@ -0,0 +1,23 @@
--TEST--
simple variable replacement test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is heredoc test #$a.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is heredoc test #$b.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is heredoc test #1.
This is heredoc test #2.

23
Zend/tests/heredoc_004.phpt

@ -0,0 +1,23 @@
--TEST--
braces variable replacement test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is heredoc test #{$a}.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is heredoc test #{$b}.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is heredoc test #1.
This is heredoc test #2.

22
Zend/tests/heredoc_005.phpt

@ -0,0 +1,22 @@
--TEST--
unbraced complex variable replacement test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is heredoc test #s $a, $b, $c['c'], and $d->d.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is heredoc test #s $a, $b, $c['c'], and $d->d.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECTF--
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in %sheredoc_005.php on line 6

23
Zend/tests/heredoc_006.phpt

@ -0,0 +1,23 @@
--TEST--
braced complex variable replacement test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is heredoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is heredoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is heredoc test #s 1, 2, 3, and 4.
This is heredoc test #s 1, 2, 3, and 4.

23
Zend/tests/heredoc_007.phpt

@ -0,0 +1,23 @@
--TEST--
braced and unbraced complex variable replacement test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
This is heredoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
This is heredoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
This is heredoc test #s 1, 2, 3, and 4.
This is heredoc test #s 1, 2, 3, and 4.

17
Zend/tests/heredoc_008.phpt

@ -0,0 +1,17 @@
--TEST--
empty doc test (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--

42
Zend/tests/heredoc_009.phpt

@ -0,0 +1,42 @@
--TEST--
Torture the T_END_HEREDOC rules (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<ENDOFHEREDOC
ENDOFHEREDOC ;
ENDOFHEREDOC;
ENDOFHEREDOC
ENDOFHEREDOC
$ENDOFHEREDOC;
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
ENDOFHEREDOC ;
ENDOFHEREDOC;
ENDOFHEREDOC
ENDOFHEREDOC
$ENDOFHEREDOC;
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECTF--
Notice: Undefined variable: ENDOFHEREDOC in %s on line %d
ENDOFHEREDOC ;
ENDOFHEREDOC;
ENDOFHEREDOC
ENDOFHEREDOC
;
Notice: Undefined variable: ENDOFHEREDOC in %s on line %d
ENDOFHEREDOC ;
ENDOFHEREDOC;
ENDOFHEREDOC
ENDOFHEREDOC
;

32
Zend/tests/heredoc_010.phpt

@ -0,0 +1,32 @@
--TEST--
Torture the T_END_HEREDOC rules with variable expansions (heredoc)
--FILE--
<?php
require_once 'nowdoc.inc';
$fooledYou = '';
print <<<ENDOFHEREDOC
{$fooledYou}ENDOFHEREDOC{$fooledYou}
ENDOFHEREDOC{$fooledYou}
{$fooledYou}ENDOFHEREDOC
ENDOFHEREDOC;
$x = <<<ENDOFHEREDOC
{$fooledYou}ENDOFHEREDOC{$fooledYou}
ENDOFHEREDOC{$fooledYou}
{$fooledYou}ENDOFHEREDOC
ENDOFHEREDOC;
print "{$x}";
?>
--EXPECT--
ENDOFHEREDOC
ENDOFHEREDOC
ENDOFHEREDOC
ENDOFHEREDOC
ENDOFHEREDOC
ENDOFHEREDOC

20
Zend/tests/heredoc_011.phpt

@ -0,0 +1,20 @@
--TEST--
Heredocs can NOT be used as static scalars.
--FILE--
<?php
require_once 'nowdoc.inc';
class e {
const E = <<<THISMUSTERROR
If you see this, something's wrong.
THISMUSTERROR;
};
print e::E . "\n";
?>
--EXPECTF--
Parse error: syntax error, unexpected T_START_HEREDOC in %sheredoc_011.php on line 8

11
Zend/tests/nowdoc.inc

@ -0,0 +1,11 @@
<?php
// Common definitions for heredoc/nowdoc tests.
$a = 1;
$b = 2;
$c = array( 'c' => 3, );
class d { public function __construct() { $this->d = 4; } };
$d = new d;
?>

24
Zend/tests/nowdoc_001.phpt

@ -0,0 +1,24 @@
--TEST--
basic nowdoc syntax
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is a nowdoc test.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is another nowdoc test.
With another line in it.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is a nowdoc test.
This is another nowdoc test.
With another line in it.

23
Zend/tests/nowdoc_002.phpt

@ -0,0 +1,23 @@
--TEST--
basic binary nowdoc syntax
--FILE--
<?php
require_once 'nowdoc.inc';
print b<<<'ENDOFNOWDOC'
This is a nowdoc test.
ENDOFNOWDOC;
$x = b<<<'ENDOFNOWDOC'
This is another nowdoc test.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is a nowdoc test.
This is another nowdoc test.

23
Zend/tests/nowdoc_003.phpt

@ -0,0 +1,23 @@
--TEST--
simple variable replacement test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is nowdoc test #$a.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is nowdoc test #$b.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is nowdoc test #$a.
This is nowdoc test #$b.

23
Zend/tests/nowdoc_004.phpt

@ -0,0 +1,23 @@
--TEST--
braces variable replacement test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is nowdoc test #{$a}.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is nowdoc test #{$b}.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is nowdoc test #{$a}.
This is nowdoc test #{$b}.

23
Zend/tests/nowdoc_005.phpt

@ -0,0 +1,23 @@
--TEST--
unbraced complex variable replacement test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is nowdoc test #s $a, $b, $c['c'], and $d->d.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is nowdoc test #s $a, $b, $c['c'], and $d->d.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is nowdoc test #s $a, $b, $c['c'], and $d->d.
This is nowdoc test #s $a, $b, $c['c'], and $d->d.

23
Zend/tests/nowdoc_006.phpt

@ -0,0 +1,23 @@
--TEST--
braced complex variable replacement test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.

23
Zend/tests/nowdoc_007.phpt

@ -0,0 +1,23 @@
--TEST--
braced and unbraced complex variable replacement test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.

17
Zend/tests/nowdoc_008.phpt

@ -0,0 +1,17 @@
--TEST--
empty doc test (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--

40
Zend/tests/nowdoc_009.phpt

@ -0,0 +1,40 @@
--TEST--
Torture the T_END_NOWDOC rules (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
print <<<'ENDOFNOWDOC'
ENDOFNOWDOC ;
ENDOFNOWDOC;
ENDOFNOWDOC
ENDOFNOWDOC
$ENDOFNOWDOC;
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
ENDOFNOWDOC ;
ENDOFNOWDOC;
ENDOFNOWDOC
ENDOFNOWDOC
$ENDOFNOWDOC;
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
ENDOFNOWDOC ;
ENDOFNOWDOC;
ENDOFNOWDOC
ENDOFNOWDOC
$ENDOFNOWDOC;
ENDOFNOWDOC ;
ENDOFNOWDOC;
ENDOFNOWDOC
ENDOFNOWDOC
$ENDOFNOWDOC;

33
Zend/tests/nowdoc_010.phpt

@ -0,0 +1,33 @@
--TEST--
Torture the T_END_NOWDOC rules with variable expansions (nowdoc)
--FILE--
<?php
require_once 'nowdoc.inc';
$fooledYou = '';
print <<<'ENDOFNOWDOC'
{$fooledYou}ENDOFNOWDOC{$fooledYou}
ENDOFNOWDOC{$fooledYou}
{$fooledYou}ENDOFNOWDOC
ENDOFNOWDOC;
$x = <<<'ENDOFNOWDOC'
{$fooledYou}ENDOFNOWDOC{$fooledYou}
ENDOFNOWDOC{$fooledYou}
{$fooledYou}ENDOFNOWDOC
ENDOFNOWDOC;
print "{$x}";
?>
--EXPECT--
{$fooledYou}ENDOFNOWDOC{$fooledYou}
ENDOFNOWDOC{$fooledYou}
{$fooledYou}ENDOFNOWDOC
{$fooledYou}ENDOFNOWDOC{$fooledYou}
ENDOFNOWDOC{$fooledYou}
{$fooledYou}ENDOFNOWDOC

20
Zend/tests/nowdoc_011.phpt

@ -0,0 +1,20 @@
--TEST--
Nowdocs CAN be used as static scalars.
--FILE--
<?php
require_once 'nowdoc.inc';
class e {
const E = <<<'THISMUSTNOTERROR'
If you DON'T see this, something's wrong.
THISMUSTNOTERROR;
};
print e::E . "\n";
?>
--EXPECTF--
If you DON'T see this, something's wrong.

25
Zend/tests/nowdoc_012.phpt

@ -0,0 +1,25 @@
--TEST--
Test false labels
--FILE--
<?php
require_once 'nowdoc.inc';
$x = <<<'ENDOFNOWDOC'
This is a nowdoc test.
NOTREALLYEND;
Another line
NOTENDEITHER;
ENDOFNOWDOCWILLBESOON
Now let's finish it
ENDOFNOWDOC;
print "{$x}\n";
?>
--EXPECT--
This is a nowdoc test.
NOTREALLYEND;
Another line
NOTENDEITHER;
ENDOFNOWDOCWILLBESOON
Now let's finish it

26
Zend/tests/nowdoc_013.phpt

@ -0,0 +1,26 @@
--TEST--
Test whitespace following end of nowdoc
--INI--
highlight.string = #DD0000
highlight.comment = #FF8000
highlight.keyword = #007700
highlight.bg = #FFFFFF
highlight.default = #0000BB
highlight.html = #000000
--FILE--
<?php
$code = <<<'EOF'
<?php
$x = <<<'EOT'
some string
EOT
$y = 2;
?>
EOF;
highlight_string($code);
?>
--EXPECT--
<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code>

25
Zend/tests/nowdoc_014.phpt

@ -0,0 +1,25 @@
--TEST--
Highliting empty nowdoc
--INI--
highlight.string = #DD0000
highlight.comment = #FF8000
highlight.keyword = #007700
highlight.bg = #FFFFFF
highlight.default = #0000BB
highlight.html = #000000
--FILE--
<?php
$code = <<<'EOF'
<?php
$x = <<<'EOT'
EOT
$y = 2;
?>
EOF;
highlight_string($code);
?>
--EXPECT--
<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB"></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code>

74
Zend/tests/nowdoc_015.phpt

@ -0,0 +1,74 @@
--TEST--
Test nowdoc and line numbering
--FILE--
<?php
function error_handler($num, $msg, $file, $line, $vars) {
echo $line,"\n";
}
set_error_handler('error_handler');
trigger_error("line", E_USER_ERROR);
$x = <<<EOF
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
$x = <<<'EOF'
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
$x = <<<EOF
test
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
$x = <<<'EOF'
test
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
$x = <<<EOF
test1
test2
test3
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
$x = <<<'EOF'
test1
test2
test3
EOF;
var_dump($x);
trigger_error("line", E_USER_ERROR);
echo "ok\n";
?>
--EXPECT--
6
string(0) ""
10
string(0) ""
14
string(4) "test"
19
string(4) "test"
24
string(20) "test1
test2
test3
"
34
string(20) "test1
test2
test3
"
44
ok

1
Zend/zend_compile.c

@ -4642,6 +4642,7 @@ again:
retval = T_ECHO;
break;
case T_END_HEREDOC:
case T_END_NOWDOC:
efree(Z_STRVAL(zendlval->u.constant));
break;
case EOF:

4
Zend/zend_highlight.c

@ -150,6 +150,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
}
switch (token_type) {
case T_END_HEREDOC:
case T_END_NOWDOC:
zend_html_puts(token.value.str.val, token.value.str.len TSRMLS_CC);
break;
default:
@ -172,7 +173,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
efree(token.value.str.val);
break;
}
} else if (token_type == T_END_HEREDOC) {
} else if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
efree(token.value.str.val);
}
token.type = 0;
@ -222,6 +223,7 @@ ZEND_API void zend_strip(TSRMLS_D)
return;
case T_END_HEREDOC:
case T_END_NOWDOC:
zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
efree(token.value.str.val);
/* read the following character, either newline or ; */

3
Zend/zend_language_parser.y

@ -146,6 +146,8 @@
%token T_NAMESPACE
%token T_NS_C
%token T_DIR
%token T_START_NOWDOC
%token T_END_NOWDOC
%% /* Rules */
@ -721,6 +723,7 @@ common_scalar:
| T_METHOD_C { $$ = $1; }
| T_FUNC_C { $$ = $1; }
| T_NS_C { $$ = $1; }
| T_START_NOWDOC T_ENCAPSED_AND_WHITESPACE T_END_NOWDOC { $$ = $2; }
;

101
Zend/zend_language_scanner.l

@ -39,6 +39,9 @@
%x ST_HEREDOC
%x ST_START_HEREDOC
%x ST_END_HEREDOC
%x ST_NOWDOC
%x ST_START_NOWDOC
%x ST_END_NOWDOC
%x ST_LOOKING_FOR_PROPERTY
%x ST_LOOKING_FOR_VARNAME
%x ST_VAR_OFFSET
@ -965,6 +968,8 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLL
BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
HEREDOC_CHARS ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({HEREDOC_NEWLINE}+({HEREDOC_NON_LABEL}|{HEREDOC_LABEL_NO_NEWLINE})))
NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
%option noyylineno
%option noyywrap
%%
@ -2065,6 +2070,102 @@ HEREDOC_CHARS ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({
}
%{
/* BEGIN nowdoc */
%}
<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
int bprefix = (yytext[0] != '<') ? 1 : 0;
char *s;
CG(zend_lineno)++;
/* 3 is <<<, 2 is quotes, 1 is newline */
CG(heredoc_len) = yyleng-bprefix-3-2-1-(yytext[yyleng-2]=='\r'?1:0);
s = yytext+bprefix+3;
while ((*s == ' ') || (*s == '\t')) {
s++;
CG(heredoc_len)--;
}
s++; /* first quote */
CG(heredoc) = estrndup(s, CG(heredoc_len));
BEGIN(ST_START_NOWDOC);
return T_START_NOWDOC;
}
<ST_START_NOWDOC>{ANY_CHAR} {
yyless(0);
BEGIN(ST_NOWDOC);
}
<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
int label_len = yyleng - 1;
if (yytext[label_len-1]==';') {
label_len--;
}
if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
yyless(label_len-1);
yyleng = 0;
BEGIN(ST_END_NOWDOC);
ZVAL_EMPTY_STRING(zendlval);
return T_ENCAPSED_AND_WHITESPACE;
} else {
yyless(label_len);
yymore();
BEGIN(ST_NOWDOC);
}
}
<ST_NOWDOC>{NOWDOC_CHARS}*{NEWLINE}+{LABEL}";"?[\n\r] {
char *end = yytext + yyleng - 1;
if (end[-1] == ';') {
end--;
yyleng--;
}
if (yyleng > CG(heredoc_len) && !memcmp(end - CG(heredoc_len), CG(heredoc), CG(heredoc_len))) {
int len = yyleng - CG(heredoc_len) - 2; /* 2 for newline before and after label */
if (len > 0 && yytext[len - 1] == '\r' && yytext[len] == '\n') {
len--;
}
/* Go back before last label char, to match in ST_END_HEREDOC state */
yyless(yyleng - 2);
/* Subtract the remaining label length. yyleng must include newline
* before label, for zend_highlight/strip, tokenizer, etc. */
yyleng -= CG(heredoc_len) - 1;
CG(increment_lineno) = 1; /* For newline before label */
BEGIN(ST_END_NOWDOC);
HANDLE_NEWLINES(yytext, len);
zend_copy_value(zendlval, yytext, len);
zendlval->type = IS_STRING;
return T_ENCAPSED_AND_WHITESPACE;
} else {
/* Go back to end of label, so the next match works correctly in case of
* a variable or another label at the beginning of the next line */
yyless(yyleng - 1);
yymore();
}
}
<ST_END_NOWDOC>{ANY_CHAR} {
Z_STRVAL_P(zendlval) = CG(heredoc);
Z_STRLEN_P(zendlval) = CG(heredoc_len);
yytext = CG(heredoc);
yyleng = CG(heredoc_len);
CG(heredoc) = NULL;
CG(heredoc_len) = 0;
BEGIN(ST_IN_SCRIPTING);
return T_END_NOWDOC;
}
%{
/* END nowdoc */
%}
<ST_DOUBLE_QUOTES>["] {
BEGIN(ST_IN_SCRIPTING);
return '"';

Loading…
Cancel
Save