package yamlx

  1. Overview
  2. Docs
Pure-OCaml YAML 1.2/1.1 parser with a lossless, comment-preserving AST

Install

dune-project
 Dependency

Authors

Maintainers

Sources

yamlx-0.3.0.tbz
sha256=f691a9e174828cc130b14a87b70a322c129351d3e399871ca9a53774b9205738
sha512=ba0e837f1773ba0b09cd0d9720c033f9b0d6b9816dbad8cb9f3b167cac6ae855d6b8fd39db2956e91f575e886689db38324a5e879593127b3e726771151a2a4b

Description

YAMLx is a pure-OCaml YAML 1.2 library. It passes all 371 tests from the yaml-test-suite and has no C bindings or external runtime dependencies. The parsed node tree preserves scalar styles, flow vs. block collection style, tags, anchors, source positions, and comments. A pretty-printer can round-trip the AST back to YAML. A typed-value resolver applies the YAML 1.2 JSON schema and returns Null / Bool / Int / Float / String / Seq / Map values. Structured errors carry line, column, and byte-offset information.

YAMLx is currently released under the AGPL. A commercial license and a path to a fully permissive ISC license are available โ€” see FUNDING.md.

Tags

yaml parser serialization

Published: 24 Apr 2026

README

YAMLx

A pure-OCaml YAML 1.2 and 1.1 library with a lossless, comment-preserving AST.

This is AI-assisted software, fully owned and maintained by Martin Jambon.

๐Ÿ‘‰ API Documentation

Features

  • Full YAML 1.2 compliance โ€” passes all 371 tests from the yaml-test-suite.
  • Pure OCaml โ€” no C bindings, no external runtime dependencies.
  • Lossless AST โ€” the parsed node tree preserves scalar styles (plain, 'single-quoted', "double-quoted", | literal, > folded), flow vs. block collection style, tags, anchors, and source positions.
  • Best-effort comment preservation โ€” standalone (head) comments before a node, inline (line) comments after a value, and trailing (foot) comments after the last item of a block collection are attached to the nearest node and re-emitted by the printer.
  • Pretty-printer โ€” Nodes.to_yaml serializes a node list back to a YAML string, preserving all of the above.
  • Plain-YAML printer โ€” Nodes.to_plain_yaml_exn produces a restricted subset with no anchors, no aliases (expanded inline), no tags, no flow collections, and no complex mapping keys โ€” the fragment of YAML that most people recognize on sight.
  • Typed-value resolver โ€” Values.of_yaml applies the YAML 1.2 JSON schema and returns value list with Null | Bool | Int | Float | String | Seq | Map constructors.
  • Multi-document streams โ€” both the node and value APIs handle streams containing more than one ----separated document.
  • Correct anchor scoping โ€” anchors are document-local; an alias in document N cannot refer to an anchor defined in document Nโˆ’1.
  • Structured errors โ€” Scan_error and Parse_error carry a pos record with line, column, and byte offset. catch_errors wraps any of these into a (_, string) result with a human-readable message, optionally prefixed with a file name.
  • Command-line tool โ€” the yamlx binary reads YAML from a file or stdin and prints it in one of several formats (see below).

Quick start

(* Resolve to typed values โ€” returns (value list, string) result *)
match YAMLx.Values.of_yaml "answer: 42\nflag: true" with
| Ok [ Map (_, [(_, String (_, "answer"), Int (_, 42L));
               (_, String (_, "flag"),   Bool (_, true))]) ] -> ...
| _ -> ...

(* Read from a file; errors include the file name *)
match YAMLx.Values.of_yaml_file "config.yaml" with
| Ok values -> ...
| Error msg -> prerr_endline msg  (* "file config.yaml, line 3, col 5: ..." *)

(* Expect exactly one document *)
match YAMLx.Values.one_of_yaml input with
| Ok value  -> ...
| Error msg -> ...

(* Round-trip through the lossless AST *)
match YAMLx.Nodes.of_yaml input with
| Ok nodes -> print_string (YAMLx.Nodes.to_yaml nodes)
| Error msg -> ...

(* Strip YAML-specific features *)
match YAMLx.Nodes.of_yaml input with
| Ok nodes ->
    (match YAMLx.catch_errors (fun () ->
         YAMLx.Nodes.to_plain_yaml_exn nodes) with
    | Ok plain -> print_string plain
    | Error msg -> ...)
| Error msg -> ...

Command-line tool

yamlx [-f FORMAT] [FILE]

Output formats (-f FORMAT):
  yaml        Re-emit YAML, preserving styles and comments (default)
  plain       Plain YAML: aliases expanded, tags stripped, block-only
  value       Typed-value tree: Null / Bool / Int / Float / String / Seq / Map
  value-noloc Same as value but without source locations
  node        Full AST: anchors, tags, styles, locations, comments
  node-noloc  Same as node but without source locations and heights
  events      yaml-test-suite event-tree notation (mainly for debugging)

Options:
  --strict    With -f plain: raise an error on tags instead of stripping them

Comment preservation

Comments are captured on a best-effort basis during scanning and attached to the AST after parsing:

# head comment (attached to the node that follows)
key: value  # line comment (attached to the scalar)
list:
  - a
  - b
  # foot comment (attached to the sequence, after the last item)

Comments inside flow collections ([...], {...}) and on block scalar header lines (key: | # this) are not captured.

Pipeline

Reader โ†’ Scanner โ†’ Parser โ†’ Composer โ†’ Resolver
  • Reader โ€” UTF-8 / UTF-16 / UTF-32 input normalization.
  • Scanner โ€” tokenization, indentation, flow-level tracking, comment capture.
  • Parser โ€” token stream โ†’ event stream (YAML grammar).
  • Composer โ€” events โ†’ node graph (anchor/alias resolution).
  • Resolver โ€” nodes โ†’ typed value tree (YAML 1.2 JSON schema).

License

YAMLx is currently released under the AGPL. There is an ongoing fundraiser: once a funding goal is reached, the license will switch to the permissive ISC license for everyone. Donors above a certain threshold receive an immediate commercial license. See FUNDING.md for details.

References

Dependencies (3)

  1. ppx_deriving
  2. ocaml >= "4.14.0"
  3. dune >= "3.20"

Dev Dependencies (4)

  1. odoc with-doc
  2. yaml dev
  3. afl-persistent dev
  4. testo with-test

Used by (1)

  1. atd-yamlx

Conflicts

None