|
| 1 | +# About YAMLStar |
| 2 | + |
| 3 | +## Vision |
| 4 | + |
| 5 | +YAMLStar aims to be the best YAML loader available, with these key features: |
| 6 | + |
| 7 | +- **YAML 1.2 Spec Compliance**: 100% compliant with the YAML 1.2 specification |
| 8 | +- **Pure Clojure Parser**: No dependencies on SnakeYAML or other external parsers |
| 9 | +- **Cross-Language Consistency**: Identical behavior in 15+ languages via shared |
| 10 | + library |
| 11 | +- **Highly Configurable**: Plugin system for extensibility (coming in Phase 3) |
| 12 | +- **Lightweight**: Minimal dependencies, fast startup, small binaries |
| 13 | + |
| 14 | +## What Makes YAMLStar Different |
| 15 | + |
| 16 | +YAMLStar is designed from the ground up to provide a consistent YAML loading |
| 17 | +experience across all programming languages. |
| 18 | +Unlike traditional YAML libraries that are implemented separately for each |
| 19 | +language, YAMLStar uses a single core implementation compiled to a native |
| 20 | +shared library. |
| 21 | + |
| 22 | +### Key Advantages |
| 23 | + |
| 24 | +**Consistency Across Languages** |
| 25 | +: Every language binding uses the same underlying YAML parser, ensuring |
| 26 | + identical behavior everywhere. |
| 27 | + No more "it works in Python but not in Go" issues. |
| 28 | + |
| 29 | +**100% Spec Compliance** |
| 30 | +: Built on the pure Clojure YAML Reference Parser, YAMLStar implements the full |
| 31 | + YAML 1.2 specification without shortcuts or omissions. |
| 32 | + |
| 33 | +**Zero External Dependencies** |
| 34 | +: The core library depends only on Clojure itself. |
| 35 | + No SnakeYAML, libyaml, or other external YAML parsers. |
| 36 | + |
| 37 | +**Lightweight Design** |
| 38 | +: YAMLStar implements only what's needed for YAML loading. |
| 39 | + The 4-stage pipeline is ~80% lighter than YAMLScript's 7-stage pipeline. |
| 40 | + |
| 41 | +## Architecture |
| 42 | + |
| 43 | +YAMLStar uses a clean 4-stage pipeline to convert YAML text into native data |
| 44 | +structures: |
| 45 | + |
| 46 | +<div class="architecture-diagram"> |
| 47 | +<pre> |
| 48 | +YAML String (input) |
| 49 | + ↓ |
| 50 | +┌─────────────────────┐ |
| 51 | +│ Parser │ yamlstar.parser |
| 52 | +│ (Pure Clojure) │ - PEG grammar engine |
| 53 | +│ YAML 1.2 spec │ - 211 production rules |
| 54 | +└─────────────────────┘ - Event emission |
| 55 | + ↓ Event Stream |
| 56 | + [{:event "mapping_start"} |
| 57 | + {:event "scalar" :value "key"} |
| 58 | + {:event "scalar" :value "value"} |
| 59 | + {:event "mapping_end"}] |
| 60 | + ↓ |
| 61 | +┌─────────────────────┐ |
| 62 | +│ Composer │ yamlstar.composer |
| 63 | +│ (Stack-based) │ - Event→Node tree |
| 64 | +└─────────────────────┘ - Anchor/tag tracking |
| 65 | + ↓ Node Tree |
| 66 | + {:kind :mapping |
| 67 | + :value [[{:kind :scalar :value "key"} |
| 68 | + {:kind :scalar :value "value"}]]} |
| 69 | + ↓ |
| 70 | +┌─────────────────────┐ |
| 71 | +│ Resolver │ yamlstar.resolver |
| 72 | +│ (Tag resolution) │ - Tag inference (!!str, !!int, etc.) |
| 73 | +└─────────────────────┘ - Alias resolution |
| 74 | + ↓ Resolved Nodes |
| 75 | + {:kind :mapping :tag "!!map" |
| 76 | + :value [[{:kind :scalar :tag "!!str" :value "key"} |
| 77 | + {:kind :scalar :tag "!!str" :value "value"}]]} |
| 78 | + ↓ |
| 79 | +┌─────────────────────┐ |
| 80 | +│ Constructor │ yamlstar.constructor |
| 81 | +│ (Data conversion) │ - Node→Data |
| 82 | +└─────────────────────┘ - Type coercion |
| 83 | + ↓ |
| 84 | +Native Data: {"key" "value"} |
| 85 | +</pre> |
| 86 | +</div> |
| 87 | + |
| 88 | +### Pipeline Stages |
| 89 | + |
| 90 | +1. **Parser**: Converts YAML text into a stream of events using a PEG |
| 91 | + (Parsing Expression Grammar) implementation of the YAML 1.2 spec. |
| 92 | + |
| 93 | +2. **Composer**: Converts the flat event stream into a hierarchical node tree, |
| 94 | + tracking anchors and tags along the way. |
| 95 | + |
| 96 | +3. **Resolver**: Infers YAML types for untagged nodes using the YAML 1.2 Core |
| 97 | + Schema rules (null, bool, int, float, str). |
| 98 | + Also resolves anchor references to their aliased nodes. |
| 99 | + |
| 100 | +4. **Constructor**: Converts resolved nodes into native data structures for the |
| 101 | + target language (maps, lists, strings, numbers, etc.). |
| 102 | + |
| 103 | +## Comparison to YAMLScript |
| 104 | + |
| 105 | +YAMLStar is derived from YAMLScript but with a different focus: |
| 106 | + |
| 107 | +| Feature | YAMLScript | YAMLStar | |
| 108 | +|---------|-----------|----------| |
| 109 | +| **Purpose** | YAML + scripting language | Pure YAML loader | |
| 110 | +| **Runtime** | Includes SCI interpreter | No runtime evaluation | |
| 111 | +| **Pipeline** | 7 stages (parser → runtime) | 4 stages (parser → data) | |
| 112 | +| **Dependencies** | Heavy (Babashka, SCI, etc.) | Minimal (Clojure only) | |
| 113 | +| **Extensibility** | Built-in scripting | Plugin system (Phase 3) | |
| 114 | +| **Use Case** | Dynamic config, scripting | Static config loading | |
| 115 | + |
| 116 | +YAMLScript is excellent for configurations that need dynamic behavior, template |
| 117 | +expansion, or computation. |
| 118 | +YAMLStar is ideal when you need a lightweight, reliable YAML loader that |
| 119 | +behaves identically across all your applications. |
| 120 | + |
| 121 | +## Technical Details |
| 122 | + |
| 123 | +### YAML 1.2 Core Schema |
| 124 | + |
| 125 | +YAMLStar implements the YAML 1.2 Core Schema for type resolution: |
| 126 | + |
| 127 | +- **null**: `null`, `Null`, `NULL`, `~` |
| 128 | +- **bool**: `true`, `True`, `TRUE`, `false`, `False`, `FALSE` |
| 129 | +- **int**: `[-+]?[0-9]+` (base 10 only) |
| 130 | +- **float**: Decimal floats including `.inf`, `-.inf`, `.nan` |
| 131 | +- **str**: Everything else (default type) |
| 132 | + |
| 133 | +Explicit tags like `!!str`, `!!int`, `!!float`, `!!bool`, `!!null` override |
| 134 | +type inference. |
| 135 | + |
| 136 | +### Event Processing |
| 137 | + |
| 138 | +The parser emits a finite sequence of events: |
| 139 | + |
| 140 | +- `stream_start` / `stream_end` |
| 141 | +- `document_start` / `document_end` |
| 142 | +- `mapping_start` / `mapping_end` |
| 143 | +- `sequence_start` / `sequence_end` |
| 144 | +- `scalar` (with value, style, anchor, tag) |
| 145 | +- `alias` (reference to anchored node) |
| 146 | + |
| 147 | +The composer uses a stack-based algorithm to build the node tree from these |
| 148 | +events. |
| 149 | + |
| 150 | +### Multi-Document Support |
| 151 | + |
| 152 | +YAMLStar supports YAML streams with multiple documents separated by `---`: |
| 153 | + |
| 154 | +- `load(yaml)` - Returns the first document (or only document) |
| 155 | +- `load_all(yaml)` - Returns a list of all documents |
| 156 | + |
| 157 | +## Project Statistics |
| 158 | + |
| 159 | +- **Total Lines of Code**: ~5,700 (including grammar) |
| 160 | +- **Core Implementation**: ~500 lines (excluding parser) |
| 161 | +- **Grammar Rules**: 211 (YAML 1.2 spec) |
| 162 | +- **Test Coverage**: 23+ comprehensive tests |
| 163 | +- **Dependencies**: 2 (Clojure + data.json for FFI) |
| 164 | +- **Language Bindings**: 9 (Clojure, C#, Fortran, Go, Java, Node.js, Perl, |
| 165 | + Python, Rust) |
| 166 | + |
| 167 | +## Credits |
| 168 | + |
| 169 | +**Created by**: Ingy döt Net |
| 170 | + |
| 171 | +- Inventor of YAML |
| 172 | +- Creator of YAMLScript |
| 173 | +- Maintainer of the YAML Reference Parser |
| 174 | + |
| 175 | +**Built on**: |
| 176 | + |
| 177 | +- **YAML Specification** - Created by Ingy döt Net |
| 178 | +- **YAMLScript** - Clojure-based YAML + scripting language |
| 179 | +- **yaml-reference-parser** - Pure Clojure YAML 1.2 parser |
| 180 | +- **Clojure** - Rich Hickey's elegant functional language |
| 181 | + |
| 182 | +**License**: MIT License - See LICENSE file |
| 183 | + |
| 184 | +## Get Involved |
| 185 | + |
| 186 | +YAMLStar is open source and welcomes contributions: |
| 187 | + |
| 188 | +- **GitHub**: [github.com/yaml/yamlstar](https://github.com/yaml/yamlstar) |
| 189 | +- **Issues**: Report bugs or request features |
| 190 | +- **Pull Requests**: Contribute code or documentation |
| 191 | +- **Discussions**: Share ideas and ask questions |
| 192 | + |
| 193 | +Join us in making YAML great again! 🌟 |
0 commit comments