Neon with AST parser and Format-preserving Printing
- David Grudl
- Nette Core | 8218
NEON has a completely rewritten parser that generates an AST tree. Even the export uses AST trees. This gives the library a few new features.
This already works in version 3.3.0, only the classes listed are marked
as @internal
because the interface may still change.
AST parser
Parsing text into AST nodes can be done using:
$input = '
hello: world
arr: [1, 2, 3]
';
$decoder = new Nette\Neon\Decoder;
$node = $decoder->parseToNode($input);
Finish processing and return a PHP value can be done with
toValue()
:
$data = $node->toValue(); // ['hello' => 'world', 'arr' => [1, 2, 3]]
Or conversely, to generate the NEON format can be done using
toString()
:
$output = $node->toString();
Which returns a string essentially identical to $input
.
You can iterate (traverse) over individual nodes and modify their values. For
example, this is how to add a key of the form key#
to all elements
in the array if they don't have a key:
use Nette\Neon\Node;
$visitor = function (Node $node) {
if ($node instanceof Node\ArrayNode) {
foreach ($node->items as $i => $item) {
$item->key ??= new Node\LiteralNode("key$i");
}
}
};
$node = $decoder->parseToNode($input);
$traverser = new Nette\Neon\Traverser;
$node = $traverser->traverse($node, $visitor);
echo $node->toString();
This would change the original $input
to:
hello: world
arr: {key0: 1, key1: 2, key2: 3}
Format-preserving Printing
The new parser gives the possibility to create format-preserving printing as well. This is implemented in the test branch for now.
Source file foo.neon
:
# List of users
users: [1, 2, 3, 4]
# Revision v0.0.1
We update its contents while preserving the formatting:
// read & parse content
$content = file_get_contents('foo.neon');
$data = Nette\Neon\Neon::decode($content);
// update data
$data->users[] = 5;
// create updated file
$output = Nette\Neon\Neon::update($content, $data);
file_put_contents('foo.neon', $output);
Writes a new foo.neon
:
# List of users
users: [1, 2, 3, 4, 5]
# Revision v0.0.1