Skip to content

Commit 4f484d3

Browse files
authored
YAML Conformance Tests and Fixes (#2305)
* YAML Conformance Tests and Fixes * Update yaml_conformance.cpp * Update yaml_conformance.cpp * indent_stack for yaml_context * detect_nested_value_indent * anchors * documentation for anchors and aliases * fixes * Update yaml_conformance.cpp * More passing anchor tests * fix more anchor failures * Whitespace around colon in mappings * More yaml conformance * More passing * conformance * More yaml parse fixes * more yaml conformance * Much more yaml conformance * more yaml conformance * progress * conformance tests passing * More write tests * Block scalars are not valid inside flow collections * Reduce duplication with parse_node_properties * avoid head allocations for anchor lookups * Update read.hpp * inline_value_has_plain_mapping_indicator * more testing * concrete struct parsing tests * Update yaml_conformance_struct.cpp
1 parent a67f6f0 commit 4f484d3

File tree

10 files changed

+13713
-515
lines changed

10 files changed

+13713
-515
lines changed

docs/yaml.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,18 +315,122 @@ auto ec = glz::read_yaml(value, yaml);
315315

316316
- `!!int` is valid for floating-point types (widening conversion allowed)
317317
- `!!float` is NOT valid for integer types
318-
- Unknown or custom tags (e.g., `!mytag`, `!!custom`) produce `feature_not_supported` error
318+
- Unknown or custom tags (e.g., `!mytag`, `!!custom`) are ignored and values parse normally
319+
- Malformed tags (e.g., unterminated `!<...` or invalid tag token syntax) produce `syntax_error`
320+
321+
## Anchors and Aliases
322+
323+
Glaze supports YAML anchors (`&name`) and aliases (`*name`), which let you define a value once and reference it elsewhere in the document. This is useful for avoiding repetition in configuration files.
324+
325+
### Basic Usage
326+
327+
```yaml
328+
defaults: &defaults
329+
timeout: 30
330+
retries: 3
331+
332+
production:
333+
host: prod.example.com
334+
<<: *defaults # Not yet supported (merge keys)
335+
336+
# Simple scalar anchors and aliases:
337+
database_host: &db_host db.example.com
338+
primary: *db_host
339+
replica: *db_host
340+
```
341+
342+
### Scalar Anchors
343+
344+
Anchor a scalar value and reuse it via alias:
345+
346+
```yaml
347+
first: &name Alice
348+
second: *name
349+
```
350+
351+
Parses into `{"first": "Alice", "second": "Alice"}`. This works with all scalar types: strings, numbers, booleans, and enums.
352+
353+
```cpp
354+
std::string yaml = R"(
355+
anchor: &val 42
356+
alias: *val)";
357+
std::map<std::string, int> obj{};
358+
auto ec = glz::read_yaml(obj, yaml);
359+
// obj["anchor"] == 42, obj["alias"] == 42
360+
```
361+
362+
### Anchors on Collections
363+
364+
Anchors can be placed on flow-style sequences and mappings:
365+
366+
```yaml
367+
# Flow mapping anchor
368+
defaults: &cfg {x: 1, y: 2}
369+
copy: *cfg
370+
371+
# Flow sequence anchor
372+
items: &list [a, b, c]
373+
more: *list
374+
```
375+
376+
```cpp
377+
std::string yaml = R"(
378+
items: &s [10, 20, 30]
379+
copy: *s)";
380+
std::map<std::string, std::vector<int>> obj{};
381+
auto ec = glz::read_yaml(obj, yaml);
382+
// obj["items"] == {10, 20, 30}, obj["copy"] == {10, 20, 30}
383+
```
384+
385+
### Anchor Override
386+
387+
Redefining an anchor replaces the stored value. Aliases always resolve to the most recent definition:
388+
389+
```yaml
390+
a: &x first
391+
b: *x # "first"
392+
c: &x second
393+
d: *x # "second"
394+
```
395+
396+
### Anchors in Sequences
397+
398+
```yaml
399+
- &a hello
400+
- &b world
401+
- *a # "hello"
402+
- *b # "world"
403+
```
404+
405+
### Error Handling
406+
407+
An alias referencing an undefined anchor produces a `syntax_error`:
408+
409+
```cpp
410+
std::string yaml = "value: *undefined";
411+
glz::generic parsed{};
412+
auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
413+
// ec is truthy — undefined alias
414+
```
415+
416+
### Current Anchor Limitations
417+
418+
- **Merge keys** (`<<: *alias`) are not yet supported
419+
- **Anchors on empty/null nodes** (`key: &anchor` with no value) are not yet resolved via alias
420+
- **Aliases as mapping keys** (`*alias: value`) have limited support
421+
- **Anchors on block-style collections** (block mappings/sequences on subsequent lines) have limited support; flow-style anchors are fully supported
422+
- **Tag + anchor combinations** (`!!tag &anchor value`) are not supported together
319423

320424
## Limitations
321425

322426
The current YAML implementation has some limitations compared to the full YAML 1.2 specification:
323427

324428
### Not Supported
325429

326-
- **Anchors and aliases** (`&anchor`, `*alias`) - These will produce a `feature_not_supported` error
327430
- **Custom tags** (`!mytag`) - Only YAML Core Schema tags are supported
328431
- **Multi-document streams** - Only single documents are supported
329432
- **Complex keys** - Only simple scalar keys are supported
433+
- **Merge keys** (`<<: *alias`) - Not yet supported
330434

331435
### Tab Indentation
332436

0 commit comments

Comments
 (0)