Partial Parsing
Partial parsing allows reading a type grammar embedded in other arbitrary data, without requiring the full input to be a valid type statement.
This is convenient, for example, for analyzing phpdoc (docblocks): a @return annotation contains a type declaration followed by a free-text description, and there is no delimiter between the two other than "the type grammar stops making sense here".
Unlike parse(), which either returns a fully valid TypeNode or throws, TypeParser::partial() always returns a TypeLang\Parser\Partial\ParsedResult, and which of the three it is says how much of the source the grammar described.
- SuccessfulParsedResult
The source is a type whole, so the reading stopped at the very end of it. Carries the
$typebuilt out of it and the$offsetthe reading stopped at.- PartialParsedResult
The grammar described the beginning of the source alone. This is a successful result as well, since a type has been built either way — the rest of the source simply begins at the
$offset.- FailureParsedResult
The source opens no type at all, so nothing has been built of it. Carries the
$messageof what stands in the way, the$position(line and column) and the$offsetthe reading stopped at.
Basic Usage
$result->offset points right after the last byte that was actually consumed while building $result->type — including any trailing whitespace that belongs to it. Everything from that offset onward is simply whatever was left in the source:
Parsing a Docblock Annotation
Let's parse the contents of a " @return " docblock. The same technique applies to any other annotation that embeds a type followed by free text.
The description can then be recovered from the reported offset:
Recovering from Incomplete Constructs
Partial parsing does not attempt to repair broken syntax — it stops at the last point where a complete sub-rule was matched and treats everything past it as trailing content, however implausible that trailing content looks.
Here the unterminated { of the shape-fields list is never entered, so the parser falls back to the last valid statement — the bare array named type — and reports offset 5, right before the {.
Validation
Where the type itself is of no use and the only question is whether the source is one, TypeParser::validate() asks exactly that and builds nothing. It returns a TypeLang\Parser\Validation\CheckResult, and which of the three it is answers the question.
- SuccessfulCheckResult
The source is a type whole, so nothing stands in the way of it.
- FailureCheckResult
The source is no type of its own. Carries the
$messageof what stands in the way, the$position(line and column) and the$offsetthe reading stopped at.- PartialCheckResult
The grammar described the beginning of the source alone. This is a failure as well, since a check asks about the source whole, and the rest of it begins at the
$offset.