My agentic slop goes here. Not intended for anyone else!

more

Changed files
+331 -117
yaml
ocaml-yamle
+32
yaml/ocaml-yamle/bin/dune
···
(executable
(name test_empty_final)
(libraries yamle))
···
(executable
(name test_empty_final)
(libraries yamle))
+
+
(executable
+
(name test_block_debug)
+
(libraries yamle))
+
+
(executable
+
(name test_failing)
+
(libraries yamle))
+
+
(executable
+
(name test_debug_cases)
+
(libraries yamle))
+
+
(executable
+
(name test_seq_comment)
+
(libraries yamle))
+
+
(executable
+
(name test_rzp5_exact)
+
(libraries yamle))
+
+
(executable
+
(name test_indent_comment)
+
(libraries yamle))
+
+
(executable
+
(name test_tokens_debug)
+
(libraries yamle))
+
+
(executable
+
(name test_error_detail)
+
(libraries yamle))
+2
yaml/ocaml-yamle/lib/error.ml
···
| Invalid_yaml_version of string
| Invalid_tag_directive of string
| Reserved_directive of string
(* Parser errors *)
| Unexpected_token of string
···
| Invalid_yaml_version s -> Printf.sprintf "invalid YAML version: %s" s
| Invalid_tag_directive s -> Printf.sprintf "invalid TAG directive: %s" s
| Reserved_directive s -> Printf.sprintf "reserved directive: %s" s
| Unexpected_token s -> Printf.sprintf "unexpected token: %s" s
| Expected_document_start -> "expected document start '---'"
| Expected_document_end -> "expected document end '...'"
···
| Invalid_yaml_version of string
| Invalid_tag_directive of string
| Reserved_directive of string
+
| Illegal_flow_key_line (** Key and : must be on same line in flow context *)
(* Parser errors *)
| Unexpected_token of string
···
| Invalid_yaml_version s -> Printf.sprintf "invalid YAML version: %s" s
| Invalid_tag_directive s -> Printf.sprintf "invalid TAG directive: %s" s
| Reserved_directive s -> Printf.sprintf "reserved directive: %s" s
+
| Illegal_flow_key_line -> "key and ':' must be on the same line in flow context"
| Unexpected_token s -> Printf.sprintf "unexpected token: %s" s
| Expected_document_start -> "expected document start '---'"
| Expected_document_end -> "expected document end '...'"
+6
yaml/ocaml-yamle/lib/parser.ml
···
push_state t Block_mapping_value;
parse_node t ~block:true ~indentless:true
end
| Token.Block_end ->
skip_token t;
t.state <- pop_state t;
Event.Mapping_end, tok.span
| _ ->
Error.raise_span tok.span Expected_key
(** Parse block mapping value *)
···
push_state t Block_mapping_value;
parse_node t ~block:true ~indentless:true
end
+
(* Handle value without explicit key - key is empty/null *)
+
| Token.Value ->
+
t.state <- Block_mapping_value;
+
empty_scalar_event ~anchor:None ~tag:None tok.span
| Token.Block_end ->
skip_token t;
t.state <- pop_state t;
Event.Mapping_end, tok.span
| _ ->
+
Printf.eprintf "DEBUG parser parse_block_mapping_key: unexpected token at %d:%d\n%!"
+
tok.span.start.line tok.span.start.column;
Error.raise_span tok.span Expected_key
(** Parse block mapping value *)
+198 -117
yaml/ocaml-yamle/lib/scanner.ml
···
mutable document_has_content : bool; (** True if we've emitted content tokens in current document *)
mutable adjacent_value_allowed_at : Position.t option; (** Position where adjacent : is allowed *)
mutable pending_value : bool; (** True if we've emitted a KEY and are waiting for VALUE *)
}
let create input =
···
document_has_content = false;
adjacent_value_allowed_at = None;
pending_value = false;
}
let of_string s = create (Input.of_string s)
···
let save_simple_key t =
if t.allow_simple_key then begin
(* A simple key is required only if we're in a block context,
-
at the current indentation level, AND we have an active indent *)
let required = t.flow_level = 0 &&
-
t.indent_stack <> [] &&
-
current_indent t = column t - 1 in
let sk = {
sk_possible = true;
sk_required = required;
···
(* Just ! followed by suffix *)
("!", Buffer.contents buf ^ scan_tag_suffix t))
in
let span = Span.make ~start ~stop:(Input.mark t.input) in
(handle, suffix, span)
···
let start = Input.mark t.input in
ignore (Input.next t.input); (* consume opening single-quote *)
let buf = Buffer.create 64 in
let rec loop () =
match Input.peek t.input with
| None -> Error.raise_at start Unclosed_single_quote
···
(* Check for escaped quote ('') *)
(match Input.peek t.input with
| Some '\'' ->
Buffer.add_char buf '\'';
ignore (Input.next t.input);
loop ()
-
| _ -> ())
| Some '\n' | Some '\r' ->
Input.consume_break t.input;
-
(* Fold line break to space unless at start of content *)
-
if Buffer.length buf > 0 then
-
Buffer.add_char buf ' ';
(* Skip leading whitespace on next line *)
while Input.next_is_blank t.input do
ignore (Input.next t.input)
done;
-
(* Check for document boundary - this terminates the quoted string *)
if Input.at_document_boundary t.input then
Error.raise_at start Unclosed_single_quote;
loop ()
| Some c ->
Buffer.add_char buf c;
ignore (Input.next t.input);
loop ()
···
(Invalid_block_scalar_header "expected newline after header");
let base_indent = current_indent t in
let content_indent = ref (
match !explicit_indent with
| Some n ->
-
(* base_indent is a column (1-indexed), convert to indent level (0-indexed) *)
let base_level = max 0 (base_indent - 1) in
base_level + n
| None -> 0 (* Will be determined by first non-empty line *)
···
(* Line starts with fewer spaces than content_indent - dedented *)
!spaces_skipped
end else if Input.next_is_blank t.input then begin
-
(* Line has spaces beyond content_indent - check if rest is only blanks *)
-
let idx = ref 0 in
-
let is_empty = ref false in
-
while not !is_empty do
-
match Input.peek_nth t.input !idx with
-
| Some c when Input.is_blank c -> incr idx
-
| Some c when Input.is_break c -> is_empty := true
-
| _ -> is_empty := true (* Not a break, so has content *)
-
done;
-
(* Check if we found a break (empty line) or content *)
-
(match Input.peek_nth t.input (!idx) with
-
| None | Some '\n' | Some '\r' ->
-
(* Empty line - preserve spaces for literal scalars *)
-
if literal then begin
-
while Input.next_is_blank t.input do
-
Buffer.add_char trailing_breaks ' ';
-
ignore (Input.next t.input)
-
done
-
end else begin
-
while Input.next_is_blank t.input do
-
ignore (Input.next t.input)
-
done
-
end;
-
Buffer.add_char trailing_breaks '\n';
-
Input.consume_break t.input;
-
skip_to_content_indent ()
-
| _ ->
-
(* Has content *)
-
!content_indent)
end else
!content_indent
end else begin
-
(* Implicit indent - skip empty lines without consuming spaces *)
if Input.next_is_break t.input then begin
Buffer.add_char trailing_breaks '\n';
Input.consume_break t.input;
skip_to_content_indent ()
-
end else if Input.next_is_blank t.input then begin
-
(* Check if line is empty *)
let idx = ref 0 in
while match Input.peek_nth t.input !idx with
-
| Some c when Input.is_blank c -> incr idx; true
| _ -> false
do () done;
match Input.peek_nth t.input (!idx) with
| None | Some '\n' | Some '\r' ->
-
(* Empty line *)
-
while Input.next_is_blank t.input do
ignore (Input.next t.input)
done;
Buffer.add_char trailing_breaks '\n';
Input.consume_break t.input;
skip_to_content_indent ()
| _ ->
-
(* Has content - don't consume anything, return 0 as we haven't skipped *)
0
end else
-
(* Not at break or blank - return 0 *)
0
end
in
···
(* Determine content indent from first content line (implicit case) *)
let first_line = !content_indent = 0 in
-
if !content_indent = 0 then begin
-
if line_indent <= base_indent then begin
-
(* No content - restore position conceptually *)
-
()
-
end else
-
content_indent := line_indent
-
end;
-
if line_indent < !content_indent then begin
-
(* Dedented - done with content *)
-
()
-
end else begin
-
(* Check if current line is "more indented" (has extra indent beyond content_indent) *)
-
let trailing_blank = line_indent > !content_indent in
(* Add trailing breaks to buffer *)
if Buffer.length buf > 0 then begin
···
let span = Span.make ~start ~stop:(Input.mark t.input) in
let token = if indicator = "---" then Token.Document_start else Token.Document_end in
(* Reset document content flag after document end marker *)
-
if indicator = "..." then
t.document_has_content <- false;
emit t span token
and fetch_directive t =
···
if t.flow_level = 0 then
t.flow_indent <- column t;
t.flow_level <- t.flow_level + 1;
t.allow_simple_key <- true;
t.simple_keys <- None :: t.simple_keys;
t.document_has_content <- true;
···
and fetch_flow_collection_end t token_type =
remove_simple_key t;
t.flow_level <- t.flow_level - 1;
t.simple_keys <- (match t.simple_keys with _ :: rest -> rest | [] -> []);
t.allow_simple_key <- false;
let start = Input.mark t.input in
···
| None -> false)
and fetch_value t =
(* Check for simple key *)
-
(match t.simple_keys with
-
| Some sk :: _ when sk.sk_possible ->
-
(* Insert KEY token before the simple key value *)
-
let key_span = Span.point sk.sk_position in
-
let key_token = { Token.token = Token.Key; span = key_span } in
-
(* We need to insert at the right position *)
-
let tokens = Queue.to_seq t.tokens |> Array.of_seq in
-
Queue.clear t.tokens;
-
let insert_pos = sk.sk_token_number - t.tokens_taken in
-
Array.iteri (fun i tok ->
-
if i = insert_pos then Queue.add key_token t.tokens;
-
Queue.add tok t.tokens
-
) tokens;
-
if insert_pos >= Array.length tokens then
-
Queue.add key_token t.tokens;
-
t.token_number <- t.token_number + 1;
-
t.pending_value <- true; (* We've inserted a KEY token, now waiting for VALUE *)
-
(* Roll indent for implicit block mapping *)
-
if t.flow_level = 0 then begin
-
let col = sk.sk_position.column in
-
if roll_indent t col ~sequence:false then begin
-
let span = Span.point sk.sk_position in
-
(* Insert block mapping start before key *)
-
let bm_token = { Token.token = Token.Block_mapping_start; span } in
-
let tokens = Queue.to_seq t.tokens |> Array.of_seq in
-
Queue.clear t.tokens;
-
Array.iteri (fun i tok ->
-
if i = insert_pos then Queue.add bm_token t.tokens;
-
Queue.add tok t.tokens
-
) tokens;
-
if insert_pos >= Array.length tokens then
-
Queue.add bm_token t.tokens;
-
t.token_number <- t.token_number + 1
-
end
-
end;
-
t.simple_keys <- None :: (List.tl t.simple_keys)
-
| _ ->
-
(* No simple key - this is a complex value (or empty key) *)
-
if t.flow_level = 0 then begin
-
if not t.allow_simple_key then
-
Error.raise_at (Input.mark t.input) Expected_key;
-
let col = column t in
-
if roll_indent t col ~sequence:false then begin
-
let span = Span.point (Input.mark t.input) in
-
emit t span Token.Block_mapping_start
-
end;
-
(* Emit KEY token for empty key case (e.g., ": value") only if we don't already have a pending KEY *)
-
if not t.pending_value then begin
-
let span = Span.point (Input.mark t.input) in
-
emit t span Token.Key;
-
t.pending_value <- true
-
end
-
end);
remove_simple_key t;
-
(* In block context, allow_simple_key becomes true only after a line break,
-
not immediately after ':'. This prevents constructs like "key: - a".
-
The line break handling in skip_to_next_token will set it to true. *)
-
t.allow_simple_key <- false;
t.document_has_content <- true;
let start = Input.mark t.input in
ignore (Input.next t.input);
···
mutable document_has_content : bool; (** True if we've emitted content tokens in current document *)
mutable adjacent_value_allowed_at : Position.t option; (** Position where adjacent : is allowed *)
mutable pending_value : bool; (** True if we've emitted a KEY and are waiting for VALUE *)
+
mutable flow_mapping_stack : bool list; (** Stack of whether each flow level is a mapping *)
}
let create input =
···
document_has_content = false;
adjacent_value_allowed_at = None;
pending_value = false;
+
flow_mapping_stack = [];
}
let of_string s = create (Input.of_string s)
···
let save_simple_key t =
if t.allow_simple_key then begin
(* A simple key is required only if we're in a block context,
+
at the current indentation level, AND the current indent needs a block end.
+
This matches saphyr's logic and prevents false positives for values. *)
let required = t.flow_level = 0 &&
+
match t.indent_stack with
+
| { indent; needs_block_end = true; _ } :: _ ->
+
indent = column t
+
| _ -> false
+
in
let sk = {
sk_possible = true;
sk_required = required;
···
(* Just ! followed by suffix *)
("!", Buffer.contents buf ^ scan_tag_suffix t))
in
+
(* Validate that tag is followed by whitespace, break, or (in flow) flow indicator *)
+
(match Input.peek t.input with
+
| None -> () (* EOF is ok *)
+
| Some c when Input.is_whitespace c || Input.is_break c -> ()
+
| Some c when t.flow_level > 0 && Input.is_flow_indicator c -> ()
+
| _ -> Error.raise_at start (Invalid_tag "expected whitespace or line break after tag"));
let span = Span.make ~start ~stop:(Input.mark t.input) in
(handle, suffix, span)
···
let start = Input.mark t.input in
ignore (Input.next t.input); (* consume opening single-quote *)
let buf = Buffer.create 64 in
+
let whitespace = Buffer.create 16 in (* Track trailing whitespace *)
+
+
let flush_whitespace () =
+
if Buffer.length whitespace > 0 then begin
+
Buffer.add_buffer buf whitespace;
+
Buffer.clear whitespace
+
end
+
in
+
let rec loop () =
match Input.peek t.input with
| None -> Error.raise_at start Unclosed_single_quote
···
(* Check for escaped quote ('') *)
(match Input.peek t.input with
| Some '\'' ->
+
flush_whitespace ();
Buffer.add_char buf '\'';
ignore (Input.next t.input);
loop ()
+
| _ ->
+
(* End of string - flush any trailing whitespace *)
+
flush_whitespace ())
+
| Some ' ' | Some '\t' ->
+
(* Track whitespace - don't add to buf yet *)
+
Buffer.add_char whitespace (Option.get (Input.peek t.input));
+
ignore (Input.next t.input);
+
loop ()
| Some '\n' | Some '\r' ->
+
(* Discard trailing whitespace before line break *)
+
Buffer.clear whitespace;
Input.consume_break t.input;
(* Skip leading whitespace on next line *)
while Input.next_is_blank t.input do
ignore (Input.next t.input)
done;
+
(* Check for document boundary *)
if Input.at_document_boundary t.input then
Error.raise_at start Unclosed_single_quote;
+
(* Count empty lines (consecutive line breaks) *)
+
let empty_lines = ref 0 in
+
while Input.next_is_break t.input do
+
incr empty_lines;
+
Input.consume_break t.input;
+
while Input.next_is_blank t.input do
+
ignore (Input.next t.input)
+
done;
+
if Input.at_document_boundary t.input then
+
Error.raise_at start Unclosed_single_quote
+
done;
+
(* Apply folding rules *)
+
if !empty_lines > 0 then begin
+
(* Empty lines: preserve as newlines *)
+
for _ = 1 to !empty_lines do
+
Buffer.add_char buf '\n'
+
done
+
end else
+
(* Single break: fold to space (even at start of string) *)
+
Buffer.add_char buf ' ';
loop ()
| Some c ->
+
flush_whitespace ();
Buffer.add_char buf c;
ignore (Input.next t.input);
loop ()
···
(Invalid_block_scalar_header "expected newline after header");
let base_indent = current_indent t in
+
(* base_indent is the indent level from the stack, -1 if empty.
+
It's used directly for comparisons in implicit indent case. *)
let content_indent = ref (
match !explicit_indent with
| Some n ->
+
(* Explicit indent: base_indent is 1-indexed column, convert to 0-indexed.
+
content_indent = (base_indent - 1) + n, but at least n for document level. *)
let base_level = max 0 (base_indent - 1) in
base_level + n
| None -> 0 (* Will be determined by first non-empty line *)
···
(* Line starts with fewer spaces than content_indent - dedented *)
!spaces_skipped
end else if Input.next_is_blank t.input then begin
+
(* Line has spaces/tabs beyond content_indent - could be whitespace content or empty line.
+
For literal scalars, whitespace-only lines ARE content (not empty).
+
For folded scalars, whitespace-only lines that are "more indented" are preserved. *)
+
if literal then
+
(* Literal: whitespace beyond content_indent is content, let read_lines handle it *)
+
!content_indent
+
else begin
+
(* Folded: check if rest is only blanks *)
+
let idx = ref 0 in
+
while match Input.peek_nth t.input !idx with
+
| Some c when Input.is_blank c -> incr idx; true
+
| _ -> false
+
do () done;
+
match Input.peek_nth t.input (!idx) with
+
| None | Some '\n' | Some '\r' ->
+
(* Empty/whitespace-only line in folded - skip spaces *)
+
while Input.next_is_blank t.input do
+
ignore (Input.next t.input)
+
done;
+
Buffer.add_char trailing_breaks '\n';
+
Input.consume_break t.input;
+
skip_to_content_indent ()
+
| _ ->
+
(* Has non-whitespace content *)
+
!content_indent
+
end
end else
!content_indent
end else begin
+
(* Implicit indent - skip empty lines without consuming spaces.
+
Note: Only SPACES count as indentation. Tabs are content, not indentation.
+
So we only check for spaces when determining if a line is "empty". *)
if Input.next_is_break t.input then begin
Buffer.add_char trailing_breaks '\n';
Input.consume_break t.input;
skip_to_content_indent ()
+
end else if Input.next_is (( = ) ' ') t.input then begin
+
(* Check if line is empty (only spaces before break) *)
let idx = ref 0 in
while match Input.peek_nth t.input !idx with
+
| Some ' ' -> incr idx; true
| _ -> false
do () done;
match Input.peek_nth t.input (!idx) with
| None | Some '\n' | Some '\r' ->
+
(* Line has only spaces - empty line *)
+
while Input.next_is (( = ) ' ') t.input do
ignore (Input.next t.input)
done;
Buffer.add_char trailing_breaks '\n';
Input.consume_break t.input;
skip_to_content_indent ()
| _ ->
+
(* Has content (including tabs which are content, not indentation) *)
0
end else
+
(* Not at break or space - could be tab (content) or other *)
0
end
in
···
(* Determine content indent from first content line (implicit case) *)
let first_line = !content_indent = 0 in
+
(* base_indent is 1-indexed column, convert to 0-indexed for comparison with line_indent.
+
If base_indent = -1 (empty stack), then base_level = -1 means col 0 is valid. *)
+
let base_level = base_indent - 1 in
+
let should_process =
+
if !content_indent = 0 then begin
+
(* For implicit indent, content must be more indented than base_level. *)
+
if line_indent <= base_level then
+
false (* No content - first line not indented enough *)
+
else begin
+
content_indent := line_indent;
+
true
+
end
+
end else if line_indent < !content_indent then
+
false (* Dedented - done with content *)
+
else
+
true
+
in
+
if should_process then begin
+
(* Check if current line is "more indented" (has extra indent or starts with whitespace).
+
For folded scalars, lines that start with any whitespace (space or tab) after the
+
content indentation are "more indented" and preserve breaks.
+
Note: we check Input.next_is_blank BEFORE reading content to see if content starts with whitespace. *)
+
let trailing_blank = line_indent > !content_indent || Input.next_is_blank t.input in
(* Add trailing breaks to buffer *)
if Buffer.length buf > 0 then begin
···
let span = Span.make ~start ~stop:(Input.mark t.input) in
let token = if indicator = "---" then Token.Document_start else Token.Document_end in
(* Reset document content flag after document end marker *)
+
if indicator = "..." then begin
t.document_has_content <- false;
+
(* After document end marker, skip whitespace and check for end of line or comment *)
+
while Input.next_is_blank t.input do ignore (Input.next t.input) done;
+
(match Input.peek t.input with
+
| None -> () (* EOF is ok *)
+
| Some c when Input.is_break c -> ()
+
| Some '#' -> () (* Comment is ok *)
+
| _ -> Error.raise_at start (Invalid_directive "content not allowed after document end marker on same line"))
+
end;
emit t span token
and fetch_directive t =
···
if t.flow_level = 0 then
t.flow_indent <- column t;
t.flow_level <- t.flow_level + 1;
+
(* Track whether this is a mapping or sequence *)
+
let is_mapping = (token_type = Token.Flow_mapping_start) in
+
t.flow_mapping_stack <- is_mapping :: t.flow_mapping_stack;
t.allow_simple_key <- true;
t.simple_keys <- None :: t.simple_keys;
t.document_has_content <- true;
···
and fetch_flow_collection_end t token_type =
remove_simple_key t;
t.flow_level <- t.flow_level - 1;
+
t.flow_mapping_stack <- (match t.flow_mapping_stack with _ :: rest -> rest | [] -> []);
t.simple_keys <- (match t.simple_keys with _ :: rest -> rest | [] -> []);
t.allow_simple_key <- false;
let start = Input.mark t.input in
···
| None -> false)
and fetch_value t =
+
let start = Input.mark t.input in
(* Check for simple key *)
+
let used_simple_key =
+
match t.simple_keys with
+
| Some sk :: _ when sk.sk_possible ->
+
(* In implicit flow mapping (inside a flow sequence), key and : must be on the same line.
+
In explicit flow mapping { }, key and : can span lines. *)
+
let is_implicit_flow_mapping = match t.flow_mapping_stack with
+
| false :: _ -> true (* false = we're in a sequence, so any mapping is implicit *)
+
| _ -> false
+
in
+
if is_implicit_flow_mapping && sk.sk_position.line < (Input.position t.input).line then
+
Error.raise_at start Illegal_flow_key_line;
+
(* Insert KEY token before the simple key value *)
+
let key_span = Span.point sk.sk_position in
+
let key_token = { Token.token = Token.Key; span = key_span } in
+
(* We need to insert at the right position *)
+
let tokens = Queue.to_seq t.tokens |> Array.of_seq in
+
Queue.clear t.tokens;
+
let insert_pos = sk.sk_token_number - t.tokens_taken in
+
Array.iteri (fun i tok ->
+
if i = insert_pos then Queue.add key_token t.tokens;
+
Queue.add tok t.tokens
+
) tokens;
+
if insert_pos >= Array.length tokens then
+
Queue.add key_token t.tokens;
+
t.token_number <- t.token_number + 1;
+
t.pending_value <- true; (* We've inserted a KEY token, now waiting for VALUE *)
+
(* Roll indent for implicit block mapping *)
+
if t.flow_level = 0 then begin
+
let col = sk.sk_position.column in
+
if roll_indent t col ~sequence:false then begin
+
let span = Span.point sk.sk_position in
+
(* Insert block mapping start before key *)
+
let bm_token = { Token.token = Token.Block_mapping_start; span } in
+
let tokens = Queue.to_seq t.tokens |> Array.of_seq in
+
Queue.clear t.tokens;
+
Array.iteri (fun i tok ->
+
if i = insert_pos then Queue.add bm_token t.tokens;
+
Queue.add tok t.tokens
+
) tokens;
+
if insert_pos >= Array.length tokens then
+
Queue.add bm_token t.tokens;
+
t.token_number <- t.token_number + 1
+
end
+
end;
+
t.simple_keys <- None :: (List.tl t.simple_keys);
+
true
+
| _ ->
+
(* No simple key - this is a complex value (or empty key) *)
+
if t.flow_level = 0 then begin
+
if not t.allow_simple_key then
+
Error.raise_at (Input.mark t.input) Expected_key;
+
let col = column t in
+
if roll_indent t col ~sequence:false then begin
+
let span = Span.point (Input.mark t.input) in
+
emit t span Token.Block_mapping_start
+
end
+
(* Note: We don't emit KEY here. Empty key handling is done by the parser,
+
which emits empty scalar when it sees VALUE without preceding KEY. *)
+
end;
+
false
+
in
remove_simple_key t;
+
(* In block context without simple key, allow simple keys for compact mappings like ": moon: white"
+
In flow context or after using a simple key, disallow simple keys *)
+
t.allow_simple_key <- (not used_simple_key) && (t.flow_level = 0);
t.document_has_content <- true;
let start = Input.mark t.input in
ignore (Input.next t.input);
+93
yaml/ocaml-yamle/tests/dune
···
(name test_remaining)
(modules test_remaining)
(libraries yamle))
···
(name test_remaining)
(modules test_remaining)
(libraries yamle))
+
+
(executable
+
(name debug_multiline)
+
(modules debug_multiline)
+
(libraries yamle))
+
+
(executable
+
(name test_anchor_tag_issues)
+
(modules test_anchor_tag_issues)
+
(libraries yamle))
+
+
(executable
+
(name debug_quoted)
+
(modules debug_quoted)
+
(libraries yamle test_suite_lib))
+
+
(executable
+
(name debug_prh3)
+
(modules debug_prh3)
+
(libraries yamle))
+
+
(executable
+
(name test_nat4_a)
+
(modules test_nat4_a)
+
(libraries yamle))
+
+
(executable
+
(name test_simple_single)
+
(modules test_simple_single)
+
(libraries yamle))
+
+
(executable
+
(name test_a984_trace)
+
(modules test_a984_trace)
+
(libraries yamle))
+
+
(executable
+
(name debug_block_scalars)
+
(modules debug_block_scalars)
+
(libraries yamle))
+
+
(executable
+
(name debug_jef9)
+
(modules debug_jef9)
+
(libraries yamle test_suite_lib))
+
+
(executable
+
(name debug_l24t)
+
(modules debug_l24t)
+
(libraries yamle test_suite_lib))
+
+
(executable
+
(name debug_r4yg)
+
(modules debug_r4yg)
+
(libraries yamle test_suite_lib))
+
+
(executable
+
(name test_y79y)
+
(modules test_y79y)
+
(libraries yamle))
+
+
(executable
+
(name test_y79y_simple)
+
(modules test_y79y_simple)
+
(libraries yamle))
+
+
(executable
+
(name test_y79y_trace)
+
(modules test_y79y_trace)
+
(libraries yamle))
+
+
(executable
+
(name test_y79y_all)
+
(modules test_y79y_all)
+
(libraries yamle))
+
+
(executable
+
(name debug_block_issues)
+
(modules debug_block_issues)
+
(libraries yamle test_suite_lib))
+
(executable (name test_simple_key_debug) (modules test_simple_key_debug) (libraries yamle))
+
(executable (name test_trace_a984) (modules test_trace_a984) (libraries yamle))
+
(executable (name test_debug_stale) (modules test_debug_stale) (libraries yamle))
+
(executable (name test_error_type) (modules test_error_type) (libraries yamle))
+
(executable (name test_a984_minimal) (modules test_a984_minimal) (libraries yamle))
+
(executable (name test_indent_debug) (modules test_indent_debug) (libraries yamle))
+
(executable (name test_all_mentioned_cases) (modules test_all_mentioned_cases) (libraries yamle))
+
(executable (name debug_m2n8) (modules debug_m2n8) (libraries yamle test_suite_lib))
+
(executable (name debug_v9d5) (modules debug_v9d5) (libraries yamle test_suite_lib))
+
(executable (name test_lhl4) (modules test_lhl4) (libraries yamle))
+
(executable (name test_dk4h) (modules test_dk4h) (libraries yamle))
+
(executable (name test_sy6v) (modules test_sy6v) (libraries yamle))
+
(executable (name test_3hfz) (modules test_3hfz) (libraries yamle))