RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
* The ending label no longer has to be followed by a semicolon or
newline. Any non-label character is fine.
* The ending label may be indented. The indentation will be stripped
from all lines in the heredoc/nowdoc string.
Lexing of heredoc strings performs a scan-ahead to determine the
indentation of the ending label, so that the correct amount of
indentation can be removed when calculting the semantic values for
use by the parser. This makes the implementation quite a bit more
complicated than we would like :/
In the following piece of code:
```php
function from1234($x) {
return $x;
}
function foo($x) {
yield from1234($x);
}
```
The statement inside foo is taken as `yield from` `1234($x)`
which is neither the intent, nor even legal syntax for an fcall.
Do a lookahead for breaking non-label characters after the
`yield from` and only accept it if they occur.
Introduce an on_event_context passed to the on_event hook. Use this
context to pass along the token array. Previously this was stored
in a non-tls global :/
This slightly improves calls to regular function and method calls in cost of a bit slower generator initialization.
Separate call frame for generators, allocated on heap, now created by ZEND_GENERATOR_CREATE instruction.
This turned out to be rather inconvenient after all. Instead just
return the same output we did on PHP 5. If people want to have an
error, use TOKEN_PARSE.
Added Throwable interface that exceptions must
implement in order to be thrown. BaseException
was removed, EngineException renamed to
Error, and TypeException and ParseException
renamed to TypeError and ParseError. Exception
and Error no longer extend a common base
class, rather they both implement the Throwable
interface.
we basically added a mechanism to store the token stream during parsing
and exposed the entire parser stack on the tokenizer extension through
an opt in flag: token_get_all($src, TOKEN_PARSE).
this change allows easy future language enhancements regarding context
aware parsing & scanning without further maintance on the tokenizer
extension while solves known inconsistencies "parseless" tokenizer
extension has when it handles `__halt_compiler()` presence.
The implementation has no regression risks, has an even smaller footprint
compared to the previous attempt involving a pure lexical approach, is higly
predictable and higly configurable.
To turn a word semi-reserved you only need to edit the "SEMI_RESERVED" parser rule,
it's an inclusive list of all the words that should be matched as T_STRING on specific contexts.
Example:
```
method_modifiers function returns_ref indentifier '(' parameter_list ')' ...
```
instead of:
```
method_modifiers function returns_ref T_STRING '(' parameter_list ')' ...
```
TODO: port ext tokenizer