From 824142581daf4cc824df3b04944836a429f53f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Fri, 5 Apr 2024 23:38:41 -0700 Subject: [PATCH] feat(v2): implement kdl v2 parser and related changes Fixes: https://github.com/kdl-org/kdl-rs/issues/69 --- Cargo.toml | 5 +- examples/Cargo.kdl | 6 +- examples/ci.kdl | 39 +- examples/custom-errors.rs | 87 +- examples/kdl-schema.kdl | 311 ++--- examples/nuget.kdl | 154 +-- examples/website.kdl | 47 + src/document.rs | 145 ++- src/entry.rs | 12 +- src/error.rs | 41 +- src/fmt.rs | 54 +- src/identifier.rs | 14 +- src/lib.rs | 14 +- src/node.rs | 130 +- src/query.rs | 14 +- src/query_parser.rs | 28 +- src/{parser.rs => v1_parser.rs} | 36 +- src/v2_parser.rs | 1093 +++++++++++++++++ src/value.rs | 2 + tests/compliance.rs | 6 +- tests/{ => disabled_tests}/query_api.rs | 0 tests/{ => disabled_tests}/query_matchers.rs | 0 tests/{ => disabled_tests}/query_ops.rs | 0 tests/{ => disabled_tests}/query_syntax.rs | 0 .../expected_kdl/_negative_exponent.kdl | 1 - .../expected_kdl/_parse_all_arg_types.kdl | 1 - .../expected_kdl/_positive_exponent.kdl | 1 - .../expected_kdl/_underscore_in_exponent.kdl | 1 - tests/test_cases/expected_kdl/all_escapes.kdl | 2 +- .../expected_kdl/all_node_fields.kdl | 2 +- .../expected_kdl/arg_and_prop_same_name.kdl | 2 +- tests/test_cases/expected_kdl/arg_bare.kdl | 1 + .../expected_kdl/arg_false_type.kdl | 2 +- .../test_cases/expected_kdl/arg_null_type.kdl | 2 +- .../expected_kdl/arg_raw_string_type.kdl | 2 +- .../expected_kdl/arg_string_type.kdl | 2 +- .../test_cases/expected_kdl/arg_true_type.kdl | 2 +- tests/test_cases/expected_kdl/arg_type.kdl | 2 +- tests/test_cases/expected_kdl/bare_emoji.kdl | 2 +- .../expected_kdl/bare_ident_dot.kdl | 1 + .../expected_kdl/bare_ident_sign.kdl | 1 + .../expected_kdl/bare_ident_sign_dot.kdl | 1 + .../expected_kdl/blank_prop_type.kdl | 2 +- .../test_cases/expected_kdl/block_comment.kdl | 2 +- .../expected_kdl/block_comment_after_node.kdl | 2 +- tests/test_cases/expected_kdl/bom_initial.kdl | 1 + tests/test_cases/expected_kdl/boolean_arg.kdl | 2 +- .../test_cases/expected_kdl/boolean_prop.kdl | 2 +- .../expected_kdl/chevrons_in_bare_id.kdl | 1 + .../expected_kdl/comma_in_bare_id.kdl | 1 + .../expected_kdl/comment_after_arg_type.kdl | 1 + .../expected_kdl/comment_after_node_type.kdl | 1 + .../expected_kdl/comment_after_prop_type.kdl | 1 + .../expected_kdl/comment_and_newline.kdl | 2 + .../expected_kdl/comment_in_arg_type.kdl | 1 + .../expected_kdl/comment_in_node_type.kdl | 1 + .../expected_kdl/comment_in_prop_type.kdl | 1 + .../test_cases/expected_kdl/commented_arg.kdl | 2 +- .../expected_kdl/commented_child.kdl | 2 +- .../expected_kdl/commented_prop.kdl | 2 +- tests/test_cases/expected_kdl/dash_dash.kdl | 1 + tests/test_cases/expected_kdl/emoji.kdl | 2 +- .../expected_kdl/empty_line_comment.kdl | 1 + .../expected_kdl/empty_quoted_node_id.kdl | 2 +- .../expected_kdl/empty_quoted_prop_key.kdl | 2 +- .../expected_kdl/eof_after_escape.kdl | 1 + .../expected_kdl/escaped_whitespace.kdl | 1 + tests/test_cases/expected_kdl/escline.kdl | 2 +- .../expected_kdl/escline_line_comment.kdl | 2 +- .../expected_kdl/floating_point_keywords.kdl | 1 + tests/test_cases/expected_kdl/hex.kdl | 2 +- tests/test_cases/expected_kdl/hex_int.kdl | 2 +- .../expected_kdl/initial_slashdash.kdl | 1 + .../expected_kdl/multiline_comment.kdl | 2 +- .../expected_kdl/multiline_nodes.kdl | 2 +- .../expected_kdl/multiline_raw_string.kdl | 1 + .../multiline_raw_string_indented.kdl | 1 + .../expected_kdl/multiline_string.kdl | 2 +- .../multiline_string_indented.kdl | 1 + .../expected_kdl/negative_exponent.kdl | 1 + .../expected_kdl/nested_block_comment.kdl | 2 +- .../expected_kdl/nested_comments.kdl | 2 +- .../nested_multiline_block_comment.kdl | 2 +- .../newlines_in_block_comment.kdl | 2 +- .../expected_kdl/no_decimal_exponent.kdl | 2 +- tests/test_cases/expected_kdl/node_false.kdl | 2 +- tests/test_cases/expected_kdl/node_true.kdl | 2 +- tests/test_cases/expected_kdl/null_arg.kdl | 2 +- tests/test_cases/expected_kdl/null_prop.kdl | 2 +- .../expected_kdl/optional_child_semicolon.kdl | 5 + .../expected_kdl/parse_all_arg_types.kdl | 1 + .../expected_kdl/positive_exponent.kdl | 1 + .../expected_kdl/prop_false_type.kdl | 2 +- .../expected_kdl/prop_float_type.kdl | 2 +- .../expected_kdl/prop_identifier_type.kdl | 1 + .../expected_kdl/prop_null_type.kdl | 2 +- .../expected_kdl/prop_raw_string_type.kdl | 2 +- .../expected_kdl/prop_string_type.kdl | 2 +- .../expected_kdl/prop_true_type.kdl | 2 +- tests/test_cases/expected_kdl/prop_type.kdl | 2 +- .../question_mark_before_number.kdl | 1 + .../expected_kdl/quoted_prop_name.kdl | 2 +- .../expected_kdl/quoted_prop_type.kdl | 2 +- tests/test_cases/expected_kdl/r_node.kdl | 2 +- .../test_cases/expected_kdl/raw_arg_type.kdl | 2 +- .../test_cases/expected_kdl/raw_prop_type.kdl | 2 +- .../expected_kdl/raw_string_arg.kdl | 5 +- .../expected_kdl/raw_string_newline.kdl | 2 +- .../expected_kdl/raw_string_prop.kdl | 5 +- .../test_cases/expected_kdl/repeated_arg.kdl | 2 +- tests/test_cases/expected_kdl/same_args.kdl | 1 - ...ation_large.kdl => sci_notation_large.kdl} | 0 ...ation_small.kdl => sci_notation_small.kdl} | 0 tests/test_cases/expected_kdl/single_arg.kdl | 2 +- tests/test_cases/expected_kdl/single_prop.kdl | 2 +- .../slashdash_arg_after_newline_esc.kdl | 2 +- .../expected_kdl/slashdash_prop.kdl | 2 +- .../expected_kdl/slashdash_repeated_prop.kdl | 2 +- .../expected_kdl/space_after_arg_type.kdl | 1 + .../expected_kdl/space_after_node_type.kdl | 1 + .../expected_kdl/space_after_prop_type.kdl | 1 + .../expected_kdl/space_around_prop_marker.kdl | 1 + .../expected_kdl/space_in_arg_type.kdl | 1 + .../expected_kdl/space_in_node_type.kdl | 1 + .../expected_kdl/space_in_prop_type.kdl | 1 + tests/test_cases/expected_kdl/string_arg.kdl | 2 +- .../string_escaped_literal_whitespace.kdl | 1 + tests/test_cases/expected_kdl/string_prop.kdl | 2 +- .../expected_kdl/underscore_before_number.kdl | 1 + .../expected_kdl/underscore_in_exponent.kdl | 1 + .../expected_kdl/unicode_equals_signs.kdl | 1 + .../unusual_bare_id_chars_in_quoted_id.kdl | 2 +- .../expected_kdl/unusual_chars_in_bare_id.kdl | 2 +- .../expected_kdl/vertical_tab_whitespace.kdl | 1 + tests/test_cases/input/all_escapes.kdl | 2 +- tests/test_cases/input/all_node_fields.kdl | 2 +- .../input/arg_and_prop_same_name.kdl | 2 +- tests/test_cases/input/arg_bare.kdl | 1 + tests/test_cases/input/arg_false_type.kdl | 2 +- tests/test_cases/input/arg_null_type.kdl | 2 +- .../test_cases/input/arg_raw_string_type.kdl | 2 +- tests/test_cases/input/arg_string_type.kdl | 2 +- tests/test_cases/input/arg_true_type.kdl | 2 +- tests/test_cases/input/arg_type.kdl | 2 +- .../test_cases/input/backslash_in_bare_id.kdl | 1 - tests/test_cases/input/bare_arg.kdl | 1 - tests/test_cases/input/bare_emoji.kdl | 2 +- tests/test_cases/input/bare_ident_dot.kdl | 1 + tests/test_cases/input/bare_ident_numeric.kdl | 1 + .../input/bare_ident_numeric_dot.kdl | 1 + .../input/bare_ident_numeric_sign.kdl | 1 + tests/test_cases/input/bare_ident_sign.kdl | 1 + .../test_cases/input/bare_ident_sign_dot.kdl | 1 + tests/test_cases/input/blank_prop_type.kdl | 2 +- tests/test_cases/input/block_comment.kdl | 2 +- .../input/block_comment_after_node.kdl | 2 +- tests/test_cases/input/bom_initial.kdl | 1 + tests/test_cases/input/bom_later.kdl | 1 + tests/test_cases/input/boolean_arg.kdl | 2 +- tests/test_cases/input/boolean_prop.kdl | 2 +- .../test_cases/input/brackets_in_bare_id.kdl | 2 +- .../test_cases/input/chevrons_in_bare_id.kdl | 2 +- tests/test_cases/input/comma_in_bare_id.kdl | 2 +- .../input/comment_after_arg_type.kdl | 2 +- .../input/comment_after_node_type.kdl | 2 +- .../input/comment_after_prop_type.kdl | 2 +- .../test_cases/input/comment_and_newline.kdl | 2 + .../test_cases/input/comment_in_arg_type.kdl | 2 +- .../test_cases/input/comment_in_node_type.kdl | 2 +- .../test_cases/input/comment_in_prop_type.kdl | 2 +- tests/test_cases/input/commented_arg.kdl | 2 +- tests/test_cases/input/commented_child.kdl | 2 +- tests/test_cases/input/commented_line.kdl | 2 +- tests/test_cases/input/commented_node.kdl | 1 + tests/test_cases/input/commented_prop.kdl | 2 +- tests/test_cases/input/crlf_between_nodes.kdl | 4 +- tests/test_cases/input/dash_dash.kdl | 2 +- tests/test_cases/input/emoji.kdl | 2 +- tests/test_cases/input/empty_child.kdl | 2 +- .../input/empty_child_different_lines.kdl | 2 +- .../input/empty_child_whitespace.kdl | 2 +- tests/test_cases/input/empty_line_comment.kdl | 2 + tests/test_cases/input/empty_prop_type.kdl | 2 +- .../test_cases/input/empty_quoted_node_id.kdl | 2 +- .../input/empty_quoted_prop_key.kdl | 2 +- tests/test_cases/input/eof_after_escape.kdl | 1 + .../input/err_backslash_in_bare_id.kdl | 1 + tests/test_cases/input/escaped_whitespace.kdl | 15 + tests/test_cases/input/escline.kdl | 2 +- .../test_cases/input/escline_comment_node.kdl | 3 - .../test_cases/input/escline_line_comment.kdl | 5 +- ...t_keyword_identifier_strings_error.kdl.kdl | 1 + .../input/floating_point_keywords.kdl | 1 + tests/test_cases/input/hash_in_id.kdl | 1 + tests/test_cases/input/hex.kdl | 2 +- tests/test_cases/input/hex_int.kdl | 2 +- tests/test_cases/input/initial_slashdash.kdl | 2 + tests/test_cases/input/just_child.kdl | 4 +- .../input/just_space_in_prop_type.kdl | 2 +- tests/test_cases/input/leading_newline.kdl | 2 +- tests/test_cases/input/multiline_comment.kdl | 2 +- tests/test_cases/input/multiline_nodes.kdl | 4 +- .../test_cases/input/multiline_raw_string.kdl | 5 + .../input/multiline_raw_string_indented.kdl | 5 + ...ng_non_matching_prefix_character_error.kdl | 5 + ...string_non_matching_prefix_count_error.kdl | 5 + tests/test_cases/input/multiline_string.kdl | 3 +- .../input/multiline_string_indented.kdl | 5 + ...ng_non_matching_prefix_character_error.kdl | 5 + ...string_non_matching_prefix_count_error.kdl | 5 + .../test_cases/input/nested_block_comment.kdl | 2 +- tests/test_cases/input/nested_children.kdl | 2 +- tests/test_cases/input/nested_comments.kdl | 2 +- .../input/nested_multiline_block_comment.kdl | 2 +- .../input/newlines_in_block_comment.kdl | 2 +- tests/test_cases/input/no_integer_digit.kdl | 1 + tests/test_cases/input/no_solidus_escape.kdl | 1 + tests/test_cases/input/node_false.kdl | 2 +- tests/test_cases/input/node_true.kdl | 2 +- tests/test_cases/input/null_arg.kdl | 2 +- tests/test_cases/input/null_prop.kdl | 2 +- tests/test_cases/input/only_cr.kdl | 3 +- .../input/only_line_comment_crlf.kdl | 2 +- .../input/optional_child_semicolon.kdl | 1 + tests/test_cases/input/parens_in_bare_id.kdl | 2 +- .../test_cases/input/parse_all_arg_types.kdl | 2 +- .../test_cases/input/preserve_node_order.kdl | 2 +- tests/test_cases/input/prop_false_type.kdl | 2 +- .../test_cases/input/prop_identifier_type.kdl | 1 + tests/test_cases/input/prop_null_type.kdl | 2 +- .../test_cases/input/prop_raw_string_type.kdl | 2 +- tests/test_cases/input/prop_true_type.kdl | 2 +- tests/test_cases/input/prop_type.kdl | 2 +- .../input/question_mark_at_start_of_int.kdl | 1 - .../input/question_mark_before_number.kdl | 2 +- tests/test_cases/input/quote_in_bare_id.kdl | 2 +- tests/test_cases/input/quoted_prop_name.kdl | 2 +- tests/test_cases/input/quoted_prop_type.kdl | 2 +- tests/test_cases/input/raw_arg_type.kdl | 2 +- tests/test_cases/input/raw_node_name.kdl | 2 +- tests/test_cases/input/raw_prop_type.kdl | 2 +- tests/test_cases/input/raw_string_arg.kdl | 5 +- .../test_cases/input/raw_string_backslash.kdl | 2 +- .../input/raw_string_hash_no_esc.kdl | 2 +- .../input/raw_string_just_backslash.kdl | 2 +- .../input/raw_string_just_quote.kdl | 2 +- .../input/raw_string_multiple_hash.kdl | 2 +- tests/test_cases/input/raw_string_newline.kdl | 4 +- tests/test_cases/input/raw_string_prop.kdl | 5 +- tests/test_cases/input/raw_string_quote.kdl | 2 +- tests/test_cases/input/repeated_arg.kdl | 2 +- tests/test_cases/input/same_args.kdl | 1 - tests/test_cases/input/semicolon_in_child.kdl | 2 +- tests/test_cases/input/single_arg.kdl | 2 +- tests/test_cases/input/single_prop.kdl | 2 +- tests/test_cases/input/slash_in_bare_id.kdl | 2 +- .../input/slashdash_arg_after_newline_esc.kdl | 2 +- .../slashdash_arg_before_newline_esc.kdl | 2 +- .../test_cases/input/slashdash_full_node.kdl | 3 +- .../input/slashdash_in_slashdash.kdl | 2 +- .../input/slashdash_node_in_child.kdl | 2 +- .../input/slashdash_node_with_child.kdl | 2 +- tests/test_cases/input/slashdash_prop.kdl | 2 +- .../input/slashdash_raw_prop_key.kdl | 2 +- .../input/slashdash_repeated_prop.kdl | 2 +- .../input/space_after_prop_type.kdl | 2 +- .../input/space_around_prop_marker.kdl | 1 + tests/test_cases/input/space_in_arg_type.kdl | 2 +- tests/test_cases/input/space_in_prop_type.kdl | 2 +- .../input/square_bracket_in_bare_id.kdl | 2 +- .../string_escaped_literal_whitespace.kdl | 2 + tests/test_cases/input/trailing_crlf.kdl | 2 +- .../input/unbalanced_raw_hashes.kdl | 2 +- .../input/underscore_at_start_of_int.kdl | 1 - tests/test_cases/input/unicode_delete.kdl | 2 + .../test_cases/input/unicode_equals_signs.kdl | 4 + tests/test_cases/input/unicode_fsi.kdl | 2 + tests/test_cases/input/unicode_lre.kdl | 2 + tests/test_cases/input/unicode_lri.kdl | 2 + tests/test_cases/input/unicode_lrm.kdl | 2 + tests/test_cases/input/unicode_lro.kdl | 2 + tests/test_cases/input/unicode_pdf.kdl | 2 + tests/test_cases/input/unicode_pdi.kdl | 2 + tests/test_cases/input/unicode_rle.kdl | 2 + tests/test_cases/input/unicode_rli.kdl | 2 + tests/test_cases/input/unicode_rlm.kdl | 2 + tests/test_cases/input/unicode_rlo.kdl | 2 + tests/test_cases/input/unicode_under_0x20.kdl | 2 + .../unusual_bare_id_chars_in_quoted_id.kdl | 2 +- .../input/unusual_chars_in_bare_id.kdl | 2 +- .../input/vertical_tab_whitespace.kdl | 1 + 291 files changed, 2066 insertions(+), 698 deletions(-) create mode 100644 examples/website.kdl rename src/{parser.rs => v1_parser.rs} (97%) create mode 100644 src/v2_parser.rs rename tests/{ => disabled_tests}/query_api.rs (100%) rename tests/{ => disabled_tests}/query_matchers.rs (100%) rename tests/{ => disabled_tests}/query_ops.rs (100%) rename tests/{ => disabled_tests}/query_syntax.rs (100%) delete mode 100644 tests/test_cases/expected_kdl/_negative_exponent.kdl delete mode 100644 tests/test_cases/expected_kdl/_parse_all_arg_types.kdl delete mode 100644 tests/test_cases/expected_kdl/_positive_exponent.kdl delete mode 100644 tests/test_cases/expected_kdl/_underscore_in_exponent.kdl create mode 100644 tests/test_cases/expected_kdl/arg_bare.kdl create mode 100644 tests/test_cases/expected_kdl/bare_ident_dot.kdl create mode 100644 tests/test_cases/expected_kdl/bare_ident_sign.kdl create mode 100644 tests/test_cases/expected_kdl/bare_ident_sign_dot.kdl create mode 100644 tests/test_cases/expected_kdl/bom_initial.kdl create mode 100644 tests/test_cases/expected_kdl/chevrons_in_bare_id.kdl create mode 100644 tests/test_cases/expected_kdl/comma_in_bare_id.kdl create mode 100644 tests/test_cases/expected_kdl/comment_after_arg_type.kdl create mode 100644 tests/test_cases/expected_kdl/comment_after_node_type.kdl create mode 100644 tests/test_cases/expected_kdl/comment_after_prop_type.kdl create mode 100644 tests/test_cases/expected_kdl/comment_and_newline.kdl create mode 100644 tests/test_cases/expected_kdl/comment_in_arg_type.kdl create mode 100644 tests/test_cases/expected_kdl/comment_in_node_type.kdl create mode 100644 tests/test_cases/expected_kdl/comment_in_prop_type.kdl create mode 100644 tests/test_cases/expected_kdl/dash_dash.kdl create mode 100644 tests/test_cases/expected_kdl/empty_line_comment.kdl create mode 100644 tests/test_cases/expected_kdl/eof_after_escape.kdl create mode 100644 tests/test_cases/expected_kdl/escaped_whitespace.kdl create mode 100644 tests/test_cases/expected_kdl/floating_point_keywords.kdl create mode 100644 tests/test_cases/expected_kdl/initial_slashdash.kdl create mode 100644 tests/test_cases/expected_kdl/multiline_raw_string.kdl create mode 100644 tests/test_cases/expected_kdl/multiline_raw_string_indented.kdl create mode 100644 tests/test_cases/expected_kdl/multiline_string_indented.kdl create mode 100644 tests/test_cases/expected_kdl/negative_exponent.kdl create mode 100644 tests/test_cases/expected_kdl/optional_child_semicolon.kdl create mode 100644 tests/test_cases/expected_kdl/parse_all_arg_types.kdl create mode 100644 tests/test_cases/expected_kdl/positive_exponent.kdl create mode 100644 tests/test_cases/expected_kdl/prop_identifier_type.kdl create mode 100644 tests/test_cases/expected_kdl/question_mark_before_number.kdl delete mode 100644 tests/test_cases/expected_kdl/same_args.kdl rename tests/test_cases/expected_kdl/{_sci_notation_large.kdl => sci_notation_large.kdl} (100%) rename tests/test_cases/expected_kdl/{_sci_notation_small.kdl => sci_notation_small.kdl} (100%) create mode 100644 tests/test_cases/expected_kdl/space_after_arg_type.kdl create mode 100644 tests/test_cases/expected_kdl/space_after_node_type.kdl create mode 100644 tests/test_cases/expected_kdl/space_after_prop_type.kdl create mode 100644 tests/test_cases/expected_kdl/space_around_prop_marker.kdl create mode 100644 tests/test_cases/expected_kdl/space_in_arg_type.kdl create mode 100644 tests/test_cases/expected_kdl/space_in_node_type.kdl create mode 100644 tests/test_cases/expected_kdl/space_in_prop_type.kdl create mode 100644 tests/test_cases/expected_kdl/string_escaped_literal_whitespace.kdl create mode 100644 tests/test_cases/expected_kdl/underscore_before_number.kdl create mode 100644 tests/test_cases/expected_kdl/underscore_in_exponent.kdl create mode 100644 tests/test_cases/expected_kdl/unicode_equals_signs.kdl create mode 100644 tests/test_cases/expected_kdl/vertical_tab_whitespace.kdl create mode 100644 tests/test_cases/input/arg_bare.kdl delete mode 100644 tests/test_cases/input/backslash_in_bare_id.kdl delete mode 100644 tests/test_cases/input/bare_arg.kdl create mode 100644 tests/test_cases/input/bare_ident_dot.kdl create mode 100644 tests/test_cases/input/bare_ident_numeric.kdl create mode 100644 tests/test_cases/input/bare_ident_numeric_dot.kdl create mode 100644 tests/test_cases/input/bare_ident_numeric_sign.kdl create mode 100644 tests/test_cases/input/bare_ident_sign.kdl create mode 100644 tests/test_cases/input/bare_ident_sign_dot.kdl create mode 100644 tests/test_cases/input/bom_initial.kdl create mode 100644 tests/test_cases/input/bom_later.kdl create mode 100644 tests/test_cases/input/comment_and_newline.kdl create mode 100644 tests/test_cases/input/empty_line_comment.kdl create mode 100644 tests/test_cases/input/eof_after_escape.kdl create mode 100644 tests/test_cases/input/err_backslash_in_bare_id.kdl create mode 100644 tests/test_cases/input/escaped_whitespace.kdl delete mode 100644 tests/test_cases/input/escline_comment_node.kdl create mode 100644 tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl create mode 100644 tests/test_cases/input/floating_point_keywords.kdl create mode 100644 tests/test_cases/input/hash_in_id.kdl create mode 100644 tests/test_cases/input/initial_slashdash.kdl create mode 100644 tests/test_cases/input/multiline_raw_string.kdl create mode 100644 tests/test_cases/input/multiline_raw_string_indented.kdl create mode 100644 tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl create mode 100644 tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl create mode 100644 tests/test_cases/input/multiline_string_indented.kdl create mode 100644 tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl create mode 100644 tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl create mode 100644 tests/test_cases/input/no_integer_digit.kdl create mode 100644 tests/test_cases/input/no_solidus_escape.kdl create mode 100644 tests/test_cases/input/optional_child_semicolon.kdl create mode 100644 tests/test_cases/input/prop_identifier_type.kdl delete mode 100644 tests/test_cases/input/question_mark_at_start_of_int.kdl delete mode 100644 tests/test_cases/input/same_args.kdl create mode 100644 tests/test_cases/input/space_around_prop_marker.kdl create mode 100644 tests/test_cases/input/string_escaped_literal_whitespace.kdl delete mode 100644 tests/test_cases/input/underscore_at_start_of_int.kdl create mode 100644 tests/test_cases/input/unicode_delete.kdl create mode 100644 tests/test_cases/input/unicode_equals_signs.kdl create mode 100644 tests/test_cases/input/unicode_fsi.kdl create mode 100644 tests/test_cases/input/unicode_lre.kdl create mode 100644 tests/test_cases/input/unicode_lri.kdl create mode 100644 tests/test_cases/input/unicode_lrm.kdl create mode 100644 tests/test_cases/input/unicode_lro.kdl create mode 100644 tests/test_cases/input/unicode_pdf.kdl create mode 100644 tests/test_cases/input/unicode_pdi.kdl create mode 100644 tests/test_cases/input/unicode_rle.kdl create mode 100644 tests/test_cases/input/unicode_rli.kdl create mode 100644 tests/test_cases/input/unicode_rlm.kdl create mode 100644 tests/test_cases/input/unicode_rlo.kdl create mode 100644 tests/test_cases/input/unicode_under_0x20.kdl create mode 100644 tests/test_cases/input/vertical_tab_whitespace.kdl diff --git a/Cargo.toml b/Cargo.toml index 7ceb851..1808e1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,11 @@ default = ["span"] span = [] [dependencies] -miette = "5.7.0" +miette = "7.2.0" nom = "7.1.1" thiserror = "1.0.40" +winnow = { version = "0.6.5", features = ["alloc", "unstable-recover"] } [dev-dependencies] -miette = { version = "5.7.0", features = ["fancy"] } +miette = { version = "7.2.0", features = ["fancy"] } pretty_assertions = "1.3.0" diff --git a/examples/Cargo.kdl b/examples/Cargo.kdl index 7b58dba..caec020 100644 --- a/examples/Cargo.kdl +++ b/examples/Cargo.kdl @@ -1,9 +1,9 @@ package { - name "kdl" + name kdl version "0.0.0" - description "kat's document language" + description "The kdl document language" authors "Kat Marchán " - license-file "LICENSE.md" + license-file LICENSE.md edition "2018" } diff --git a/examples/ci.kdl b/examples/ci.kdl index d5443c7..d2fcf0e 100644 --- a/examples/ci.kdl +++ b/examples/ci.kdl @@ -1,47 +1,52 @@ // This example is a GitHub Action if it used KDL syntax. // See .github/workflows/ci.yml for the file this was based on. -name "CI" +name CI -on "push" "pull_request" +on push pull_request env { - RUSTFLAGS "-Dwarnings" + RUSTFLAGS -Dwarnings } jobs { fmt_and_docs "Check fmt & build docs" { - runs-on "ubuntu-latest" + runs-on ubuntu-latest steps { step uses="actions/checkout@v1" step "Install Rust" uses="actions-rs/toolchain@v1" { - profile "minimal" - toolchain "stable" - components "rustfmt" - override true + profile minimal + toolchain stable + components rustfmt + override #true } - step "rustfmt" run="cargo fmt --all -- --check" - step "docs" run="cargo doc --no-deps" + step rustfmt { run cargo fmt --all -- --check } + step docs { run cargo doc --no-deps } } } build_and_test "Build & Test" { runs-on "${{ matrix.os }}" strategy { matrix { - rust "1.46.0" "stable" - os "ubuntu-latest" "macOS-latest" "windows-latest" + rust "1.46.0" stable + os ubuntu-latest macOS-latest windows-latest } } steps { step uses="actions/checkout@v1" step "Install Rust" uses="actions-rs/toolchain@v1" { - profile "minimal" + profile minimal toolchain "${{ matrix.rust }}" - components "clippy" - override true + components clippy + override #true } - step "Clippy" run="cargo clippy --all -- -D warnings" - step "Run tests" run="cargo test --all --verbose" + step Clippy { run cargo clippy --all -- -D warnings } + step "Run tests" { run cargo test --all --verbose } + step "Other Stuff" run=" + echo foo + echo bar + echo baz + " } } } diff --git a/examples/custom-errors.rs b/examples/custom-errors.rs index 20fa2c0..94e769d 100644 --- a/examples/custom-errors.rs +++ b/examples/custom-errors.rs @@ -1,47 +1,50 @@ -/// Show how to build your own diagnostics, without having to use the -/// `fancy` feature or having `main()` return `miette::Result` -use kdl::KdlDocument; -use miette::Diagnostic; -use miette::SourceSpan; +// TODO(@zkat): Error stuff has changed, so this needs updating. -#[derive(Debug)] -pub struct MyError { - pub message: String, -} +// /// Show how to build your own diagnostics, without having to use the +// /// `fancy` feature or having `main()` return `miette::Result` +// /// +// use kdl::KdlDocument; +// use miette::Diagnostic; +// use miette::SourceSpan; -fn parse(input: &str) -> Result { - let doc = input.parse::(); - doc.map_err(|error| { - let source = error - .source_code() - .expect("parse errors should have source code"); - let help = error.help.unwrap_or_default(); - let span: SourceSpan = error.span; - let contents = source - .read_span(&span, 0, 0) - .expect("source should have span contents"); - // miette uses 0 based indexes, but humans prefer 1-based - let line = contents.line() + 1; - let column = contents.column() + 1; - let message = format!( - "line {}, column {}: {}\n help: {}", - line, column, error, help - ); - MyError { message } - }) -} +// #[derive(Debug)] +// pub struct MyError { +// pub message: String, +// } + +// fn parse(input: &str) -> Result { +// let doc = input.parse::(); +// doc.map_err(|error| { +// let source = error +// .source_code() +// .expect("parse errors should have source code"); +// let help = error.help.unwrap_or_default(); +// let span: SourceSpan = error.span; +// let contents = source +// .read_span(&span, 0, 0) +// .expect("source should have span contents"); +// // miette uses 0 based indexes, but humans prefer 1-based +// let line = contents.line() + 1; +// let column = contents.column() + 1; +// let message = format!( +// "line {}, column {}: {}\n help: {}", +// line, column, error, help +// ); +// MyError { message } +// }) +// } fn main() { - let input = r#" - foo { - bar { - baz 1. - } - } - "#; - let err = parse(input).unwrap_err(); - eprintln!("{}", err.message); - // Output: - // line 4, column 14: Expected valid value. - // help: Floating point numbers must be base 10, and have numbers after the decimal point. + // let input = r#" + // foo { + // bar { + // baz 1. + // } + // } + // "#; + // let err = parse(input).unwrap_err(); + // eprintln!("{}", err.message); + // // Output: + // // line 4, column 14: Expected valid value. + // // help: Floating point numbers must be base 10, and have numbers after the decimal point. } diff --git a/examples/kdl-schema.kdl b/examples/kdl-schema.kdl index 4315199..041c464 100644 --- a/examples/kdl-schema.kdl +++ b/examples/kdl-schema.kdl @@ -1,371 +1,374 @@ document { info { - title "KDL Schema" lang="en" - description "KDL Schema KDL schema in KDL" lang="en" + title "KDL Schema" lang=en + description "KDL Schema KDL schema in KDL" lang=en author "Kat Marchán" { - link "https://github.com/zkat" rel="self" + link "https://github.com/zkat" rel=self } contributor "Lars Willighagen" { - link "https://github.com/larsgw" rel="self" + link "https://github.com/larsgw" rel=self } - link "https://github.com/zkat/kdl" rel="documentation" - license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx="CC-BY-SA-4.0" { - link "https://creativecommons.org/licenses/by-sa/4.0/" lang="en" + link "https://github.com/zkat/kdl" rel=documentation + license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx=CC-BY-SA-4.0 { + link "https://creativecommons.org/licenses/by-sa/4.0/" lang=en } published "2021-08-31" modified "2021-09-01" } - node "document" { + node document { min 1 max 1 - children id="node-children" { - node "node-names" id="node-names-node" description="Validations to apply specifically to arbitrary node names" { - children ref=r#"[id="validations"]"# + children id=node-children { + node node-names id=node-names-node description="Validations to apply specifically to arbitrary node names" { + children ref=#"[id="validations"]"# } - node "other-nodes-allowed" id="other-nodes-allowed-node" description="Whether to allow child nodes other than the ones explicitly listed. Defaults to 'false'." { + node other-nodes-allowed id=other-nodes-allowed-node description="Whether to allow child nodes other than the ones explicitly listed. Defaults to '#false'." { max 1 value { min 1 max 1 - type "boolean" + type boolean } } - node "tag-names" description="Validations to apply specifically to arbitrary type tag names" { - children ref=r#"[id="validations"]"# + node tag-names description="Validations to apply specifically to arbitrary type tag names" { + children ref=#"[id="validations"]"# } - node "other-tags-allowed" description="Whether to allow child node tags other than the ones explicitly listed. Defaults to 'false'." { + node other-tags-allowed description="Whether to allow child node tags other than the ones explicitly listed. Defaults to '#false'." { max 1 value { min 1 max 1 - type "boolean" + type boolean } } - node "info" description="A child node that describes the schema itself." { + node info description="A child node that describes the schema itself." { children { - node "title" description="The title of the schema or the format it describes" { + node title description="The title of the schema or the format it describes" { value description="The title text" { - type "string" + type string min 1 max 1 } - prop "lang" id="info-lang" description="The language of the text" { - type "string" + prop lang id=info-lang description="The language of the text" { + type string } } - node "description" description="A description of the schema or the format it describes" { + node description description="A description of the schema or the format it describes" { value description="The description text" { - type "string" + type string min 1 max 1 } - prop ref=r#"[id="info-lang"]"# + prop ref=#"[id="info-lang"]"# } - node "author" description="Author of the schema" { - value id="info-person-name" description="Person name" { - type "string" + node author description="Author of the schema" { + value id=info-person-name description="Person name" { + type string min 1 max 1 } - prop "orcid" id="info-orcid" description="The ORCID of the person" { - type "string" - pattern r"\d{4}-\d{4}-\d{4}-\d{4}" + prop orcid id=info-orcid description="The ORCID of the person" { + type string + pattern #"\d{4}-\d{4}-\d{4}-\d{4}"# } children { - node ref=r#"[id="info-link"]"# + node ref=#"[id="info-link"]"# } } - node "contributor" description="Contributor to the schema" { - value ref=r#"[id="info-person-name"]"# - prop ref=r#"[id="info-orcid"]"# + node contributor description="Contributor to the schema" { + value ref=#"[id="info-person-name"]"# + prop ref=#"[id="info-orcid"]"# + children { + node ref=#"[id="info-link"]"# + } } - node "link" id="info-link" description="Links to itself, and to sources describing it" { + node link id=info-link description="Links to itself, and to sources describing it" { value description="A URL that the link points to" { - type "string" - format "url" "irl" + type string + format url irl min 1 max 1 } - prop "rel" description="The relation between the current entity and the URL" { - type "string" - enum "self" "documentation" + prop rel description="The relation between the current entity and the URL" { + type string + enum self documentation } - prop ref=r#"[id="info-lang"]"# + prop ref=#"[id="info-lang"]"# } - node "license" description="The license(s) that the schema is licensed under" { + node license description="The license(s) that the schema is licensed under" { value description="Name of the used license" { - type "string" + type string min 1 max 1 } - prop "spdx" description="An SPDX license identifier" { - type "string" + prop spdx description="An SPDX license identifier" { + type string } children { - node ref=r#"[id="info-link"]"# + node ref=#"[id="info-link"]"# } } - node "published" description="When the schema was published" { + node published description="When the schema was published" { value description="Publication date" { - type "string" - format "date" + type string + format date min 1 max 1 } - prop "time" id="info-time" description="A time to accompany the date" { - type "string" - format "time" + prop time id=info-time description="A time to accompany the date" { + type string + format time } } - node "modified" description="When the schema was last modified" { + node modified description="When the schema was last modified" { value description="Modification date" { - type "string" - format "date" + type string + format date min 1 max 1 } - prop ref=r#"[id="info-time"]"# + prop ref=#"[id="info-time"]"# } - node "version" description="The version number of this version of the schema" { + node version description="The version number of this version of the schema" { value description="Semver version number" { - type "string" - pattern r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" + type string + pattern #"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"# min 1 max 1 } } } } - node "tag" id="tag-node" description="A tag belonging to a child node of `document` or another node." { + node tag id=tag-node description="A tag belonging to a child node of `document` or another node." { value description="The name of the tag. If a tag name is not supplied, the node rules apply to _all_ nodes belonging to the parent." { - type "string" + type string max 1 } - prop "description" description="A description of this node's purpose." { - type "string" + prop description description="A description of this node's purpose." { + type string } - prop "id" description="A globally-unique ID for this node." { - type "string" + prop id description="A globally-unique ID for this node." { + type string } - prop "ref" description="A globally unique reference to another node." { - type "string" - format "kdl-query" + prop ref description="A globally unique reference to another node." { + type string + format kdl-query } children { - node ref=r#"[id="node-names-node"]"# - node ref=r#"[id="other-nodes-allowed-node"]"# - node ref=r#"[id="node-node"]"# + node ref=#"[id="node-names-node"]"# + node ref=#"[id="other-nodes-allowed-node"]"# + node ref=#"[id="node-node"]"# } } - node "node" id="node-node" description="A child node belonging either to `document` or to another `node`. Nodes may be anonymous." { + node node id=node-node description="A child node belonging either to `document` or to another `node`. Nodes may be anonymous." { value description="The name of the node. If a node name is not supplied, the node rules apply to _all_ nodes belonging to the parent." { - type "string" + type string max 1 } - prop "description" description="A description of this node's purpose." { - type "string" + prop description description="A description of this node's purpose." { + type string } - prop "id" description="A globally-unique ID for this node." { - type "string" + prop id description="A globally-unique ID for this node." { + type string } - prop "ref" description="A globally unique reference to another node." { - type "string" - format "kdl-query" + prop ref description="A globally unique reference to another node." { + type string + format kdl-query } children { - node "prop-names" description="Validations to apply specifically to arbitrary property names" { - children ref=r#"[id="validations"]"# + node prop-names description="Validations to apply specifically to arbitrary property names" { + children ref=#"[id="validations"]"# } - node "other-props-allowed" description="Whether to allow properties other than the ones explicitly listed. Defaults to 'false'." { + node other-props-allowed description="Whether to allow properties other than the ones explicitly listed. Defaults to '#false'." { max 1 value { min 1 max 1 - type "boolean" + type boolean } } - node "min" description="minimum number of instances of this node in its parent's children." { + node min description="minimum number of instances of this node in its parent's children." { max 1 value { min 1 max 1 - type "number" + type number } } - node "max" description="maximum number of instances of this node in its parent's children." { + node max description="maximum number of instances of this node in its parent's children." { max 1 value { min 1 max 1 - type "number" + type number } } - node ref=r#"[id="value-tag-node"]"# - node "prop" id="prop-node" description="A node property key/value pair." { + node ref=#"[id="value-tag-node"]"# + node prop id="prop-node" description="A node property key/value pair." { value description="The property key." { - type "string" + type string } - prop "id" description="A globally-unique ID of this property." { - type "string" + prop id description="A globally-unique ID of this property." { + type string } - prop "ref" description="A globally unique reference to another property node." { - type "string" - format "kdl-query" + prop ref description="A globally unique reference to another property node." { + type string + format kdl-query } - prop "description" description="A description of this property's purpose." { - type "string" + prop description description="A description of this property's purpose." { + type string } children description="Property-specific validations." { - node "required" description="Whether this property is required if its parent is present." { + node required description="Whether this property is required if its parent is present." { max 1 value { min 1 max 1 - type "boolean" + type boolean } } } - children id="validations" description="General value validations." { - node "tag" id="value-tag-node" description="The tags associated with this value" { + children id=validations description="General value validations." { + node tag id=value-tag-node description="The tags associated with this value" { max 1 - children ref=r#"[id="validations"]"# + children ref=#"[id="validations"]"# } - node "type" description="The type for this prop's value." { + node type description="The type for this prop's value." { max 1 value { min 1 - type "string" + type string } } - node "enum" description="An enumeration of possible values" { + node enum description="An enumeration of possible values" { max 1 value description="Enumeration choices" { min 1 } } - node "pattern" description="PCRE (Regex) pattern or patterns to test prop values against." { + node pattern description="PCRE (Regex) pattern or patterns to test prop values against." { value { min 1 - type "string" + type string } } - node "min-length" description="Minimum length of prop value, if it's a string." { + node min-length description="Minimum length of prop value, if it's a string." { max 1 value { min 1 - type "number" + type number } } - node "max-length" description="Maximum length of prop value, if it's a string." { + node max-length description="Maximum length of prop value, if it's a string." { max 1 value { min 1 - type "number" + type number } } - node "format" description="Intended data format." { + node format description="Intended data format." { max 1 value { min 1 - type "string" + type string // https://json-schema.org/understanding-json-schema/reference/string.html#format - enum "date-time" "date" "time" "duration" "decimal" "currency" "country-2" "country-3" "country-subdivision" "email" "idn-email" "hostname" "idn-hostname" "ipv4" "ipv6" "url" "url-reference" "irl" "irl-reference" "url-template" "regex" "uuid" "kdl-query" "i8" "i16" "i32" "i64" "u8" "u16" "u32" "u64" "isize" "usize" "f32" "f64" "decimal64" "decimal128" + enum date-time date time duration decimal currency country-2 country-3 country-subdivision email idn-email hostname idn-hostname ipv4 ipv6 url url-reference irl irl-reference url-template regex uuid kdl-query i8 i16 i32 i64 u8 u16 u32 u64 isize usize f32 f64 decimal64 decimal128 } } - node "%" description="Only used for numeric values. Constrains them to be multiples of the given number(s)" { + node % description="Only used for numeric values. Constrains them to be multiples of the given number(s)" { max 1 value { min 1 - type "number" + type number } } - node ">" description="Only used for numeric values. Constrains them to be greater than the given number(s)" { + node > description="Only used for numeric values. Constrains them to be greater than the given number(s)" { max 1 value { min 1 max 1 - type "number" + type number } } - node ">=" description="Only used for numeric values. Constrains them to be greater than or equal to the given number(s)" { + node >= description="Only used for numeric values. Constrains them to be greater than or equal to the given number(s)" { max 1 value { min 1 max 1 - type "number" + type number } } - node "<" description="Only used for numeric values. Constrains them to be less than the given number(s)" { + node < description="Only used for numeric values. Constrains them to be less than the given number(s)" { max 1 value { min 1 max 1 - type "number" + type number } } - node "<=" description="Only used for numeric values. Constrains them to be less than or equal to the given number(s)" { + node <= description="Only used for numeric values. Constrains them to be less than or equal to the given number(s)" { max 1 value { min 1 max 1 - type "number" + type number } } } } - node "value" id="value-node" description="one or more direct node values" { - prop "id" description="A globally-unique ID of this value." { - type "string" + node value id=value-node description="one or more direct node values" { + prop id description="A globally-unique ID of this value." { + type string } - prop "ref" description="A globally unique reference to another value node." { - type "string" - format "kdl-query" + prop ref description="A globally unique reference to another value node." { + type string + format kdl-query } - prop "description" description="A description of this property's purpose." { - type "string" + prop description description="A description of this property's purpose." { + type string } - children ref=r#"[id="validations"]"# + children ref=#"[id="validations"]"# children description="Node value-specific validations" { - node "min" description="minimum number of values for this node." { + node min description="minimum number of values for this node." { max 1 value { min 1 max 1 - type "number" + type number } } - node "max" description="maximum number of values for this node." { + node max description="maximum number of values for this node." { max 1 value { min 1 max 1 - type "number" + type number } } } } - node "children" id="children-node" { - prop "id" description="A globally-unique ID of this children node." { - type "string" + node children id=children-node { + prop id description="A globally-unique ID of this children node." { + type string } - prop "ref" description="A globally unique reference to another children node." { - type "string" - format "kdl-query" + prop ref description="A globally unique reference to another children node." { + type string + format kdl-query } - prop "description" description="A description of this these children's purpose." { - type "string" + prop description description="A description of this these children's purpose." { + type string } - children ref=r#"[id="node-children"]"# + children ref=#"[id="node-children"]"# } } } - node "definitions" description="Definitions to reference in parts of the top-level nodes" { + node definitions description="Definitions to reference in parts of the top-level nodes" { children { - node ref=r#"[id="node-node"]"# - node ref=r#"[id="value-node"]"# - node ref=r#"[id="prop-node"]"# - node ref=r#"[id="children-node"]"# - node ref=r#"[id="tag-node"]"# + node ref=#"[id="node-node"]"# + node ref=#"[id="value-node"]"# + node ref=#"[id="prop-node"]"# + node ref=#"[id="children-node"]"# + node ref=#"[id="tag-node"]"# } } } diff --git a/examples/nuget.kdl b/examples/nuget.kdl index 9ab4aa1..033f8da 100644 --- a/examples/nuget.kdl +++ b/examples/nuget.kdl @@ -1,48 +1,48 @@ // Based on https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Clients/NuGet.CommandLine/NuGet.CommandLine.csproj Project { PropertyGroup { - IsCommandLinePackage true + IsCommandLinePackage #true } - Import Project=r"$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'README.md'))\build\common.props" - Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" - Import Project="ilmerge.props" + Import Project=#"$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'README.md'))\build\common.props"# + Import Project=Sdk.props Sdk=Microsoft.NET.Sdk + Import Project=ilmerge.props PropertyGroup { - RootNamespace "NuGet.CommandLine" - AssemblyName "NuGet" + RootNamespace NuGet.CommandLine + AssemblyName NuGet AssemblyTitle "NuGet Command Line" - PackageId "NuGet.CommandLine" + PackageId NuGet.CommandLine TargetFramework "$(NETFXTargetFramework)" - GenerateDocumentationFile false + GenerateDocumentationFile #false Description "NuGet Command Line Interface." - ApplicationManifest "app.manifest" - Shipping true - OutputType "Exe" - ComVisible false + ApplicationManifest app.manifest + Shipping #true + OutputType Exe + ComVisible #false // Pack properties - PackProject true - IncludeBuildOutput false + PackProject #true + IncludeBuildOutput #false TargetsForTfmSpecificContentInPackage "$(TargetsForTfmSpecificContentInPackage)" "CreateCommandlineNupkg" - SuppressDependenciesWhenPacking true - DevelopmentDependency true - PackageRequireLicenseAcceptance false - UsePublicApiAnalyzer false + SuppressDependenciesWhenPacking #true + DevelopmentDependency #true + PackageRequireLicenseAcceptance #false + UsePublicApiAnalyzer #false } - Target Name="CreateCommandlineNupkg" { + Target Name=CreateCommandlineNupkg { ItemGroup { - TfmSpecificPackageFile Include=r"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe" { + TfmSpecificPackageFile Include=#"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe"# { PackagePath "tools/" } - TfmSpecificPackageFile Include=r"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.pdb" { + TfmSpecificPackageFile Include=#"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.pdb"# { PackagePath "tools/" } } } ItemGroup Condition="$(DefineConstants.Contains(SIGNED_BUILD))" { - AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { + AssemblyAttribute Include=System.Runtime.CompilerServices.InternalsVisibleTo { _Parameter1 "NuGet.CommandLine.FuncTest, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293" } AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { @@ -51,81 +51,81 @@ Project { } ItemGroup Condition="!$(DefineConstants.Contains(SIGNED_BUILD))" { - AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { - _Parameter1 "NuGet.CommandLine.FuncTest" + AssemblyAttribute Include=System.Runtime.CompilerServices.InternalsVisibleTo { + _Parameter1 NuGet.CommandLine.FuncTest } - AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { - _Parameter1 "NuGet.CommandLine.Test" + AssemblyAttribute Include=System.Runtime.CompilerServices.InternalsVisibleTo { + _Parameter1 NuGet.CommandLine.Test } } ItemGroup Condition="$(DefineConstants.Contains(SIGNED_BUILD))" { - AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { + AssemblyAttribute Include=System.Runtime.CompilerServices.InternalsVisibleTo { _Parameter1 "NuGet.CommandLine.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293" } } ItemGroup Condition="!$(DefineConstants.Contains(SIGNED_BUILD))" { - AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo" { - _Parameter1 "NuGet.CommandLine.Test" + AssemblyAttribute Include=System.Runtime.CompilerServices.InternalsVisibleTo { + _Parameter1 NuGet.CommandLine.Test } } ItemGroup { - Reference Include="Microsoft.Build.Utilities.v4.0" - Reference Include="Microsoft.CSharp" - Reference Include="System" - Reference Include="System.ComponentModel.Composition" - Reference Include="System.ComponentModel.Composition.Registration" - Reference Include="System.ComponentModel.DataAnnotations" - Reference Include="System.IO.Compression" - Reference Include="System.Net.Http" - Reference Include="System.Xml" - Reference Include="System.Xml.Linq" - Reference Include="NuGet.Core" { - HintPath r"$(SolutionPackagesFolder)nuget.core\2.14.0-rtm-832\lib\net40-Client\NuGet.Core.dll" - Aliases "CoreV2" + Reference Include=Microsoft.Build.Utilities.v4.0 + Reference Include=Microsoft.CSharp + Reference Include=System + Reference Include=System.ComponentModel.Composition + Reference Include=System.ComponentModel.Composition.Registration + Reference Include=System.ComponentModel.DataAnnotations + Reference Include=System.IO.Compression + Reference Include=System.Net.Http + Reference Include=System.Xml + Reference Include=System.Xml.Linq + Reference Include=NuGet.Core { + HintPath #"$(SolutionPackagesFolder)nuget.core\2.14.0-rtm-832\lib\net40-Client\NuGet.Core.dll"# + Aliases CoreV2 } } ItemGroup { - PackageReference Include="Microsoft.VisualStudio.Setup.Configuration.Interop" - ProjectReference Include=r"$(NuGetCoreSrcDirectory)NuGet.PackageManagement\NuGet.PackageManagement.csproj" - ProjectReference Include=r"$(NuGetCoreSrcDirectory)NuGet.Build.Tasks\NuGet.Build.Tasks.csproj" + PackageReference Include=Microsoft.VisualStudio.Setup.Configuration.Interop + ProjectReference Include=#"$(NuGetCoreSrcDirectory)NuGet.PackageManagement\NuGet.PackageManagement.csproj"# + ProjectReference Include=#"$(NuGetCoreSrcDirectory)NuGet.Build.Tasks\NuGet.Build.Tasks.csproj"# } ItemGroup { - EmbeddedResource Update="NuGetCommand.resx" { - Generator "ResXFileCodeGenerator" - LastGenOutput "NuGetCommand.Designer.cs" + EmbeddedResource Update=NuGetCommand.resx { + Generator ResXFileCodeGenerator + LastGenOutput NuGetCommand.Designer.cs } - Compile Update="NuGetCommand.Designer.cs" { - DesignTime true - AutoGen true - DependentUpon "NuGetCommand.resx" + Compile Update=NuGetCommand.Designer.cs { + DesignTime #true + AutoGen #true + DependentUpon NuGetCommand.resx } - EmbeddedResource Update="NuGetResources.resx" { + EmbeddedResource Update=NuGetResources.resx { // Strings are shared by other projects, use public strings. - Generator "PublicResXFileCodeGenerator" - LastGenOutput "NuGetResources.Designer.cs" + Generator PublicResXFileCodeGenerator + LastGenOutput NuGetResources.Designer.cs } - Compile Update="NuGetResources.Designer.cs" { - DesignTime true - AutoGen true - DependentUpon "NuGetResources.resx" + Compile Update=NuGetResources.Designer.cs { + DesignTime #true + AutoGen #true + DependentUpon NuGetResources.resx } } ItemGroup { - EmbeddedResource Include=r"$(NuGetCoreSrcDirectory)NuGet.Build.Tasks\NuGet.targets" { - Link "NuGet.targets" - SubType "Designer" + EmbeddedResource Include=#"$(NuGetCoreSrcDirectory)NuGet.Build.Tasks\NuGet.targets"# { + Link NuGet.targets + SubType Designer } } // Since we are moving some code and strings from NuGet.CommandLine to NuGet.Commands, we opted to go through normal localization process (build .resources.dll) and then add them to the ILMerged nuget.exe // This will also be called from CI build, after assemblies are localized, since our test infra takes nuget.exe before Localization - Target Name="ILMergeNuGetExe" \ - AfterTargets="Build" \ + Target Name=ILMergeNuGetExe \ + AfterTargets=Build \ Condition="'$(BuildingInsideVisualStudio)' != 'true' and '$(SkipILMergeOfNuGetExe)' != 'true'" \ { PropertyGroup { @@ -133,9 +133,9 @@ Project { ExpectedLocalizedArtifactCount 0 Condition="'$(ExpectedLocalizedArtifactCount)' == ''" } ItemGroup { - BuildArtifacts Include=r"$(OutputPath)\*.dll" Exclude="@(MergeExclude)" + BuildArtifacts Include=#"$(OutputPath)\*.dll"# Exclude="@(MergeExclude)" // NuGet.exe needs all NuGet.Commands.resources.dll merged in - LocalizedArtifacts Include=r"$(ArtifactsDirectory)\NuGet.Commands\**\$(NETFXTargetFramework)\**\*.resources.dll" + LocalizedArtifacts Include=#"$(ArtifactsDirectory)\NuGet.Commands\**\$(NETFXTargetFramework)\**\*.resources.dll"# } Error Text="Build dependencies are inconsistent with mergeinclude specified in ilmerge.props" \ Condition="'@(BuildArtifacts->Count())' != '@(MergeInclude->Count())'" @@ -143,36 +143,36 @@ Project { Condition="'@(LocalizedArtifacts->Count())' != '$(ExpectedLocalizedArtifactCount)'" PropertyGroup { PathToBuiltNuGetExe "$(OutputPath)NuGet.exe" - IlmergeCommand r"$(ILMergeExePath) /lib:$(OutputPath) /out:$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe @(MergeAllowDup -> '/allowdup:%(Identity)', ' ') /log:$(OutputPath)IlMergeLog.txt" + IlmergeCommand #"$(ILMergeExePath) /lib:$(OutputPath) /out:$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe @(MergeAllowDup -> '/allowdup:%(Identity)', ' ') /log:$(OutputPath)IlMergeLog.txt"# IlmergeCommand Condition="Exists($(MS_PFX_PATH))" "$(IlmergeCommand) /delaysign /keyfile:$(MS_PFX_PATH)" // LocalizedArtifacts need fullpath, since there will be duplicate file names IlmergeCommand "$(IlmergeCommand) $(PathToBuiltNuGetExe) @(BuildArtifacts->'%(filename)%(extension)', ' ') @(LocalizedArtifacts->'%(fullpath)', ' ')" } MakeDir Directories="$(ArtifactsDirectory)$(VsixOutputDirName)" - Exec Command="$(IlmergeCommand)" ContinueOnError="false" + Exec Command="$(IlmergeCommand)" ContinueOnError=#false } Import Project="$(BuildCommonDirectory)common.targets" Import Project="$(BuildCommonDirectory)embedinterop.targets" // Do nothing. This basically strips away the framework assemblies from the resulting nuspec. - Target Name="_GetFrameworkAssemblyReferences" DependsOnTargets="ResolveReferences" + Target Name=_GetFrameworkAssemblyReferences DependsOnTargets=ResolveReferences - Target Name="GetSigningInputs" Returns="@(DllsToSign)" { + Target Name=GetSigningInputs Returns="@(DllsToSign)" { ItemGroup { - DllsToSign Include=r"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe" { - StrongName "MsSharedLib72" - Authenticode "Microsoft400" + DllsToSign Include=#"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe"# { + StrongName MsSharedLib72 + Authenticode Microsoft400 } } } - Target Name="GetSymbolsToIndex" Returns="@(SymbolsToIndex)" { + Target Name=GetSymbolsToIndex Returns="@(SymbolsToIndex)" { ItemGroup { - SymbolsToIndex Include=r"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe" - SymbolsToIndex Include=r"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.pdb" + SymbolsToIndex Include=#"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.exe"# + SymbolsToIndex Include=#"$(ArtifactsDirectory)$(VsixOutputDirName)\NuGet.pdb"# } } - Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" + Import Project=Sdk.targets Sdk=Microsoft.NET.Sdk } diff --git a/examples/website.kdl b/examples/website.kdl new file mode 100644 index 0000000..d2c7dc5 --- /dev/null +++ b/examples/website.kdl @@ -0,0 +1,47 @@ +!doctype html +html lang=en { + head { + meta charset=utf-8 + meta name=viewport content="width=device-width, initial-scale=1.0" + meta \ + name=description \ + content="kdl is a document language, mostly based on SDLang, with xml-like semantics that looks like you're invoking a bunch of CLI commands!" + title "kdl - The KDL Document Language" + link rel=stylesheet href="/styles/global.css" + } + body { + main { + header class="py-10 bg-gray-300" { + h1 class="text-4xl text-center" "kdl - The KDL Document Language" + } + section class=kdl-section id=description { + p { + - "kdl is a document language, mostly based on " + a href="https://sdlang.org" "SDLang" + - " with xml-like semantics that looks like you're invoking a bunch of CLI commands" + } + p "It's meant to be used both as a serialization format and a configuration language, and is relatively light on syntax compared to XML." + } + section class=kdl-section id=design-and-discussion { + h2 "Design and Discussion" + p { + - "kdl is still extremely new, and discussion about the format should happen over on the " + a href="https://github.com/kdoclang/kdl/discussions" { + - "discussions" + } + - " page in the Github repo. Feel free to jump in and give us your 2 cents!" + } + } + section class=kdl-section id=design-principles { + h2 "Design Principles" + ol { + li Maintainability + li Flexibility + li "Cognitive simplicity and Learnability" + li "Ease of de/serialization" + li "Ease of implementation" + } + } + } + } +} diff --git a/src/document.rs b/src/document.rs index 85f1b46..e63fdce 100644 --- a/src/document.rs +++ b/src/document.rs @@ -1,8 +1,8 @@ #[cfg(feature = "span")] use miette::SourceSpan; -use std::{fmt::Display, str::FromStr}; +use std::fmt::Display; -use crate::{parser, IntoKdlQuery, KdlError, KdlNode, KdlQueryIterator, KdlValue, NodeKey}; +use crate::{KdlNode, KdlValue}; /// Represents a KDL /// [`Document`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#document). @@ -251,69 +251,75 @@ impl KdlDocument { self.fmt_impl(0, true); } - /// Queries this Document's children according to the KQL query language, - /// returning an iterator over all matching nodes. - /// - /// # NOTE - /// - /// Any query selectors that try to select the toplevel `scope()` will - /// fail to match when using this method, since there's no [`KdlNode`] to - /// return in this case. - pub fn query_all(&self, query: impl IntoKdlQuery) -> Result, KdlError> { - let parsed = query.into_query()?; - Ok(KdlQueryIterator::new(None, Some(self), parsed)) - } - - /// Queries this Document's children according to the KQL query language, - /// returning the first match, if any. - /// - /// # NOTE - /// - /// Any query selectors that try to select the toplevel `scope()` will - /// fail to match when using this method, since there's no [`KdlNode`] to - /// return in this case. - pub fn query(&self, query: impl IntoKdlQuery) -> Result, KdlError> { - let mut iter = self.query_all(query)?; - Ok(iter.next()) - } - - /// Queries this Document's children according to the KQL query language, - /// picking the first match, and calling `.get(key)` on it, if the query - /// succeeded. - /// - /// # NOTE - /// - /// Any query selectors that try to select the toplevel `scope()` will - /// fail to match when using this method, since there's no [`KdlNode`] to - /// return in this case. - pub fn query_get( - &self, - query: impl IntoKdlQuery, - key: impl Into, - ) -> Result, KdlError> { - Ok(self.query(query)?.and_then(|node| node.get(key))) - } - - /// Queries this Document's children according to the KQL query language, - /// returning an iterator over all matching nodes, returning the requested - /// field from each of those nodes and filtering out nodes that don't have - /// it. - /// - /// # NOTE - /// - /// Any query selectors that try to select the toplevel `scope()` will - /// fail to match when using this method, since there's no [`KdlNode`] to - /// return in this case. - pub fn query_get_all( - &self, - query: impl IntoKdlQuery, - key: impl Into, - ) -> Result, KdlError> { - let key: NodeKey = key.into(); - Ok(self - .query_all(query)? - .filter_map(move |node| node.get(key.clone()))) - } + // TODO(@zkat): These should all be moved into the query module itself, + // instead of being methods on the models + // + // /// Queries this Document's children according to the KQL query language, + // /// returning an iterator over all matching nodes. + // /// + // /// # NOTE + // /// + // /// Any query selectors that try to select the toplevel `scope()` will + // /// fail to match when using this method, since there's no [`KdlNode`] to + // /// return in this case. + // pub fn query_all( + // &self, + // query: impl IntoKdlQuery, + // ) -> Result, KdlDiagnostic> { + // let parsed = query.into_query()?; + // Ok(KdlQueryIterator::new(None, Some(self), parsed)) + // } + + // /// Queries this Document's children according to the KQL query language, + // /// returning the first match, if any. + // /// + // /// # NOTE + // /// + // /// Any query selectors that try to select the toplevel `scope()` will + // /// fail to match when using this method, since there's no [`KdlNode`] to + // /// return in this case. + // pub fn query(&self, query: impl IntoKdlQuery) -> Result, KdlDiagnostic> { + // let mut iter = self.query_all(query)?; + // Ok(iter.next()) + // } + + // /// Queries this Document's children according to the KQL query language, + // /// picking the first match, and calling `.get(key)` on it, if the query + // /// succeeded. + // /// + // /// # NOTE + // /// + // /// Any query selectors that try to select the toplevel `scope()` will + // /// fail to match when using this method, since there's no [`KdlNode`] to + // /// return in this case. + // pub fn query_get( + // &self, + // query: impl IntoKdlQuery, + // key: impl Into, + // ) -> Result, KdlDiagnostic> { + // Ok(self.query(query)?.and_then(|node| node.get(key))) + // } + + // /// Queries this Document's children according to the KQL query language, + // /// returning an iterator over all matching nodes, returning the requested + // /// field from each of those nodes and filtering out nodes that don't have + // /// it. + // /// + // /// # NOTE + // /// + // /// Any query selectors that try to select the toplevel `scope()` will + // /// fail to match when using this method, since there's no [`KdlNode`] to + // /// return in this case. + // pub fn query_get_all( + // &self, + // query: impl IntoKdlQuery, + // key: impl Into, + // ) -> Result, KdlDiagnostic> { + // let key: NodeKey = key.into(); + // Ok(self + // .query_all(query)? + // .filter_map(move |node| node.get(key.clone()))) + // } } impl Display for KdlDocument { @@ -370,15 +376,6 @@ impl IntoIterator for KdlDocument { } } -impl FromStr for KdlDocument { - type Err = KdlError; - - fn from_str(input: &str) -> Result { - let kdl_parser = parser::KdlParser::new(input); - kdl_parser.parse(parser::document(&kdl_parser)) - } -} - #[cfg(test)] mod test { #[cfg(feature = "span")] diff --git a/src/entry.rs b/src/entry.rs index e867afe..9bf01f4 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -2,7 +2,7 @@ use miette::SourceSpan; use std::{fmt::Display, str::FromStr}; -use crate::{parser, KdlError, KdlIdentifier, KdlValue}; +use crate::{v2_parser, KdlIdentifier, KdlParseFailure, KdlValue}; /// KDL Entries are the "arguments" to KDL nodes: either a (positional) /// [`Argument`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#argument) or @@ -232,11 +232,15 @@ where } impl FromStr for KdlEntry { - type Err = KdlError; + type Err = KdlParseFailure; fn from_str(s: &str) -> Result { - let kdl_parser = parser::KdlParser::new(s); - kdl_parser.parse(parser::entry_with_trailing(&kdl_parser)) + let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node_entry, s); + if let Some(Some(v)) = maybe_val { + Ok(v) + } else { + Err(v2_parser::failure_from_errs(errs, s)) + } } } diff --git a/src/error.rs b/src/error.rs index bd1d287..8bbaae1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,7 @@ -use std::num::{ParseFloatError, ParseIntError}; +use std::{ + num::{ParseFloatError, ParseIntError}, + sync::Arc, +}; use miette::{Diagnostic, SourceSpan}; use nom::error::{ContextError, ErrorKind, FromExternalError, ParseError}; @@ -10,11 +13,12 @@ use { std::convert::{TryFrom, TryInto}, }; -/// An error that occurs when parsing a KDL document. +/// The toplevel `Error` type for KDL: this is returned when a KDL document +/// failed to parse entirely. /// -/// This error implements [`miette::Diagnostic`] and can be used to display -/// detailed, pretty-printed diagnostic messages when using [`miette::Result`] -/// and the `"fancy"` feature flag for `miette`: +/// This diagnostic implements [`miette::Diagnostic`] and can be used to +/// display detailed, pretty-printed diagnostic messages when using +/// [`miette::Result`] and the `"fancy"` feature flag for `miette`: /// /// ```no_run /// fn main() -> miette::Result<()> { @@ -35,14 +39,29 @@ use { /// help: Floating point numbers must be base 10, and have numbers after the decimal point. /// ``` #[derive(Debug, Diagnostic, Clone, Eq, PartialEq, Error)] +#[error("Failed to parse KDL.")] +pub struct KdlParseFailure { + /// Original input that this failure came from. + #[source_code] + pub input: Arc, + + /// Sub-diagnostics for this failure. + #[related] + pub diagnostics: Vec, +} + +/// An individual diagnostic message for a KDL parsing issue. +/// +/// While generally signifying errors, they can also be treated as warnings. +#[derive(Debug, Diagnostic, Clone, Eq, PartialEq, Error)] #[error("{kind}")] -pub struct KdlError { - /// Source string for the KDL document that failed to parse. +pub struct KdlDiagnostic { + /// Shared source for the diagnostic. #[source_code] - pub input: String, + pub input: Arc, /// Offset in chars of the error. - #[label("{}", label.unwrap_or("here"))] + #[label("{}", label.unwrap_or("here".into()))] pub span: SourceSpan, /// Label text for this span. Defaults to `"here"`. @@ -52,6 +71,10 @@ pub struct KdlError { #[help] pub help: Option<&'static str>, + /// Severity level for the Diagnostic. + #[diagnostic(severity)] + pub severity: miette::Severity, + /// Specific error kind for this parser error. pub kind: KdlErrorKind, } diff --git a/src/fmt.rs b/src/fmt.rs index 3c69460..af2074c 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,42 +1,44 @@ use std::fmt::Write as _; -pub(crate) fn fmt_leading(leading: &mut String, indent: usize, no_comments: bool) { +pub(crate) fn fmt_leading(leading: &mut String, indent: usize, _no_comments: bool) { if leading.is_empty() { return; } + // TODO let mut result = String::new(); - if !no_comments { - let input = leading.trim(); - let kdl_parser = crate::parser::KdlParser { full_input: input }; - let comments = kdl_parser - .parse(crate::parser::leading_comments(&kdl_parser)) - .expect("invalid leading text"); - for line in comments { - let trimmed = line.trim(); - if !trimmed.is_empty() { - writeln!(result, "{:indent$}{}", "", trimmed, indent = indent).unwrap(); - } - } - } + // if !no_comments { + // let input = leading.trim(); + // let kdl_parser = crate::v1_parser::KdlParser { full_input: input }; + // let comments = kdl_parser + // .parse(crate::v1_parser::leading_comments(&kdl_parser)) + // .expect("invalid leading text"); + // for line in comments { + // let trimmed = line.trim(); + // if !trimmed.is_empty() { + // writeln!(result, "{:indent$}{}", "", trimmed, indent = indent).unwrap(); + // } + // } + // } write!(result, "{:indent$}", "", indent = indent).unwrap(); *leading = result; } -pub(crate) fn fmt_trailing(decor: &mut String, no_comments: bool) { +pub(crate) fn fmt_trailing(decor: &mut String, _no_comments: bool) { if decor.is_empty() { return; } *decor = decor.trim().to_string(); - let mut result = String::new(); - if !no_comments { - let input = &*decor; - let kdl_parser = crate::parser::KdlParser { full_input: input }; - let comments = kdl_parser - .parse(crate::parser::trailing_comments(&kdl_parser)) - .expect("invalid trailing text"); - for comment in comments { - result.push_str(comment); - } - } + let result = String::new(); + // TODO + // if !no_comments { + // let input = &*decor; + // let kdl_parser = crate::v1_parser::KdlParser { full_input: input }; + // let comments = kdl_parser + // .parse(crate::v1_parser::trailing_comments(&kdl_parser)) + // .expect("invalid trailing text"); + // for comment in comments { + // result.push_str(comment); + // } + // } *decor = result; } diff --git a/src/identifier.rs b/src/identifier.rs index 27288ee..5d851d5 100644 --- a/src/identifier.rs +++ b/src/identifier.rs @@ -2,7 +2,7 @@ use miette::SourceSpan; use std::{fmt::Display, str::FromStr}; -use crate::{parser, KdlError}; +use crate::{v2_parser, KdlParseFailure}; /// Represents a KDL /// [Identifier](https://github.com/kdl-org/kdl/blob/main/SPEC.md#identifier). @@ -201,11 +201,15 @@ impl From for String { } impl FromStr for KdlIdentifier { - type Err = KdlError; + type Err = KdlParseFailure; fn from_str(s: &str) -> Result { - let kdl_parser = crate::parser::KdlParser::new(s); - kdl_parser.parse(parser::identifier(&kdl_parser)) + let (maybe_val, errs) = v2_parser::try_parse(v2_parser::identifier, s); + if let Some(v) = maybe_val { + Ok(v) + } else { + Err(v2_parser::failure_from_errs(errs, s)) + } } } @@ -226,7 +230,7 @@ mod test { } ); - let quoted = "\"foo\\\"bar\""; + let quoted = r#""foo\"bar""#; assert_eq!( quoted.parse::()?, KdlIdentifier { diff --git a/src/lib.rs b/src/lib.rs index 11efc3d..2bf9553 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -159,7 +159,7 @@ #![deny(missing_debug_implementations, nonstandard_style)] #![warn(missing_docs, unreachable_pub, rust_2018_idioms, unreachable_pub)] -#![cfg_attr(test, deny(warnings))] +// #![cfg_attr(test, deny(warnings))] #![doc(html_favicon_url = "https://kdl.dev/favicon.ico")] #![doc(html_logo_url = "https://kdl.dev/logo.svg")] @@ -168,7 +168,7 @@ pub use entry::*; pub use error::*; pub use identifier::*; pub use node::*; -pub use query::*; +// pub use query::*; pub use value::*; mod document; @@ -177,8 +177,10 @@ mod error; mod fmt; mod identifier; mod node; -mod nom_compat; -mod parser; -mod query; -mod query_parser; +// mod nom_compat; +// mod query; +// mod query_parser; +// mod v1_parser; mod value; + +mod v2_parser; diff --git a/src/node.rs b/src/node.rs index f1a4f02..842cc8d 100644 --- a/src/node.rs +++ b/src/node.rs @@ -7,10 +7,7 @@ use std::{ #[cfg(feature = "span")] use miette::SourceSpan; -use crate::{ - parser, IntoKdlQuery, KdlDocument, KdlEntry, KdlError, KdlIdentifier, KdlQueryIterator, - KdlValue, -}; +use crate::{v2_parser, KdlDocument, KdlEntry, KdlIdentifier, KdlParseFailure, KdlValue}; /// Represents an individual KDL /// [`Node`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) inside a @@ -22,6 +19,9 @@ pub struct KdlNode { pub(crate) name: KdlIdentifier, // TODO: consider using `hashlink` for this instead, later. pub(crate) entries: Vec, + pub(crate) before_ty_name: Option, + pub(crate) after_ty_name: Option, + pub(crate) after_ty: Option, pub(crate) before_children: Option, pub(crate) children: Option, pub(crate) trailing: Option, @@ -63,6 +63,9 @@ impl KdlNode { leading: None, ty: None, entries: Vec::new(), + before_ty_name: None, + after_ty_name: None, + after_ty: None, before_children: None, children: None, trailing: None, @@ -143,11 +146,41 @@ impl KdlNode { self.before_children.as_deref() } + /// Gets text (whitespace, comments) between the type annotation and the node name. + pub fn after_ty(&self) -> Option<&str> { + self.after_ty.as_deref() + } + + /// Gets text (whitespace, comments) between the opening `(` and the type annotation name. + pub fn before_ty_name(&self) -> Option<&str> { + self.before_ty_name.as_deref() + } + + /// Gets text (whitespace, comments) between the type annotation name and the closing `)`. + pub fn after_ty_name(&self) -> Option<&str> { + self.after_ty_name.as_deref() + } + /// Gets text (whitespace, comments) right before the children block's starting `{`. pub fn set_before_children(&mut self, before: impl Into) { self.before_children = Some(before.into()); } + /// Sets text (whitespace, comments) between the type annotation and the node name. + pub fn set_after_ty(&mut self, after_ty: impl Into) { + self.after_ty = Some(after_ty.into()); + } + + /// Sets text (whitespace, comments) between the opening `(` and the type annotation name. + pub fn set_before_ty_name(&mut self, before_ty_name: impl Into) { + self.after_ty_name = Some(before_ty_name.into()); + } + + /// Sets text (whitespace, comments) between the type annotation name and the closing `)`. + pub fn set_after_ty_name(&mut self, after_ty_name: impl Into) { + self.after_ty_name = Some(after_ty_name.into()); + } + /// Gets trailing text (whitespace, comments) for this node. pub fn trailing(&self) -> Option<&str> { self.trailing.as_deref() @@ -418,44 +451,47 @@ impl KdlNode { self.fmt_impl(0, true); } - /// Queries this Node according to the KQL query language, - /// returning an iterator over all matching nodes. - pub fn query_all(&self, query: impl IntoKdlQuery) -> Result, KdlError> { - let q = query.into_query()?; - Ok(KdlQueryIterator::new(Some(self), None, q)) - } - - /// Queries this Node according to the KQL query language, - /// returning the first match, if any. - pub fn query(&self, query: impl IntoKdlQuery) -> Result, KdlError> { - Ok(self.query_all(query)?.next()) - } - - /// Queries this Node according to the KQL query language, - /// picking the first match, and calling `.get(key)` on it, if the query - /// succeeded. - pub fn query_get( - &self, - query: impl IntoKdlQuery, - key: impl Into, - ) -> Result, KdlError> { - Ok(self.query(query)?.and_then(|node| node.get(key))) - } - - /// Queries this Node according to the KQL query language, - /// returning an iterator over all matching nodes, returning the requested - /// field from each of those nodes and filtering out nodes that don't have - /// it. - pub fn query_get_all( - &self, - query: impl IntoKdlQuery, - key: impl Into, - ) -> Result, KdlError> { - let key: NodeKey = key.into(); - Ok(self - .query_all(query)? - .filter_map(move |node| node.get(key.clone()))) - } + // TODO(@zkat): These should all be moved into the query module, instead + // of being model methods. + // + // /// Queries this Node according to the KQL + // query language, /// returning an iterator over all matching nodes. pub + // fn query_all( &self, query: impl IntoKdlQuery, ) -> + // Result, KdlDiagnostic> { let q = + // query.into_query()?; Ok(KdlQueryIterator::new(Some(self), None, q)) + // } + + // /// Queries this Node according to the KQL query language, + // /// returning the first match, if any. + // pub fn query(&self, query: impl IntoKdlQuery) -> Result, KdlDiagnostic> { + // Ok(self.query_all(query)?.next()) + // } + + // /// Queries this Node according to the KQL query language, + // /// picking the first match, and calling `.get(key)` on it, if the query + // /// succeeded. + // pub fn query_get( + // &self, + // query: impl IntoKdlQuery, + // key: impl Into, + // ) -> Result, KdlDiagnostic> { + // Ok(self.query(query)?.and_then(|node| node.get(key))) + // } + + // /// Queries this Node according to the KQL query language, + // /// returning an iterator over all matching nodes, returning the requested + // /// field from each of those nodes and filtering out nodes that don't have + // /// it. + // pub fn query_get_all( + // &self, + // query: impl IntoKdlQuery, + // key: impl Into, + // ) -> Result, KdlDiagnostic> { + // let key: NodeKey = key.into(); + // Ok(self + // .query_all(query)? + // .filter_map(move |node| node.get(key.clone()))) + // } } /// Represents a [`KdlNode`]'s entry key. @@ -517,11 +553,15 @@ impl IndexMut<&str> for KdlNode { } impl FromStr for KdlNode { - type Err = KdlError; + type Err = KdlParseFailure; fn from_str(input: &str) -> Result { - let kdl_parser = crate::parser::KdlParser::new(input); - kdl_parser.parse(parser::node(&kdl_parser)) + let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node, input); + if let Some(v) = maybe_val { + Ok(v) + } else { + Err(v2_parser::failure_from_errs(errs, input)) + } } } diff --git a/src/query.rs b/src/query.rs index c41a35a..6611dee 100644 --- a/src/query.rs +++ b/src/query.rs @@ -1,6 +1,6 @@ use std::{collections::VecDeque, str::FromStr, sync::Arc}; -use crate::{query_parser::KdlQueryParser, KdlDocument, KdlError, KdlNode, KdlValue}; +use crate::{query_parser::KdlQueryParser, KdlDiagnostic, KdlDocument, KdlNode, KdlValue}; /// A parsed KQL query. For details on the syntax, see the [KQL /// spec](https://github.com/kdl-org/kdl/blob/main/QUERY-SPEC.md). @@ -8,7 +8,7 @@ use crate::{query_parser::KdlQueryParser, KdlDocument, KdlError, KdlNode, KdlVal pub struct KdlQuery(pub(crate) Vec); impl FromStr for KdlQuery { - type Err = KdlError; + type Err = KdlDiagnostic; fn from_str(s: &str) -> Result { let parser = KdlQueryParser::new(s); @@ -26,29 +26,29 @@ impl<'a> IntoKdlQuery for &'a String {} #[doc(hidden)] pub trait IntoQuerySealed { - fn into_query(self) -> Result; + fn into_query(self) -> Result; } impl IntoQuerySealed for KdlQuery { - fn into_query(self) -> Result { + fn into_query(self) -> Result { Ok(self) } } impl IntoQuerySealed for &str { - fn into_query(self) -> Result { + fn into_query(self) -> Result { self.parse() } } impl IntoQuerySealed for String { - fn into_query(self) -> Result { + fn into_query(self) -> Result { self.parse() } } impl IntoQuerySealed for &String { - fn into_query(self) -> Result { + fn into_query(self) -> Result { self.parse() } } diff --git a/src/query_parser.rs b/src/query_parser.rs index 23d482d..d6c0624 100644 --- a/src/query_parser.rs +++ b/src/query_parser.rs @@ -1,10 +1,11 @@ use crate::nom_compat::many0; -use crate::parser::{value, KdlParser}; use crate::query::{ KdlQuery, KdlQueryAttributeOp, KdlQueryMatcher, KdlQueryMatcherAccessor, KdlQueryMatcherDetails, KdlQuerySelector, KdlQuerySelectorSegment, KdlSegmentCombinator, }; -use crate::{KdlError, KdlErrorKind, KdlParseError, KdlValue}; +use crate::v1_parser::{value, KdlParser}; +use crate::{KdlDiagnostic, KdlErrorKind, KdlParseError, KdlValue}; +use miette::Severity; use nom::branch::alt; use nom::bytes::complete::tag; use nom::combinator::{all_consuming, cut, map, opt, recognize}; @@ -20,7 +21,7 @@ impl<'a> KdlQueryParser<'a> { Self(KdlParser::new(full_input)) } - pub(crate) fn parse(&self, parser: P) -> Result + pub(crate) fn parse(&self, parser: P) -> Result where P: Parser<&'a str, T, KdlParseError<&'a str>>, { @@ -29,7 +30,7 @@ impl<'a> KdlQueryParser<'a> { .map(|(_, arg)| arg) .map_err(|e| { let span_substr = &e.input[..e.len]; - KdlError { + KdlDiagnostic { input: self.0.full_input.into(), span: self.0.span_from_substr(span_substr), help: if let Some(help) = e.help { @@ -47,6 +48,7 @@ impl<'a> KdlQueryParser<'a> { } else { KdlErrorKind::Context("a valid KQL query") }, + severity: Severity::Error, } }) } @@ -176,7 +178,7 @@ fn node_matchers<'a: 'b, 'b>( } } - let (input, node) = opt(crate::parser::identifier(&kdl_parser.0))(input)?; + let (input, node) = opt(crate::v1_parser::identifier(&kdl_parser.0))(input)?; if let Some(node) = node { matchers.push(KdlQueryMatcherDetails { op: KdlQueryAttributeOp::Equal, @@ -230,7 +232,7 @@ fn node_matchers<'a: 'b, 'b>( } // Check for trailing node name matcher. - let (end, ident) = opt(crate::parser::identifier(&kdl_parser.0))(input)?; + let (end, ident) = opt(crate::v1_parser::identifier(&kdl_parser.0))(input)?; if ident.is_some() { return Err(nom::Err::Error(KdlParseError { input: start, @@ -275,7 +277,7 @@ fn attribute_matcher_inner<'a: 'b, 'b>( let (input, _) = whitespace(input)?; if let Some(op) = op { let prev = input; - let (input, val) = opt(crate::parser::value)(input)?; + let (input, val) = opt(crate::v1_parser::value)(input)?; // Make sure it's a syntax error to try and use string // operators with non-string arguments. if let Some((_, value)) = val { @@ -370,7 +372,7 @@ fn annotation_matcher<'a: 'b, 'b>( let start = input; let (input, _) = tag("(")(input)?; let (input, _) = whitespace(input)?; - let (input, ty) = opt(crate::parser::identifier(&kdl_parser.0))(input)?; + let (input, ty) = opt(crate::v1_parser::identifier(&kdl_parser.0))(input)?; let (input, _) = context("closing ')' for type annotation", cut(tag(")")))(input) .map_err(|e| set_details(e, start, Some("annotation"), Some("annotations can only be KDL identifiers (including string identifiers), and can't have any space inside the parentheses.")))?; Ok(( @@ -464,7 +466,7 @@ fn prop_name_accessor<'a: 'b, 'b>( ) -> impl Fn(&'a str) -> IResult<&'a str, KdlQueryMatcherAccessor, KdlParseError<&'a str>> + 'b { move |input| { let start = input; - let (input, prop_name) = crate::parser::identifier(&kdl_parser.0)(input)?; + let (input, prop_name) = crate::v1_parser::identifier(&kdl_parser.0)(input)?; let (_, paren) = opt(preceded(whitespace, tag("(")))(input)?; if paren.is_some() { Err(nom::Err::Error(KdlParseError { @@ -512,7 +514,7 @@ fn parenthesized_prop<'a: 'b, 'b>( ) -> impl Fn(&'a str) -> IResult<&'a str, String, KdlParseError<&'a str>> + 'b { move |input| { let (input, _) = tag("(")(input)?; - let (input, prop) = crate::parser::identifier(&kdl_parser.0)(input)?; + let (input, prop) = crate::v1_parser::identifier(&kdl_parser.0)(input)?; let (input, _) = tag(")")(input)?; Ok((input, prop.value().to_owned())) } @@ -547,7 +549,7 @@ fn bad_accessor<'a: 'b, 'b>( } let (input, ident) = opt(terminated( - crate::parser::identifier(&kdl_parser.0), + crate::v1_parser::identifier(&kdl_parser.0), preceded( whitespace, terminated(tag("("), opt(preceded(whitespace, tag(")")))), @@ -585,7 +587,7 @@ fn bad_accessor<'a: 'b, 'b>( fn whitespace(input: &str) -> IResult<&str, &str, KdlParseError<&str>> { recognize(many0(alt(( - crate::parser::unicode_space, - crate::parser::newline, + crate::v1_parser::unicode_space, + crate::v1_parser::newline, ))))(input) } diff --git a/src/parser.rs b/src/v1_parser.rs similarity index 97% rename from src/parser.rs rename to src/v1_parser.rs index 74be3ed..69f21ee 100644 --- a/src/parser.rs +++ b/src/v1_parser.rs @@ -6,7 +6,7 @@ use std::ops::RangeTo; use crate::nom_compat::{many0, many1, many_till}; -use miette::SourceSpan; +use miette::{Severity, SourceSpan}; use nom::branch::alt; use nom::bytes::complete::{tag, take_until, take_while, take_while_m_n}; use nom::character::complete::{anychar, char, none_of, one_of}; @@ -16,7 +16,8 @@ use nom::sequence::{delimited, preceded, terminated, tuple}; use nom::{Finish, IResult, Offset, Parser, Slice}; use crate::{ - KdlDocument, KdlEntry, KdlError, KdlErrorKind, KdlIdentifier, KdlNode, KdlParseError, KdlValue, + KdlDiagnostic, KdlDocument, KdlEntry, KdlErrorKind, KdlIdentifier, KdlNode, KdlParseError, + KdlValue, }; /// The parser for the entire input. @@ -36,7 +37,7 @@ impl<'a> KdlParser<'a> { Self { full_input } } - pub(crate) fn parse(&self, parser: P) -> Result + pub(crate) fn parse(&self, parser: P) -> Result where P: Parser<&'a str, T, KdlParseError<&'a str>>, { @@ -45,7 +46,7 @@ impl<'a> KdlParser<'a> { .map(|(_, arg)| arg) .map_err(|e| { let span_substr = &e.input[..e.len]; - KdlError { + KdlDiagnostic { input: self.full_input.into(), span: self.span_from_substr(span_substr), help: e.help, @@ -57,6 +58,7 @@ impl<'a> KdlParser<'a> { } else { KdlErrorKind::Other }, + severity: Severity::Error, } }) } @@ -840,7 +842,7 @@ mod node_tests { #[test] fn basic() { let input = "foo 1 \"bar\"=false"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); match node(&kdl_parser)(input) { Ok(("", parsed)) => { let mut ident = KdlIdentifier::from("foo"); @@ -873,7 +875,7 @@ mod node_tests { #[test] fn errant_ident1() { let input = "struct Vec { }"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("Vec", &e.span, &input); @@ -885,7 +887,7 @@ mod node_tests { let input = r##" some_node bad evil"##; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("evil", &e.span, &input); @@ -895,7 +897,7 @@ mod node_tests { #[test] fn errant_ident3() { let input = r##"node "ok" wait "fine""##; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("wait", &e.span, &input); @@ -905,7 +907,7 @@ mod node_tests { #[test] fn errant_ident4() { let input = r##"node x="ok" oof z="5"##; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("oof", &e.span, &input); @@ -917,7 +919,7 @@ mod node_tests { // NOTE: this one is a different situation and doesn't provide as good help still! // But at least it's clear that the value is bad, which is ok! let input = r##"node x=bad"##; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("", &e.span, &input); @@ -929,7 +931,7 @@ mod node_tests { // NOTE: this one is a different situation and doesn't provide as good help still! // But at least it's clear that the value is bad, which is ok! let input = r##"node (int)bad"##; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let res = kdl_parser.parse(document(&kdl_parser)); let e = res.unwrap_err(); check_span("", &e.span, &input); @@ -952,7 +954,7 @@ mod whitespace_tests { use super::all_whitespace; let input = " \t\n\r"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); assert_eq!(all_whitespace(&kdl_parser)(input), Ok(("", " \t\n\r"))); } } @@ -964,18 +966,18 @@ mod comment_tests { #[test] fn single_line() { let input = "// Hello world"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); assert_eq!(comment(&kdl_parser)(input), Ok(("", "// Hello world"))); } #[test] fn multi_line() { let input = "/* Hello world */"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); assert_eq!(comment(&kdl_parser)(input), Ok(("", "/* Hello world */"))); let input = "/* Hello /* world */ blah */"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); assert_eq!( comment(&kdl_parser)(input), Ok(("", "/* Hello /* world */ blah */")) @@ -985,7 +987,7 @@ mod comment_tests { #[test] fn slashdash() { let input = "/-foo 1 2"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); assert_eq!(comment(&kdl_parser)(input), Ok(("", "/-foo 1 2"))); } @@ -1071,7 +1073,7 @@ mod value_tests { )) ); let input = "node 0x0123_4567_89ab_cdef"; - let kdl_parser = crate::parser::KdlParser::new(input); + let kdl_parser = crate::v1_parser::KdlParser::new(input); let (_, n) = node(&kdl_parser)(input).expect("failed to parse node"); assert_eq!(&n[0], &KdlValue::Base16(0x0123456789abcdef)); assert_eq!( diff --git a/src/v2_parser.rs b/src/v2_parser.rs new file mode 100644 index 0000000..402d24d --- /dev/null +++ b/src/v2_parser.rs @@ -0,0 +1,1093 @@ +// A bunch of random variables/functions become dead when you disable +// span support and rather than turning the code into complete cfg +// swiss-cheese, it's simpler to just hush the compiler about it +#![cfg_attr(not(feature = "span"), allow(dead_code, unused_variables))] + +use std::{ + num::{ParseFloatError, ParseIntError}, + sync::Arc, +}; + +use miette::{Severity, SourceSpan}; + +use winnow::{ + ascii::{digit1, hex_digit1, oct_digit1, Caseless}, + combinator::{alt, cut_err, eof, not, opt, peek, preceded, repeat, repeat_till}, + error::{ + AddContext, ContextError, ErrMode, ErrorKind, FromExternalError, FromRecoverableError, + ParserError, StrContext, StrContextValue, + }, + prelude::*, + stream::{AsChar, Location, Recoverable, Stream}, + token::{any, none_of, one_of, take_until, take_while}, + Located, +}; + +use crate::{ + KdlDiagnostic, KdlDocument, KdlEntry, KdlErrorKind, KdlIdentifier, KdlNode, KdlParseFailure, + KdlValue, +}; + +type Input<'a> = Recoverable, KdlParseError>; +type PResult = winnow::PResult; + +impl std::str::FromStr for KdlDocument { + type Err = KdlParseFailure; + + fn from_str(s: &str) -> Result { + let (maybe_val, errs) = try_parse(document, s); + if let Some(v) = maybe_val { + Ok(v) + } else { + Err(failure_from_errs(errs, s)) + } + } +} + +pub(crate) fn try_parse<'a, P: Parser, T, KdlParseError>, T>( + mut parser: P, + input: &'a str, +) -> (Option, Vec) { + let (_, maybe_val, errs) = parser.recoverable_parse(Located::new(input)); + (maybe_val, errs) +} + +pub(crate) fn failure_from_errs(errs: Vec, input: &str) -> KdlParseFailure { + let src = Arc::new(String::from(input)); + KdlParseFailure { + input: src.clone(), + diagnostics: errs + .into_iter() + .map(|e| KdlDiagnostic { + input: src.clone(), + span: e.span.unwrap_or_else(|| (0usize..0usize).into()), + label: e.label, + help: e.help, + severity: Severity::Error, + kind: if let Some(ctx) = e.context { + KdlErrorKind::Context(ctx) + } else { + KdlErrorKind::Other + }, + }) + .collect(), + } +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub(crate) struct KdlParseError { + pub(crate) context: Option<&'static str>, + pub(crate) span: Option, + pub(crate) label: Option<&'static str>, + pub(crate) help: Option<&'static str>, + pub(crate) kind: Option, + pub(crate) touched: bool, +} + +fn set_span(err: &mut ErrMode, start: usize, end: usize) { + match err { + ErrMode::Backtrack(e) | ErrMode::Cut(e) => { + e.span = Some(SourceSpan::new(start.into(), end - start)); + } + ErrMode::Incomplete(_) => {} + } +} + +impl ParserError for KdlParseError { + fn from_error_kind(_input: &I, _kind: ErrorKind) -> Self { + Self { + span: None, + label: None, + help: None, + context: None, + kind: None, + touched: false, + } + } + + fn append( + self, + _input: &I, + _token_start: &::Checkpoint, + _kind: ErrorKind, + ) -> Self { + self + } +} + +impl AddContext for KdlParseError { + fn add_context( + mut self, + _input: &I, + _token_start: &::Checkpoint, + ctx: &'static str, + ) -> Self { + self.context = self.context.or(Some(ctx)); + self + } +} + +impl<'a> FromExternalError, ParseIntError> for KdlParseError { + fn from_external_error(_: &Input<'a>, _kind: ErrorKind, e: ParseIntError) -> Self { + KdlParseError { + span: None, + label: None, + help: None, + context: None, + kind: Some(KdlErrorKind::ParseIntError(e)), + touched: false, + } + } +} + +impl<'a> FromExternalError, ParseFloatError> for KdlParseError { + fn from_external_error(_input: &Input<'a>, _kind: ErrorKind, e: ParseFloatError) -> Self { + KdlParseError { + span: None, + label: None, + help: None, + context: None, + kind: Some(KdlErrorKind::ParseFloatError(e)), + touched: false, + } + } +} + +impl FromRecoverableError for KdlParseError { + #[inline] + fn from_recoverable_error( + _token_start: &::Checkpoint, + _err_start: &::Checkpoint, + _input: &I, + e: Self, + ) -> Self { + e + } +} + +impl FromRecoverableError for KdlParseError { + #[inline] + fn from_recoverable_error( + _token_start: &::Checkpoint, + _err_start: &::Checkpoint, + _input: &I, + e: ContextError, + ) -> Self { + KdlParseError { + span: None, + label: None, + help: None, + context: e.context().next().and_then(|e| match e { + StrContext::Label(l) => Some(*l), + StrContext::Expected(StrContextValue::StringLiteral(s)) => Some(*s), + StrContext::Expected(StrContextValue::Description(s)) => Some(*s), + _ => None, + }), + kind: None, + touched: false, + } + } +} + +/// Consumes the rest of a value we've cut_err on, so we can contine the parse. +// TODO: maybe use this for detecting invalid codepoints with useful errors? +fn badval<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat_till( + 0.., + (not(alt((ws, newline, eof.void()))), any), + alt((eof.void(), peek(alt((ws, newline, eof.void()))))), + ) + .map(|(_, _): ((), _)| ()) + .parse_next(input) +} + +fn lbl(label: &'static str) -> &'static str { + label +} + +#[cfg(test)] +fn new_input<'a>(s: &'a str) -> Input<'a> { + Recoverable::new(Located::new(s)) +} + +/// `document := bom? nodes` +fn document<'s>(input: &mut Input<'s>) -> PResult { + let bom = opt(bom.recognize()).parse_next(input)?; + let mut doc = nodes.parse_next(input)?; + if let Some(bom) = bom { + doc.leading = Some(if let Some(leading) = doc.leading { + format!("{bom}{leading}") + } else { + bom.into() + }); + } + Ok(doc) +} + +/// `nodes := (line-space* node)* line-space*` +fn nodes<'s>(input: &mut Input<'s>) -> PResult { + let ((leading, nodes, trailing), span) = ( + repeat(0.., line_space).map(|()| ()).recognize(), + repeat(0.., node), + repeat(0.., line_space).map(|()| ()).recognize(), + ) + .with_span() + .parse_next(input)?; + Ok(KdlDocument { + leading: Some(leading.into()), + nodes, + trailing: Some(trailing.into()), + span: span.into(), + }) +} + +/// `base-node := type? optional-node-space string (required-node-space node-prop-or-arg)* (required-node-space node-children)?` +fn base_node<'s>(input: &mut Input<'s>) -> PResult { + let ((ty, after_ty, name, entries, before_children, children), span) = ( + opt(ty), + optional_node_space.recognize(), + identifier, + repeat( + 0.., + (required_node_space, node_entry).map(|(_, e): ((), _)| e), + ) + .map(|e: Vec>| e.into_iter().filter_map(|e| e).collect::>()), + required_node_space.recognize(), + opt(node_children), + ) + .with_span() + .parse_next(input)?; + let (before_inner_ty, ty, after_inner_ty) = if let Some(ty_info) = ty { + ty_info + } else { + ("", None, "") + }; + Ok(KdlNode { + ty, + after_ty: Some(after_ty.into()), + before_ty_name: Some(before_inner_ty.into()), + after_ty_name: Some(after_inner_ty.into()), + name, + entries, + children, + span: span.into(), + before_children: Some(before_children.into()), + leading: None, + trailing: None, + }) +} + +/// `node := base-node optional-node-space node-terminator` +fn node<'s>(input: &mut Input<'s>) -> PResult { + let ((leading, mut node, trailing, terminator), span) = ( + repeat(0.., line_space).map(|()| ()).recognize(), + base_node, + optional_node_space.recognize(), + node_terminator.recognize(), + ) + .context("node") + .with_span() + .parse_next(input)?; + node.leading = Some(leading.into()); + node.trailing = Some(format!("{trailing}{terminator}")); + node.span = span.into(); + Ok(node) +} + +pub(crate) fn padded_node<'s>(input: &mut Input<'s>) -> PResult { + let ((mut node, trailing), span) = ( + node, + repeat(0.., plain_node_space).map(|_: ()| ()).recognize(), + ) + .with_span() + .parse_next(input)?; + node.trailing = node.trailing.map(|t| format!("{t}{trailing}")); + node.span = span.into(); + Ok(node) +} + +/// `final-node := base-node optional-node-space node-terminator?` +fn final_node<'s>(input: &mut Input<'s>) -> PResult { + let node = base_node.parse_next(input)?; + optional_node_space.parse_next(input)?; + opt(node_terminator).parse_next(input)?; + Ok(node) +} + +pub(crate) fn padded_node_entry<'s>(input: &mut Input<'s>) -> PResult> { + let ((leading, entry, trailing), span) = ( + repeat(0.., plain_node_space).map(|_: ()| ()).recognize(), + node_entry, + repeat(0.., plain_node_space).map(|_: ()| ()).recognize(), + ) + .with_span() + .parse_next(input)?; + Ok(entry.map(|mut val| { + val.leading = Some(leading.into()); + val.trailing = Some(trailing.into()); + val.span = span.into(); + val + })) +} + +/// `node-prop-or-arg := prop | value` +fn node_entry<'s>(input: &mut Input<'s>) -> PResult> { + let ((leading, mut entry), span) = (required_node_space.recognize(), alt((prop, value))) + .context(lbl("node entry")) + .with_span() + .parse_next(input)?; + entry = entry.map(|mut e| { + e.set_span(span); + e.set_leading(leading); + e + }); + Ok(entry) +} + +/// `node-children := '{' nodes final-node? '}'` +fn node_children<'s>(input: &mut Input<'s>) -> PResult { + let start = input.location(); + "{".parse_next(input)?; + let mut ns = cut_err(nodes).parse_next(input).map_err(|mut e| { + set_span(&mut e, start, input.location()); + e + })?; + let fin = opt(final_node).parse_next(input)?; + if let Some(fin) = fin { + ns.nodes.push(fin); + } + cut_err("}").parse_next(input)?; + Ok(ns) +} + +/// `node-terminator := single-line-comment | newline | ';' | eof` +fn node_terminator<'s>(input: &mut Input<'s>) -> PResult<()> { + alt((single_line_comment, newline, ";".void(), eof.void())).parse_next(input) +} + +/// `prop := string optional-node-space equals-sign optional-node-space value` +fn prop<'s>(input: &mut Input<'s>) -> PResult> { + let ((key, after_key, eq, after_eq, value), span) = ( + identifier, + optional_node_space.recognize(), + equals_sign.recognize(), + optional_node_space.recognize(), + cut_err(value) + .context("property value") + .resume_after(badval), + ) + .context("property") + .with_span() + .parse_next(input)?; + Ok(value.flatten().map(|mut value| { + value.name = Some(key); + value.span = span.into(); + value + })) + // KdlEntry { + // ty: value.ty, + // after_ty: Some(after_ty.into()), + // before_ty_name: Some(before_inner_ty.into()), + // after_ty_name: Some(after_inner_ty.into()), + // name: Some(key), + // value: value.value, + // value_repr: Some(raw.into()), + // leading: None, + // trailing: Some("".into()), + // span: span.into(), + // }})) +} + +/// `value := type? optional-node-space (string | number | keyword)` +fn value<'s>(input: &mut Input<'s>) -> PResult> { + let ((ty, _, (value, raw)), span) = ( + opt(ty), + optional_node_space, + alt((string, number, keyword)) + .context(lbl("value")) + .resume_after(badval) + .with_recognized(), + ) + .with_span() + .parse_next(input)?; + let (before_ty, ty, after_ty) = if let Some(ty_info) = ty { + ty_info + } else { + ("", None, "") + }; + Ok(value.flatten().map(|value| KdlEntry { + ty, + value, + leading: None, + value_repr: Some(raw.into()), + name: None, + trailing: Some("".into()), + span: span.into(), + })) +} + +/// `type := '(' optional-node-space string optional-node-space ')'` +fn ty<'s>(input: &mut Input<'s>) -> PResult<(&'s str, Option, &'s str)> { + "(".parse_next(input)?; + let (before_ty, ty, after_ty) = ( + optional_node_space.recognize(), + cut_err(identifier.context(lbl("type name"))) + .resume_after((badval, peek(")").void(), badval).void()), + optional_node_space.recognize(), + ) + .parse_next(input)?; + cut_err(")").parse_next(input)?; + Ok((before_ty, ty, after_ty)) +} + +/// `plain-line-space := newline | ws | single-line-comment` +fn plain_line_space<'s>(input: &mut Input<'s>) -> PResult<()> { + alt((newline, ws, single_line_comment)).parse_next(input) +} + +/// `plain-node-space := ws* escline ws* | ws+` +fn plain_node_space<'s>(input: &mut Input<'s>) -> PResult<()> { + alt((escline, wsp)).parse_next(input) +} + +/// `line-space := plain-line-space+ | '/-' plain-node-space* node` +fn line_space<'s>(input: &mut Input<'s>) -> PResult<()> { + alt(( + repeat(1.., plain_line_space).map(|_: ()| ()).void(), + ( + "/-", + repeat(0.., plain_node_space).map(|_: ()| ()), + cut_err(node), + ) + .void() + .context(lbl("slashdashed node")), + )) + .parse_next(input) +} + +/// `node-space := plain-node-space+ ('/-' plain-node-space* (node-prop-or-arg | node-children))?` +fn node_space<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat(1.., plain_node_space) + .map(|_: ()| ()) + .parse_next(input)?; + opt(( + "/-", + repeat(0.., plain_node_space).map(|_: ()| ()), + cut_err(alt(( + node_entry.void().context(lbl("slashdashed entry")), + node_children.void().context(lbl("slashdashed children")), + ))), + )) + .void() + .parse_next(input) +} + +/// `required-node-space := node-space* plain-node-space+` +fn required_node_space<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat(0.., node_space).map(|_: ()| ()).parse_next(input)?; + repeat(1.., plain_node_space).parse_next(input) +} + +/// `optional-node-space := node-space*` +fn optional_node_space<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat(0.., node_space).parse_next(input) +} + +/// `string := identifier-string | quoted-string | raw-string` +pub(crate) fn string<'s>(input: &mut Input<'s>) -> PResult> { + alt((identifier_string, raw_string, quoted_string)) + .context("string") + .parse_next(input) +} + +pub(crate) fn identifier<'s>(input: &mut Input<'s>) -> PResult { + let ((mut ident, raw), span) = string + .verify_map(|i| { + i.and_then(|v| match v { + KdlValue::String(s) => Some(KdlIdentifier::from(s)), + _ => None, + }) + }) + .with_recognized() + .with_span() + .parse_next(input)?; + ident.set_repr(raw); + ident.set_span(span); + Ok(ident) +} + +/// `identifier-string := unambiguous-ident | signed-ident | dotted-ident` +fn identifier_string<'s>(input: &mut Input<'s>) -> PResult> { + alt((unambiguous_ident, signed_ident, dotted_ident)) + .recognize() + .map(|s| Some(KdlValue::String(s.into()))) + .parse_next(input) +} + +/// `unambiguous-ident := ((identifier-char - digit - sign - '.') identifier-char*) - 'true' - 'false' - 'null' - 'inf' - '-inf' - 'nan'` +fn unambiguous_ident<'s>(input: &mut Input<'s>) -> PResult<()> { + not(alt((digit1.void(), alt(("-", "+")).void(), ".".void()))).parse_next(input)?; + repeat(1.., identifier_char) + .verify_map(|s: String| { + if s == "true" || s == "false" || s == "null" || s == "inf" || s == "-inf" || s == "nan" + { + None + } else { + Some(s) + } + }) + .void() + .parse_next(input) +} + +/// `signed-ident := sign ((identifier-char - digit - '.') identifier-char*)?` +fn signed_ident<'s>(input: &mut Input<'s>) -> PResult<()> { + alt(("+", "-")).parse_next(input)?; + not(alt((digit1.void(), ".".void()))).parse_next(input)?; + repeat(0.., identifier_char).parse_next(input) +} + +/// `dotted-ident := sign? '.' ((identifier-char - digit) identifier-char*)?` +fn dotted_ident<'s>(input: &mut Input<'s>) -> PResult<()> { + ( + opt(sign), + ".", + not(digit1), + repeat(1.., identifier_char).map(|_: ()| ()), + ) + .void() + .parse_next(input) +} + +/// `identifier-char := unicode - unicode-space - newline - [\\/(){};\[\]"#] - disallowed-literal-code-points - equals-sign` +fn identifier_char<'s>(input: &mut Input<'s>) -> PResult { + ( + not(alt(( + unicode_space, + newline, + disallowed_unicode, + equals_sign, + ))), + none_of(['\\', '/', '(', ')', '{', '}', '[', ']', ';', '"', '#']), + ) + .map(|(_, c)| c) + .parse_next(input) +} + +/// `equals-sign := See Table ([Equals Sign](#equals-sign))` +fn equals_sign<'s>(input: &mut Input<'s>) -> PResult<()> { + one_of(['=', '﹦', '=', '🟰']) + .map(|_| ()) + .parse_next(input) +} + +/// ```text +/// quoted-string := '"' (single-line-string-body | newline multi-line-string-body newline unicode-space*) '"' +/// single-line-string-body := (string-character - newline)* +/// multi-line-string-body := string-character* +/// ``` +fn quoted_string<'s>(input: &mut Input<'s>) -> PResult> { + "\"".parse_next(input)?; + let is_multiline = opt(newline).parse_next(input)?.is_some(); + let ml_prefix: Option = if is_multiline { + Some( + peek(repeat(0.., unicode_space).map(|_: ()| ()).recognize()) + .parse_next(input)? + .to_string(), + ) + } else { + None + }; + let body: Option = if let Some(prefix) = ml_prefix { + cut_err(repeat_till( + 0.., + (&prefix[..], string_char, newline).map(|(_, s, _)| s), + (&prefix[..], "\""), + )) + .map(|(s, _): (String, _)| s) + .resume_after(quoted_string_badval) + .parse_next(input)? + } else { + cut_err(repeat_till( + 0.., + (not(newline), string_char).map(|(_, s)| s), + "\"", + )) + .map(|(s, _): (String, _)| s) + .resume_after(quoted_string_badval) + .parse_next(input)? + }; + Ok(body.map(|body| KdlValue::String(body))) +} + +/// Like badval, but is able to slurp up invalid raw strings, which contain whitespace. +fn quoted_string_badval<'s>(input: &mut Input<'s>) -> PResult<()> { + let terminator = ("\"", peek(alt((ws, newline, eof.void())))); + let terminator2 = ("\"", peek(alt((ws, newline, eof.void())))); + repeat_till(0.., (not(terminator), any), terminator2) + .map(|(v, _)| v) + .parse_next(input) +} +/// ```text +/// string-character := '\' escape | [^\\"] - disallowed-literal-code-points +/// ``` +fn string_char<'s>(input: &mut Input<'s>) -> PResult { + alt(( + escaped_char, + (not(disallowed_unicode), none_of(['\\', '"'])).map(|(_, c)| c), + )) + .parse_next(input) +} + +/// ```text +/// escape := ["\\bfnrts] | 'u{' hex-digit{1, 6} '}' | (unicode-space | newline)+ +/// hex-digit := [0-9a-fA-F] +/// ``` +fn escaped_char<'s>(input: &mut Input<'s>) -> PResult { + alt(( + preceded( + "\\", + alt(( + "\\".value('\\'), + "\"".value('\"'), + "b".value('\u{0008}'), + "f".value('\u{000C}'), + "n".value('\n'), + "r".value('\r'), + "t".value('\t'), + "s".value(' '), + )), + ), + ( + "u{", + cut_err(take_while(1..6, AsChar::is_hex_digit)), + cut_err("}"), + ) + .verify_map(|(_, hx, _)| { + let val = u32::from_str_radix(hx, 16) + .expect("Should have already been validated to be a hex string."); + char::from_u32(val) + }), + repeat(1.., alt((unicode_space, newline))).map(|_: ()| ' '), + )) + .parse_next(input) +} + +/// `raw-string := '#' raw-string-quotes '#' | '#' raw-string '#'` +/// `raw-string-quotes := '"' (single-line-raw-string-body | newline multi-line-raw-string-body newline unicode-space*) '"'` +/// `single-line-raw-string-body := (unicode - newline - disallowed-literal-code-points)*` +/// `multi-line-raw-string-body := (unicode - disallowed-literal-code-points)` +fn raw_string<'s>(input: &mut Input<'s>) -> PResult> { + let hashes = repeat(1.., "#").parse_next(input)?; + "\"".parse_next(input)?; + let is_multiline = opt(newline).parse_next(input)?.is_some(); + let ml_prefix: Option = if is_multiline { + Some( + peek(repeat(0.., unicode_space).map(|_: ()| ()).recognize()) + .parse_next(input)? + .to_string(), + ) + } else { + None + }; + let body: Option = if let Some(prefix) = ml_prefix { + cut_err(repeat_till( + 0.., + ( + &prefix[..], + not(disallowed_unicode), + not(("\"", hashes)), + any, + newline, + ) + .map(|(_, _, _, s, _)| s), + (&prefix[..], "\"", hashes), + )) + .map(|(s, _): (String, _)| s) + .resume_after(raw_string_badval) + .parse_next(input)? + } else { + cut_err(repeat_till( + 0.., + ( + not(disallowed_unicode), + not(newline), + not(("\"", hashes)), + any, + ) + .map(|(_, _, _, s)| s), + ("\"", hashes), + )) + .map(|(s, _): (String, _)| s) + .resume_after(raw_string_badval) + .parse_next(input)? + }; + Ok(body.map(|body| KdlValue::String(body))) +} + +/// Like badval, but is able to slurp up invalid raw strings, which contain whitespace. +fn raw_string_badval<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat_till( + 0.., + (not(alt(("#", "\""))), any), + (alt(("#", "\"")), peek(alt((ws, newline, eof.void())))), + ) + .map(|(v, _)| v) + .parse_next(input) +} + +/// ```text +/// keyword := '#true' | '#false' | '#null' +/// keyword-number := '#inf' | '#-inf' | '#nan' +/// ```` +fn keyword<'s>(input: &mut Input<'s>) -> PResult> { + let _ = "#".parse_next(input)?; + let _ = not(one_of(['#', '"'])).parse_next(input)?; + cut_err(alt(( + Caseless("true").map(|_| KdlValue::Bool(true)), + Caseless("false").map(|_| KdlValue::Bool(false)), + Caseless("null").map(|_| KdlValue::Null), + Caseless("nan").map(|_| KdlValue::Base10Float(f64::NAN)), + Caseless("inf").map(|_| KdlValue::Base10Float(f64::INFINITY)), + Caseless("-inf").map(|_| KdlValue::Base10Float(f64::NEG_INFINITY)), + ))) + .context(lbl("keyword")) + .resume_after(badval) + .parse_next(input) +} + +/// `bom := '\u{FEFF}'` +fn bom<'s>(input: &mut Input<'s>) -> PResult<()> { + "\u{FEFF}".map(|_| ()).parse_next(input) +} + +/// `disallowed-literal-code-points := See Table (Disallowed Literal Code +/// Points)` +/// ```markdown +/// * The codepoints `U+0000-0008` or the codepoints `U+000E-001F` (various +/// control characters). +/// * `U+007F` (the Delete control character). +/// * Any codepoint that is not a [Unicode Scalar +/// Value](https://unicode.org/glossary/#unicode_scalar_value) (`U+D800-DFFF`). +/// * `U+200E-200F`, `U+202A-202E`, and `U+2066-2069`, the [unicode +/// "direction control" +/// characters](https://www.w3.org/International/questions/qa-bidi-unicode-controls) +/// * `U+FEFF`, aka Zero-width Non-breaking Space (ZWNBSP)/Byte Order Mark (BOM), +/// except as the first code point in a document. +/// ``` +fn disallowed_unicode<'s>(input: &mut Input<'s>) -> PResult<()> { + take_while(1.., |c| match c { + '\u{0000}'..='\u{0008}' => true, + '\u{000E}'..='\u{001F}' => true, + '\u{200E}'..='\u{200F}' => true, + '\u{202A}'..='\u{202E}' => true, + '\u{2066}'..='\u{2069}' => true, + '\u{FEFF}' => true, + _ => false, + }) + .void() + .parse_next(input) +} + +/// `escline := '\\' ws* (single-line-comment | newline | eof)` +fn escline<'s>(input: &mut Input<'s>) -> PResult<()> { + "\\".parse_next(input)?; + repeat(0.., ws).map(|_: ()| ()).parse_next(input)?; + alt((single_line_comment, newline, eof.void())).parse_next(input) +} + +/// `newline := ` +fn newline<'s>(input: &mut Input<'s>) -> PResult<()> { + alt(( + "\u{000D}", + "\u{000A}", + "\u{0085}", + "\u{000C}", + "\u{2028}", + "\u{2029}", + "\u{000D}\u{000A}", + )) + .void() + .context(lbl("newline")) + .parse_next(input) +} + +fn wsp<'s>(input: &mut Input<'s>) -> PResult<()> { + repeat(1.., ws).parse_next(input) +} + +/// `ws := unicode-space | multi-line-comment`` +fn ws<'s>(input: &mut Input<'s>) -> PResult<()> { + alt((unicode_space, multi_line_comment)).parse_next(input) +} + +/// `unicode-space := ` +fn unicode_space<'s>(input: &mut Input<'s>) -> PResult<()> { + alt(( + '\u{0009}', '\u{000B}', '\u{0020}', '\u{00A0}', '\u{1680}', '\u{2000}', '\u{2001}', + '\u{2002}', '\u{2003}', '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', + '\u{2009}', '\u{200A}', '\u{202F}', '\u{205F}', '\u{3000}', + )) + .map(|_| ()) + .parse_next(input) +} + +/// `single-line-comment := '//' ^newline* (newline | eof)` +fn single_line_comment<'s>(input: &mut Input<'s>) -> PResult<()> { + "//".parse_next(input)?; + repeat_till( + 0.., + (not(alt((newline, eof.void()))), any), + alt((newline, eof.void())), + ) + .map(|(_, _): ((), _)| ()) + .parse_next(input) +} + +/// `multi-line-comment := '/*' commented-block` +fn multi_line_comment<'s>(input: &mut Input<'s>) -> PResult<()> { + "/*".parse_next(input)?; + cut_err(commented_block) + .context(lbl("closing of multi-line comment")) + .parse_next(input) +} + +/// `commented-block := '*/' | (multi-line-comment | '*' | '/' | [^*/]+) commented-block` +fn commented_block<'s>(input: &mut Input<'s>) -> PResult<()> { + alt(( + "*/".void(), + preceded( + alt(( + multi_line_comment, + "*".void(), + "/".void(), + take_until(1.., "*/").void(), + )), + commented_block, + ), + )) + .parse_next(input) +} + +/// `multi-line-comment :` +/// `number := keyword-number | hex | octal | binary | decimal` +fn number<'s>(input: &mut Input<'s>) -> PResult> { + alt((hex, octal, binary, float, integer)).parse_next(input) +} + +/// ```text +/// decimal := sign? integer ('.' integer)? exponent? +/// exponent := ('e' | 'E') sign? integer +/// ``` +fn float<'s>(input: &mut Input<'s>) -> PResult> { + alt(( + ( + integer, + opt(preceded('.', cut_err(integer_base))), + Caseless("e"), + opt(one_of(['-', '+'])), + cut_err(integer_base), + ) + .recognize(), + (integer, '.', cut_err(integer_base)).recognize(), + )) + .try_map(|float_str| { + str::replace(float_str, "_", "") + .parse::() + .map(KdlValue::Base10Float) + }) + .context(lbl("float")) + .resume_after(badval) + .parse_next(input) +} + +#[cfg(test)] +#[test] +fn float_test() { + use winnow::token::take; + + assert_eq!( + float.parse(new_input("12_34.56")).unwrap(), + Some(KdlValue::Base10Float(1234.56)) + ); + assert_eq!( + float.parse(new_input("1234_.56")).unwrap(), + Some(KdlValue::Base10Float(1234.56)) + ); + assert_eq!( + (float, take(1usize)).parse(new_input("1234.56c")).unwrap(), + (Some(KdlValue::Base10Float(1234.56)), "c") + ); + assert!(float.parse(new_input("_1234.56")).unwrap().is_none()); + assert!(float.parse(new_input("1234a.56")).unwrap().is_none()); +} + +/// Non-float decimal +fn integer<'s>(input: &mut Input<'s>) -> PResult> { + let mult = sign.parse_next(input)?; + integer_base + .map(|x| x.map(|x| KdlValue::Base10(x * mult))) + .context(lbl("integer")) + .parse_next(input) +} + +#[cfg(test)] +#[test] +fn integer_test() { + assert_eq!( + integer.parse(new_input("12_34")).unwrap(), + Some(KdlValue::Base10(1234)) + ); + assert_eq!( + integer.parse(new_input("1234_")).unwrap(), + Some(KdlValue::Base10(1234)) + ); + assert!(integer.parse(new_input("_1234")).is_err()); + assert!(integer.parse(new_input("1234a")).is_err()); +} + +/// `integer := digit (digit | '_')*` +fn integer_base<'s>(input: &mut Input<'s>) -> PResult> { + ( + digit1, + cut_err(repeat( + 0.., + alt(("_", take_while(1.., AsChar::is_dec_digit).recognize())), + )) + .resume_after(badval), + ) + .try_map(|(l, r): (&str, Option>)| { + r.map(|r| format!("{l}{}", str::replace(&r.join(""), "_", "")).parse()) + .map_or(Ok(None), |v| v.map(Some)) + }) + .parse_next(input) +} + +/// `hex := sign? '0x' hex-digit (hex-digit | '_')*` +fn hex<'s>(input: &mut Input<'s>) -> PResult> { + let mult = sign.parse_next(input)?; + alt(("0x", "0X")).parse_next(input)?; + cut_err(( + hex_digit1, + repeat( + 0.., + alt(("_", take_while(1.., AsChar::is_hex_digit).recognize())), + ), + )) + .try_map(|(l, r): (&str, Vec<&str>)| { + i64::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 16) + .map(|x| x * mult) + .map(KdlValue::Base16) + }) + .context(lbl("hexadecimal")) + .resume_after(badval) + .parse_next(input) +} + +#[cfg(test)] +#[test] +fn test_hex() { + assert_eq!( + hex.parse(new_input("0xdead_beef123")).unwrap(), + Some(KdlValue::Base16(0xdeadbeef123)) + ); + assert_eq!( + hex.parse(new_input("0xDeAd_BeEf123")).unwrap(), + Some(KdlValue::Base16(0xdeadbeef123)) + ); + assert_eq!( + hex.parse(new_input("0xdeadbeef123_")).unwrap(), + Some(KdlValue::Base16(0xdeadbeef123)) + ); + assert!(hex.parse(new_input("0x_deadbeef123")).unwrap().is_none()); + assert!(hex.parse(new_input("0xbeefg1")).is_err()); +} + +/// `octal := sign? '0o' [0-7] [0-7_]*` +fn octal<'s>(input: &mut Input<'s>) -> PResult> { + let mult = sign.parse_next(input)?; + alt(("0o", "0O")).parse_next(input)?; + cut_err(( + oct_digit1, + repeat( + 0.., + alt(("_", take_while(1.., AsChar::is_oct_digit).recognize())), + ), + )) + .try_map(|(l, r): (&str, Vec<&str>)| { + i64::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 8) + .map(|x| x * mult) + .map(KdlValue::Base8) + }) + .context(lbl("octal")) + .resume_after(badval) + .parse_next(input) +} + +#[cfg(test)] +#[test] +fn test_octal() { + assert_eq!( + octal.parse(new_input("0o12_34")).unwrap(), + Some(KdlValue::Base8(0o1234)) + ); + assert_eq!( + octal.parse(new_input("0o1234_")).unwrap(), + Some(KdlValue::Base8(0o1234)) + ); + assert!(octal.parse(new_input("0o_12_34")).unwrap().is_none()); + assert!(octal.parse(new_input("0o89")).unwrap().is_none()); +} + +/// `binary := sign? '0b' ('0' | '1') ('0' | '1' | '_')*` +fn binary<'s>(input: &mut Input<'s>) -> PResult> { + let mult = sign.parse_next(input)?; + alt(("0b", "0B")).parse_next(input)?; + cut_err( + (alt(("0", "1")), repeat(0.., alt(("0", "1", "_")))).try_map( + move |(x, xs): (&str, Vec<&str>)| { + i64::from_str_radix(&format!("{x}{}", str::replace(&xs.join(""), "_", "")), 2) + .map(|x| x * mult) + .map(KdlValue::Base2) + }, + ), + ) + .context(lbl("binary")) + .resume_after(badval) + .parse_next(input) +} + +#[cfg(test)] +#[test] +fn test_binary() { + use winnow::token::take; + + assert_eq!( + binary.parse(new_input("0b10_01")).unwrap(), + Some(KdlValue::Base2(0b1001)) + ); + assert_eq!( + binary.parse(new_input("0b1001_")).unwrap(), + Some(KdlValue::Base2(0b1001)) + ); + assert!(binary.parse(new_input("0b_10_01")).unwrap().is_none()); + assert_eq!( + (binary, take(4usize)).parse(new_input("0b12389")).unwrap(), + (Some(KdlValue::Base2(1)), "2389") + ); + assert!(binary.parse(new_input("123")).is_err()); +} + +fn sign<'s>(input: &mut Input<'s>) -> PResult { + let sign = opt(alt(('+', '-'))).parse_next(input)?; + let mult = if let Some(sign) = sign { + if sign == '+' { + 1 + } else { + -1 + } + } else { + 1 + }; + Ok(mult) +} diff --git a/src/value.rs b/src/value.rs index a155cf4..51624f6 100644 --- a/src/value.rs +++ b/src/value.rs @@ -4,6 +4,8 @@ use std::fmt::Display; #[derive(Debug, Clone, PartialOrd)] pub enum KdlValue { /// A [KDL Raw String](https://github.com/kdl-org/kdl/blob/main/SPEC.md#raw-string). + // TODO: remove this and use `String` for all strings. We can use the repr + // to keep track of whether it's raw or not. RawString(String), /// A [KDL String](https://github.com/kdl-org/kdl/blob/main/SPEC.md#string). diff --git a/tests/compliance.rs b/tests/compliance.rs index 9012f22..d39a948 100644 --- a/tests/compliance.rs +++ b/tests/compliance.rs @@ -4,7 +4,7 @@ use std::{ path::{Path, PathBuf}, }; -use kdl::{KdlDocument, KdlError, KdlIdentifier, KdlValue}; +use kdl::{KdlDocument, KdlIdentifier, KdlParseFailure, KdlValue}; use miette::IntoDiagnostic; #[test] @@ -21,13 +21,13 @@ fn spec_compliance() -> miette::Result<()> { ); let src = normalize_line_endings(fs::read_to_string(&test_path).into_diagnostic()?); println!("src: {}", src); - let res: Result = src.parse(); + let res: Result = src.parse(); validate_res(res, &test_path)?; } Ok(()) } -fn validate_res(res: Result, path: &Path) -> miette::Result<()> { +fn validate_res(res: Result, path: &Path) -> miette::Result<()> { let file_name = path.file_name().unwrap(); let expected_dir = path .parent() diff --git a/tests/query_api.rs b/tests/disabled_tests/query_api.rs similarity index 100% rename from tests/query_api.rs rename to tests/disabled_tests/query_api.rs diff --git a/tests/query_matchers.rs b/tests/disabled_tests/query_matchers.rs similarity index 100% rename from tests/query_matchers.rs rename to tests/disabled_tests/query_matchers.rs diff --git a/tests/query_ops.rs b/tests/disabled_tests/query_ops.rs similarity index 100% rename from tests/query_ops.rs rename to tests/disabled_tests/query_ops.rs diff --git a/tests/query_syntax.rs b/tests/disabled_tests/query_syntax.rs similarity index 100% rename from tests/query_syntax.rs rename to tests/disabled_tests/query_syntax.rs diff --git a/tests/test_cases/expected_kdl/_negative_exponent.kdl b/tests/test_cases/expected_kdl/_negative_exponent.kdl deleted file mode 100644 index 88982b3..0000000 --- a/tests/test_cases/expected_kdl/_negative_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1e-10 diff --git a/tests/test_cases/expected_kdl/_parse_all_arg_types.kdl b/tests/test_cases/expected_kdl/_parse_all_arg_types.kdl deleted file mode 100644 index b9b369e..0000000 --- a/tests/test_cases/expected_kdl/_parse_all_arg_types.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1 1.0 10000000000.0 1e-10 1 7 2 "arg" "arg\\\\" true false null diff --git a/tests/test_cases/expected_kdl/_positive_exponent.kdl b/tests/test_cases/expected_kdl/_positive_exponent.kdl deleted file mode 100644 index 0592b9c..0000000 --- a/tests/test_cases/expected_kdl/_positive_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 10000000000.0 diff --git a/tests/test_cases/expected_kdl/_underscore_in_exponent.kdl b/tests/test_cases/expected_kdl/_underscore_in_exponent.kdl deleted file mode 100644 index d539203..0000000 --- a/tests/test_cases/expected_kdl/_underscore_in_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1e-100 diff --git a/tests/test_cases/expected_kdl/all_escapes.kdl b/tests/test_cases/expected_kdl/all_escapes.kdl index c25f434..de0d0a0 100644 --- a/tests/test_cases/expected_kdl/all_escapes.kdl +++ b/tests/test_cases/expected_kdl/all_escapes.kdl @@ -1 +1 @@ -node "\"\\/\b\f\n\r\t" +node "\"\\\b\f\n\r\t " diff --git a/tests/test_cases/expected_kdl/all_node_fields.kdl b/tests/test_cases/expected_kdl/all_node_fields.kdl index fc8a9e4..9f4ceb5 100644 --- a/tests/test_cases/expected_kdl/all_node_fields.kdl +++ b/tests/test_cases/expected_kdl/all_node_fields.kdl @@ -1,3 +1,3 @@ -node "arg" prop="val" { +node arg prop=val { inner_node } diff --git a/tests/test_cases/expected_kdl/arg_and_prop_same_name.kdl b/tests/test_cases/expected_kdl/arg_and_prop_same_name.kdl index 27d9739..ee5ace5 100644 --- a/tests/test_cases/expected_kdl/arg_and_prop_same_name.kdl +++ b/tests/test_cases/expected_kdl/arg_and_prop_same_name.kdl @@ -1 +1 @@ -node "arg" arg="val" +node arg arg=val diff --git a/tests/test_cases/expected_kdl/arg_bare.kdl b/tests/test_cases/expected_kdl/arg_bare.kdl new file mode 100644 index 0000000..2fa9785 --- /dev/null +++ b/tests/test_cases/expected_kdl/arg_bare.kdl @@ -0,0 +1 @@ +node a diff --git a/tests/test_cases/expected_kdl/arg_false_type.kdl b/tests/test_cases/expected_kdl/arg_false_type.kdl index 895945d..92003d9 100644 --- a/tests/test_cases/expected_kdl/arg_false_type.kdl +++ b/tests/test_cases/expected_kdl/arg_false_type.kdl @@ -1 +1 @@ -node (type)false +node (type)#false diff --git a/tests/test_cases/expected_kdl/arg_null_type.kdl b/tests/test_cases/expected_kdl/arg_null_type.kdl index 476c5cd..cd66101 100644 --- a/tests/test_cases/expected_kdl/arg_null_type.kdl +++ b/tests/test_cases/expected_kdl/arg_null_type.kdl @@ -1 +1 @@ -node (type)null +node (type)#null diff --git a/tests/test_cases/expected_kdl/arg_raw_string_type.kdl b/tests/test_cases/expected_kdl/arg_raw_string_type.kdl index 2808d53..a4859b6 100644 --- a/tests/test_cases/expected_kdl/arg_raw_string_type.kdl +++ b/tests/test_cases/expected_kdl/arg_raw_string_type.kdl @@ -1 +1 @@ -node (type)"str" +node (type)str diff --git a/tests/test_cases/expected_kdl/arg_string_type.kdl b/tests/test_cases/expected_kdl/arg_string_type.kdl index 2808d53..a4859b6 100644 --- a/tests/test_cases/expected_kdl/arg_string_type.kdl +++ b/tests/test_cases/expected_kdl/arg_string_type.kdl @@ -1 +1 @@ -node (type)"str" +node (type)str diff --git a/tests/test_cases/expected_kdl/arg_true_type.kdl b/tests/test_cases/expected_kdl/arg_true_type.kdl index 6d1f9bc..20243a3 100644 --- a/tests/test_cases/expected_kdl/arg_true_type.kdl +++ b/tests/test_cases/expected_kdl/arg_true_type.kdl @@ -1 +1 @@ -node (type)true +node (type)#true diff --git a/tests/test_cases/expected_kdl/arg_type.kdl b/tests/test_cases/expected_kdl/arg_type.kdl index a0b84cf..79a093d 100644 --- a/tests/test_cases/expected_kdl/arg_type.kdl +++ b/tests/test_cases/expected_kdl/arg_type.kdl @@ -1 +1 @@ -node (type)"arg" +node (type)arg diff --git a/tests/test_cases/expected_kdl/bare_emoji.kdl b/tests/test_cases/expected_kdl/bare_emoji.kdl index 60707c8..c67d0b9 100644 --- a/tests/test_cases/expected_kdl/bare_emoji.kdl +++ b/tests/test_cases/expected_kdl/bare_emoji.kdl @@ -1 +1 @@ -😁 "happy!" +😁 happy! diff --git a/tests/test_cases/expected_kdl/bare_ident_dot.kdl b/tests/test_cases/expected_kdl/bare_ident_dot.kdl new file mode 100644 index 0000000..4ea1fa6 --- /dev/null +++ b/tests/test_cases/expected_kdl/bare_ident_dot.kdl @@ -0,0 +1 @@ +node . diff --git a/tests/test_cases/expected_kdl/bare_ident_sign.kdl b/tests/test_cases/expected_kdl/bare_ident_sign.kdl new file mode 100644 index 0000000..34594d7 --- /dev/null +++ b/tests/test_cases/expected_kdl/bare_ident_sign.kdl @@ -0,0 +1 @@ +node + diff --git a/tests/test_cases/expected_kdl/bare_ident_sign_dot.kdl b/tests/test_cases/expected_kdl/bare_ident_sign_dot.kdl new file mode 100644 index 0000000..a37a5c3 --- /dev/null +++ b/tests/test_cases/expected_kdl/bare_ident_sign_dot.kdl @@ -0,0 +1 @@ +node +. diff --git a/tests/test_cases/expected_kdl/blank_prop_type.kdl b/tests/test_cases/expected_kdl/blank_prop_type.kdl index c7b0e31..e00c6d2 100644 --- a/tests/test_cases/expected_kdl/blank_prop_type.kdl +++ b/tests/test_cases/expected_kdl/blank_prop_type.kdl @@ -1 +1 @@ -node key=("")true +node key=("")#true diff --git a/tests/test_cases/expected_kdl/block_comment.kdl b/tests/test_cases/expected_kdl/block_comment.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/block_comment.kdl +++ b/tests/test_cases/expected_kdl/block_comment.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/block_comment_after_node.kdl b/tests/test_cases/expected_kdl/block_comment_after_node.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/block_comment_after_node.kdl +++ b/tests/test_cases/expected_kdl/block_comment_after_node.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/bom_initial.kdl b/tests/test_cases/expected_kdl/bom_initial.kdl new file mode 100644 index 0000000..1b3db2c --- /dev/null +++ b/tests/test_cases/expected_kdl/bom_initial.kdl @@ -0,0 +1 @@ +node arg diff --git a/tests/test_cases/expected_kdl/boolean_arg.kdl b/tests/test_cases/expected_kdl/boolean_arg.kdl index 9c7928e..e0cdf1a 100644 --- a/tests/test_cases/expected_kdl/boolean_arg.kdl +++ b/tests/test_cases/expected_kdl/boolean_arg.kdl @@ -1 +1 @@ -node false true +node #false #true diff --git a/tests/test_cases/expected_kdl/boolean_prop.kdl b/tests/test_cases/expected_kdl/boolean_prop.kdl index 712b60b..f89da9b 100644 --- a/tests/test_cases/expected_kdl/boolean_prop.kdl +++ b/tests/test_cases/expected_kdl/boolean_prop.kdl @@ -1 +1 @@ -node prop1=true prop2=false +node prop1=#true prop2=#false diff --git a/tests/test_cases/expected_kdl/chevrons_in_bare_id.kdl b/tests/test_cases/expected_kdl/chevrons_in_bare_id.kdl new file mode 100644 index 0000000..58b2436 --- /dev/null +++ b/tests/test_cases/expected_kdl/chevrons_in_bare_id.kdl @@ -0,0 +1 @@ +foo123foo weeee diff --git a/tests/test_cases/expected_kdl/comma_in_bare_id.kdl b/tests/test_cases/expected_kdl/comma_in_bare_id.kdl new file mode 100644 index 0000000..86c78fd --- /dev/null +++ b/tests/test_cases/expected_kdl/comma_in_bare_id.kdl @@ -0,0 +1 @@ +foo123,bar weeee diff --git a/tests/test_cases/expected_kdl/comment_after_arg_type.kdl b/tests/test_cases/expected_kdl/comment_after_arg_type.kdl new file mode 100644 index 0000000..51dcb98 --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_after_arg_type.kdl @@ -0,0 +1 @@ +node (type)10 diff --git a/tests/test_cases/expected_kdl/comment_after_node_type.kdl b/tests/test_cases/expected_kdl/comment_after_node_type.kdl new file mode 100644 index 0000000..c790643 --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_after_node_type.kdl @@ -0,0 +1 @@ +(type)node diff --git a/tests/test_cases/expected_kdl/comment_after_prop_type.kdl b/tests/test_cases/expected_kdl/comment_after_prop_type.kdl new file mode 100644 index 0000000..843551b --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_after_prop_type.kdl @@ -0,0 +1 @@ +node key=(type)10 diff --git a/tests/test_cases/expected_kdl/comment_and_newline.kdl b/tests/test_cases/expected_kdl/comment_and_newline.kdl new file mode 100644 index 0000000..1c5b5f3 --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_and_newline.kdl @@ -0,0 +1,2 @@ +node1 +node2 diff --git a/tests/test_cases/expected_kdl/comment_in_arg_type.kdl b/tests/test_cases/expected_kdl/comment_in_arg_type.kdl new file mode 100644 index 0000000..51dcb98 --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_in_arg_type.kdl @@ -0,0 +1 @@ +node (type)10 diff --git a/tests/test_cases/expected_kdl/comment_in_node_type.kdl b/tests/test_cases/expected_kdl/comment_in_node_type.kdl new file mode 100644 index 0000000..c790643 --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_in_node_type.kdl @@ -0,0 +1 @@ +(type)node diff --git a/tests/test_cases/expected_kdl/comment_in_prop_type.kdl b/tests/test_cases/expected_kdl/comment_in_prop_type.kdl new file mode 100644 index 0000000..843551b --- /dev/null +++ b/tests/test_cases/expected_kdl/comment_in_prop_type.kdl @@ -0,0 +1 @@ +node key=(type)10 diff --git a/tests/test_cases/expected_kdl/commented_arg.kdl b/tests/test_cases/expected_kdl/commented_arg.kdl index 226fd56..2e98005 100644 --- a/tests/test_cases/expected_kdl/commented_arg.kdl +++ b/tests/test_cases/expected_kdl/commented_arg.kdl @@ -1 +1 @@ -node "arg2" +node arg2 diff --git a/tests/test_cases/expected_kdl/commented_child.kdl b/tests/test_cases/expected_kdl/commented_child.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/commented_child.kdl +++ b/tests/test_cases/expected_kdl/commented_child.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/commented_prop.kdl b/tests/test_cases/expected_kdl/commented_prop.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/commented_prop.kdl +++ b/tests/test_cases/expected_kdl/commented_prop.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/dash_dash.kdl b/tests/test_cases/expected_kdl/dash_dash.kdl new file mode 100644 index 0000000..9f6111a --- /dev/null +++ b/tests/test_cases/expected_kdl/dash_dash.kdl @@ -0,0 +1 @@ +node -- diff --git a/tests/test_cases/expected_kdl/emoji.kdl b/tests/test_cases/expected_kdl/emoji.kdl index 3ed56e2..88df78a 100644 --- a/tests/test_cases/expected_kdl/emoji.kdl +++ b/tests/test_cases/expected_kdl/emoji.kdl @@ -1 +1 @@ -node "😀" +node 😀 diff --git a/tests/test_cases/expected_kdl/empty_line_comment.kdl b/tests/test_cases/expected_kdl/empty_line_comment.kdl new file mode 100644 index 0000000..64f5a0a --- /dev/null +++ b/tests/test_cases/expected_kdl/empty_line_comment.kdl @@ -0,0 +1 @@ +node diff --git a/tests/test_cases/expected_kdl/empty_quoted_node_id.kdl b/tests/test_cases/expected_kdl/empty_quoted_node_id.kdl index ebfa893..94694bc 100644 --- a/tests/test_cases/expected_kdl/empty_quoted_node_id.kdl +++ b/tests/test_cases/expected_kdl/empty_quoted_node_id.kdl @@ -1 +1 @@ -"" "arg" +"" arg diff --git a/tests/test_cases/expected_kdl/empty_quoted_prop_key.kdl b/tests/test_cases/expected_kdl/empty_quoted_prop_key.kdl index e6e1310..e541793 100644 --- a/tests/test_cases/expected_kdl/empty_quoted_prop_key.kdl +++ b/tests/test_cases/expected_kdl/empty_quoted_prop_key.kdl @@ -1 +1 @@ -node ""="empty" +node ""=empty diff --git a/tests/test_cases/expected_kdl/eof_after_escape.kdl b/tests/test_cases/expected_kdl/eof_after_escape.kdl new file mode 100644 index 0000000..64f5a0a --- /dev/null +++ b/tests/test_cases/expected_kdl/eof_after_escape.kdl @@ -0,0 +1 @@ +node diff --git a/tests/test_cases/expected_kdl/escaped_whitespace.kdl b/tests/test_cases/expected_kdl/escaped_whitespace.kdl new file mode 100644 index 0000000..45dd408 --- /dev/null +++ b/tests/test_cases/expected_kdl/escaped_whitespace.kdl @@ -0,0 +1 @@ +node "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" diff --git a/tests/test_cases/expected_kdl/escline.kdl b/tests/test_cases/expected_kdl/escline.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/escline.kdl +++ b/tests/test_cases/expected_kdl/escline.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/escline_line_comment.kdl b/tests/test_cases/expected_kdl/escline_line_comment.kdl index 8a5dc33..4d38bee 100644 --- a/tests/test_cases/expected_kdl/escline_line_comment.kdl +++ b/tests/test_cases/expected_kdl/escline_line_comment.kdl @@ -1 +1 @@ -node "arg" "arg2\n" +node arg arg2 diff --git a/tests/test_cases/expected_kdl/floating_point_keywords.kdl b/tests/test_cases/expected_kdl/floating_point_keywords.kdl new file mode 100644 index 0000000..973a259 --- /dev/null +++ b/tests/test_cases/expected_kdl/floating_point_keywords.kdl @@ -0,0 +1 @@ +floats #inf #-inf #nan diff --git a/tests/test_cases/expected_kdl/hex.kdl b/tests/test_cases/expected_kdl/hex.kdl index 10e54fa..bcbc7ff 100644 --- a/tests/test_cases/expected_kdl/hex.kdl +++ b/tests/test_cases/expected_kdl/hex.kdl @@ -1 +1 @@ -node 1311768467294899695 +node 12379813812177893520 diff --git a/tests/test_cases/expected_kdl/hex_int.kdl b/tests/test_cases/expected_kdl/hex_int.kdl index 10e54fa..f8dcee1 100644 --- a/tests/test_cases/expected_kdl/hex_int.kdl +++ b/tests/test_cases/expected_kdl/hex_int.kdl @@ -1 +1 @@ -node 1311768467294899695 +node 207698809136909011942886895 diff --git a/tests/test_cases/expected_kdl/initial_slashdash.kdl b/tests/test_cases/expected_kdl/initial_slashdash.kdl new file mode 100644 index 0000000..d74a990 --- /dev/null +++ b/tests/test_cases/expected_kdl/initial_slashdash.kdl @@ -0,0 +1 @@ +another-node diff --git a/tests/test_cases/expected_kdl/multiline_comment.kdl b/tests/test_cases/expected_kdl/multiline_comment.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/multiline_comment.kdl +++ b/tests/test_cases/expected_kdl/multiline_comment.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/multiline_nodes.kdl b/tests/test_cases/expected_kdl/multiline_nodes.kdl index bec6d05..7c27fb0 100644 --- a/tests/test_cases/expected_kdl/multiline_nodes.kdl +++ b/tests/test_cases/expected_kdl/multiline_nodes.kdl @@ -1 +1 @@ -node "arg1" "arg2" +node arg1 arg2 diff --git a/tests/test_cases/expected_kdl/multiline_raw_string.kdl b/tests/test_cases/expected_kdl/multiline_raw_string.kdl new file mode 100644 index 0000000..3c31c47 --- /dev/null +++ b/tests/test_cases/expected_kdl/multiline_raw_string.kdl @@ -0,0 +1 @@ +node "hey\neveryone\nhow goes?" diff --git a/tests/test_cases/expected_kdl/multiline_raw_string_indented.kdl b/tests/test_cases/expected_kdl/multiline_raw_string_indented.kdl new file mode 100644 index 0000000..f693b84 --- /dev/null +++ b/tests/test_cases/expected_kdl/multiline_raw_string_indented.kdl @@ -0,0 +1 @@ +node " hey\n everyone\n how goes?" diff --git a/tests/test_cases/expected_kdl/multiline_string.kdl b/tests/test_cases/expected_kdl/multiline_string.kdl index 021493e..3c31c47 100644 --- a/tests/test_cases/expected_kdl/multiline_string.kdl +++ b/tests/test_cases/expected_kdl/multiline_string.kdl @@ -1 +1 @@ -node " hey\neveryone\nhow goes?\n" +node "hey\neveryone\nhow goes?" diff --git a/tests/test_cases/expected_kdl/multiline_string_indented.kdl b/tests/test_cases/expected_kdl/multiline_string_indented.kdl new file mode 100644 index 0000000..f693b84 --- /dev/null +++ b/tests/test_cases/expected_kdl/multiline_string_indented.kdl @@ -0,0 +1 @@ +node " hey\n everyone\n how goes?" diff --git a/tests/test_cases/expected_kdl/negative_exponent.kdl b/tests/test_cases/expected_kdl/negative_exponent.kdl new file mode 100644 index 0000000..aae8926 --- /dev/null +++ b/tests/test_cases/expected_kdl/negative_exponent.kdl @@ -0,0 +1 @@ +node 1.0E-10 diff --git a/tests/test_cases/expected_kdl/nested_block_comment.kdl b/tests/test_cases/expected_kdl/nested_block_comment.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/nested_block_comment.kdl +++ b/tests/test_cases/expected_kdl/nested_block_comment.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/nested_comments.kdl b/tests/test_cases/expected_kdl/nested_comments.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/nested_comments.kdl +++ b/tests/test_cases/expected_kdl/nested_comments.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/nested_multiline_block_comment.kdl b/tests/test_cases/expected_kdl/nested_multiline_block_comment.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/nested_multiline_block_comment.kdl +++ b/tests/test_cases/expected_kdl/nested_multiline_block_comment.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/newlines_in_block_comment.kdl b/tests/test_cases/expected_kdl/newlines_in_block_comment.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/newlines_in_block_comment.kdl +++ b/tests/test_cases/expected_kdl/newlines_in_block_comment.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/no_decimal_exponent.kdl b/tests/test_cases/expected_kdl/no_decimal_exponent.kdl index 0592b9c..ddf1aa6 100644 --- a/tests/test_cases/expected_kdl/no_decimal_exponent.kdl +++ b/tests/test_cases/expected_kdl/no_decimal_exponent.kdl @@ -1 +1 @@ -node 10000000000.0 +node 1E+10 diff --git a/tests/test_cases/expected_kdl/node_false.kdl b/tests/test_cases/expected_kdl/node_false.kdl index ef60c44..3bab782 100644 --- a/tests/test_cases/expected_kdl/node_false.kdl +++ b/tests/test_cases/expected_kdl/node_false.kdl @@ -1 +1 @@ -node false +node #false diff --git a/tests/test_cases/expected_kdl/node_true.kdl b/tests/test_cases/expected_kdl/node_true.kdl index 4b02a06..de00dcd 100644 --- a/tests/test_cases/expected_kdl/node_true.kdl +++ b/tests/test_cases/expected_kdl/node_true.kdl @@ -1 +1 @@ -node true +node #true diff --git a/tests/test_cases/expected_kdl/null_arg.kdl b/tests/test_cases/expected_kdl/null_arg.kdl index c0e6cb5..bed8dbf 100644 --- a/tests/test_cases/expected_kdl/null_arg.kdl +++ b/tests/test_cases/expected_kdl/null_arg.kdl @@ -1 +1 @@ -node null +node #null diff --git a/tests/test_cases/expected_kdl/null_prop.kdl b/tests/test_cases/expected_kdl/null_prop.kdl index 85ef005..c463e98 100644 --- a/tests/test_cases/expected_kdl/null_prop.kdl +++ b/tests/test_cases/expected_kdl/null_prop.kdl @@ -1 +1 @@ -node prop=null +node prop=#null diff --git a/tests/test_cases/expected_kdl/optional_child_semicolon.kdl b/tests/test_cases/expected_kdl/optional_child_semicolon.kdl new file mode 100644 index 0000000..25eaa7d --- /dev/null +++ b/tests/test_cases/expected_kdl/optional_child_semicolon.kdl @@ -0,0 +1,5 @@ +node { + foo + bar + baz +} diff --git a/tests/test_cases/expected_kdl/parse_all_arg_types.kdl b/tests/test_cases/expected_kdl/parse_all_arg_types.kdl new file mode 100644 index 0000000..773df95 --- /dev/null +++ b/tests/test_cases/expected_kdl/parse_all_arg_types.kdl @@ -0,0 +1 @@ +node 1 1.0 1.0E+10 1.0E-10 1 7 2 arg arg "arg\\" #true #false #null diff --git a/tests/test_cases/expected_kdl/positive_exponent.kdl b/tests/test_cases/expected_kdl/positive_exponent.kdl new file mode 100644 index 0000000..46dc2b9 --- /dev/null +++ b/tests/test_cases/expected_kdl/positive_exponent.kdl @@ -0,0 +1 @@ +node 1.0E+10 diff --git a/tests/test_cases/expected_kdl/prop_false_type.kdl b/tests/test_cases/expected_kdl/prop_false_type.kdl index 3377323..eb544ef 100644 --- a/tests/test_cases/expected_kdl/prop_false_type.kdl +++ b/tests/test_cases/expected_kdl/prop_false_type.kdl @@ -1 +1 @@ -node key=(type)false +node key=(type)#false diff --git a/tests/test_cases/expected_kdl/prop_float_type.kdl b/tests/test_cases/expected_kdl/prop_float_type.kdl index 166c78b..79243ec 100644 --- a/tests/test_cases/expected_kdl/prop_float_type.kdl +++ b/tests/test_cases/expected_kdl/prop_float_type.kdl @@ -1 +1 @@ -node key=(type)25000000000.0 +node key=(type)2.5E+10 diff --git a/tests/test_cases/expected_kdl/prop_identifier_type.kdl b/tests/test_cases/expected_kdl/prop_identifier_type.kdl new file mode 100644 index 0000000..7df052b --- /dev/null +++ b/tests/test_cases/expected_kdl/prop_identifier_type.kdl @@ -0,0 +1 @@ +node key=(type)str diff --git a/tests/test_cases/expected_kdl/prop_null_type.kdl b/tests/test_cases/expected_kdl/prop_null_type.kdl index bafaddc..1c25b6f 100644 --- a/tests/test_cases/expected_kdl/prop_null_type.kdl +++ b/tests/test_cases/expected_kdl/prop_null_type.kdl @@ -1 +1 @@ -node key=(type)null +node key=(type)#null diff --git a/tests/test_cases/expected_kdl/prop_raw_string_type.kdl b/tests/test_cases/expected_kdl/prop_raw_string_type.kdl index 50e2d2c..7df052b 100644 --- a/tests/test_cases/expected_kdl/prop_raw_string_type.kdl +++ b/tests/test_cases/expected_kdl/prop_raw_string_type.kdl @@ -1 +1 @@ -node key=(type)"str" +node key=(type)str diff --git a/tests/test_cases/expected_kdl/prop_string_type.kdl b/tests/test_cases/expected_kdl/prop_string_type.kdl index 50e2d2c..7df052b 100644 --- a/tests/test_cases/expected_kdl/prop_string_type.kdl +++ b/tests/test_cases/expected_kdl/prop_string_type.kdl @@ -1 +1 @@ -node key=(type)"str" +node key=(type)str diff --git a/tests/test_cases/expected_kdl/prop_true_type.kdl b/tests/test_cases/expected_kdl/prop_true_type.kdl index c4eebb6..01404b8 100644 --- a/tests/test_cases/expected_kdl/prop_true_type.kdl +++ b/tests/test_cases/expected_kdl/prop_true_type.kdl @@ -1 +1 @@ -node key=(type)true +node key=(type)#true diff --git a/tests/test_cases/expected_kdl/prop_type.kdl b/tests/test_cases/expected_kdl/prop_type.kdl index c4eebb6..01404b8 100644 --- a/tests/test_cases/expected_kdl/prop_type.kdl +++ b/tests/test_cases/expected_kdl/prop_type.kdl @@ -1 +1 @@ -node key=(type)true +node key=(type)#true diff --git a/tests/test_cases/expected_kdl/question_mark_before_number.kdl b/tests/test_cases/expected_kdl/question_mark_before_number.kdl new file mode 100644 index 0000000..7745a9e --- /dev/null +++ b/tests/test_cases/expected_kdl/question_mark_before_number.kdl @@ -0,0 +1 @@ +node ?15 diff --git a/tests/test_cases/expected_kdl/quoted_prop_name.kdl b/tests/test_cases/expected_kdl/quoted_prop_name.kdl index 170a05a..8ee5e08 100644 --- a/tests/test_cases/expected_kdl/quoted_prop_name.kdl +++ b/tests/test_cases/expected_kdl/quoted_prop_name.kdl @@ -1 +1 @@ -node "0prop"="val" +node "0prop"=val diff --git a/tests/test_cases/expected_kdl/quoted_prop_type.kdl b/tests/test_cases/expected_kdl/quoted_prop_type.kdl index 0e2b920..beca5f2 100644 --- a/tests/test_cases/expected_kdl/quoted_prop_type.kdl +++ b/tests/test_cases/expected_kdl/quoted_prop_type.kdl @@ -1 +1 @@ -node key=("type/")true +node key=("type/")#true diff --git a/tests/test_cases/expected_kdl/r_node.kdl b/tests/test_cases/expected_kdl/r_node.kdl index 4a98807..282cc04 100644 --- a/tests/test_cases/expected_kdl/r_node.kdl +++ b/tests/test_cases/expected_kdl/r_node.kdl @@ -1 +1 @@ -r "arg" +r arg diff --git a/tests/test_cases/expected_kdl/raw_arg_type.kdl b/tests/test_cases/expected_kdl/raw_arg_type.kdl index 6d1f9bc..20243a3 100644 --- a/tests/test_cases/expected_kdl/raw_arg_type.kdl +++ b/tests/test_cases/expected_kdl/raw_arg_type.kdl @@ -1 +1 @@ -node (type)true +node (type)#true diff --git a/tests/test_cases/expected_kdl/raw_prop_type.kdl b/tests/test_cases/expected_kdl/raw_prop_type.kdl index c4eebb6..01404b8 100644 --- a/tests/test_cases/expected_kdl/raw_prop_type.kdl +++ b/tests/test_cases/expected_kdl/raw_prop_type.kdl @@ -1 +1 @@ -node key=(type)true +node key=(type)#true diff --git a/tests/test_cases/expected_kdl/raw_string_arg.kdl b/tests/test_cases/expected_kdl/raw_string_arg.kdl index a909993..24f8d65 100644 --- a/tests/test_cases/expected_kdl/raw_string_arg.kdl +++ b/tests/test_cases/expected_kdl/raw_string_arg.kdl @@ -1,3 +1,2 @@ -node_1 "arg\\n" -node_2 "\"arg\\n\"and stuff" -node_3 "#\"arg\\n\"#and stuff" +node_1 "\"arg\\n\"and #stuff" +node_2 "#\"arg\\n\"#and #stuff" diff --git a/tests/test_cases/expected_kdl/raw_string_newline.kdl b/tests/test_cases/expected_kdl/raw_string_newline.kdl index d738029..fd38cb0 100644 --- a/tests/test_cases/expected_kdl/raw_string_newline.kdl +++ b/tests/test_cases/expected_kdl/raw_string_newline.kdl @@ -1 +1 @@ -node "\nhello\nworld\n" +node "hello\nworld" diff --git a/tests/test_cases/expected_kdl/raw_string_prop.kdl b/tests/test_cases/expected_kdl/raw_string_prop.kdl index 0762d88..6a1b5ee 100644 --- a/tests/test_cases/expected_kdl/raw_string_prop.kdl +++ b/tests/test_cases/expected_kdl/raw_string_prop.kdl @@ -1,3 +1,2 @@ -node_1 prop="arg\\n" -node_2 prop="\"arg\"\\n" -node_3 prop="#\"arg\"#\\n" +node_1 prop="\"arg#\"\\n" +node_2 prop="#\"arg#\"#\\n" diff --git a/tests/test_cases/expected_kdl/repeated_arg.kdl b/tests/test_cases/expected_kdl/repeated_arg.kdl index 849fee0..6525757 100644 --- a/tests/test_cases/expected_kdl/repeated_arg.kdl +++ b/tests/test_cases/expected_kdl/repeated_arg.kdl @@ -1 +1 @@ -node "arg" "arg" +node arg arg diff --git a/tests/test_cases/expected_kdl/same_args.kdl b/tests/test_cases/expected_kdl/same_args.kdl deleted file mode 100644 index 6b8ae13..0000000 --- a/tests/test_cases/expected_kdl/same_args.kdl +++ /dev/null @@ -1 +0,0 @@ -node "whee" "whee" diff --git a/tests/test_cases/expected_kdl/_sci_notation_large.kdl b/tests/test_cases/expected_kdl/sci_notation_large.kdl similarity index 100% rename from tests/test_cases/expected_kdl/_sci_notation_large.kdl rename to tests/test_cases/expected_kdl/sci_notation_large.kdl diff --git a/tests/test_cases/expected_kdl/_sci_notation_small.kdl b/tests/test_cases/expected_kdl/sci_notation_small.kdl similarity index 100% rename from tests/test_cases/expected_kdl/_sci_notation_small.kdl rename to tests/test_cases/expected_kdl/sci_notation_small.kdl diff --git a/tests/test_cases/expected_kdl/single_arg.kdl b/tests/test_cases/expected_kdl/single_arg.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/single_arg.kdl +++ b/tests/test_cases/expected_kdl/single_arg.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/single_prop.kdl b/tests/test_cases/expected_kdl/single_prop.kdl index a0d0062..282aa3b 100644 --- a/tests/test_cases/expected_kdl/single_prop.kdl +++ b/tests/test_cases/expected_kdl/single_prop.kdl @@ -1 +1 @@ -node prop="val" +node prop=val diff --git a/tests/test_cases/expected_kdl/slashdash_arg_after_newline_esc.kdl b/tests/test_cases/expected_kdl/slashdash_arg_after_newline_esc.kdl index 226fd56..2e98005 100644 --- a/tests/test_cases/expected_kdl/slashdash_arg_after_newline_esc.kdl +++ b/tests/test_cases/expected_kdl/slashdash_arg_after_newline_esc.kdl @@ -1 +1 @@ -node "arg2" +node arg2 diff --git a/tests/test_cases/expected_kdl/slashdash_prop.kdl b/tests/test_cases/expected_kdl/slashdash_prop.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/slashdash_prop.kdl +++ b/tests/test_cases/expected_kdl/slashdash_prop.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/slashdash_repeated_prop.kdl b/tests/test_cases/expected_kdl/slashdash_repeated_prop.kdl index 82c6972..dce25a7 100644 --- a/tests/test_cases/expected_kdl/slashdash_repeated_prop.kdl +++ b/tests/test_cases/expected_kdl/slashdash_repeated_prop.kdl @@ -1 +1 @@ -node arg="correct" +node arg=correct diff --git a/tests/test_cases/expected_kdl/space_after_arg_type.kdl b/tests/test_cases/expected_kdl/space_after_arg_type.kdl new file mode 100644 index 0000000..51dcb98 --- /dev/null +++ b/tests/test_cases/expected_kdl/space_after_arg_type.kdl @@ -0,0 +1 @@ +node (type)10 diff --git a/tests/test_cases/expected_kdl/space_after_node_type.kdl b/tests/test_cases/expected_kdl/space_after_node_type.kdl new file mode 100644 index 0000000..c790643 --- /dev/null +++ b/tests/test_cases/expected_kdl/space_after_node_type.kdl @@ -0,0 +1 @@ +(type)node diff --git a/tests/test_cases/expected_kdl/space_after_prop_type.kdl b/tests/test_cases/expected_kdl/space_after_prop_type.kdl new file mode 100644 index 0000000..eb544ef --- /dev/null +++ b/tests/test_cases/expected_kdl/space_after_prop_type.kdl @@ -0,0 +1 @@ +node key=(type)#false diff --git a/tests/test_cases/expected_kdl/space_around_prop_marker.kdl b/tests/test_cases/expected_kdl/space_around_prop_marker.kdl new file mode 100644 index 0000000..30a026f --- /dev/null +++ b/tests/test_cases/expected_kdl/space_around_prop_marker.kdl @@ -0,0 +1 @@ +node foo=bar diff --git a/tests/test_cases/expected_kdl/space_in_arg_type.kdl b/tests/test_cases/expected_kdl/space_in_arg_type.kdl new file mode 100644 index 0000000..92003d9 --- /dev/null +++ b/tests/test_cases/expected_kdl/space_in_arg_type.kdl @@ -0,0 +1 @@ +node (type)#false diff --git a/tests/test_cases/expected_kdl/space_in_node_type.kdl b/tests/test_cases/expected_kdl/space_in_node_type.kdl new file mode 100644 index 0000000..c790643 --- /dev/null +++ b/tests/test_cases/expected_kdl/space_in_node_type.kdl @@ -0,0 +1 @@ +(type)node diff --git a/tests/test_cases/expected_kdl/space_in_prop_type.kdl b/tests/test_cases/expected_kdl/space_in_prop_type.kdl new file mode 100644 index 0000000..eb544ef --- /dev/null +++ b/tests/test_cases/expected_kdl/space_in_prop_type.kdl @@ -0,0 +1 @@ +node key=(type)#false diff --git a/tests/test_cases/expected_kdl/string_arg.kdl b/tests/test_cases/expected_kdl/string_arg.kdl index b3a0426..1b3db2c 100644 --- a/tests/test_cases/expected_kdl/string_arg.kdl +++ b/tests/test_cases/expected_kdl/string_arg.kdl @@ -1 +1 @@ -node "arg" +node arg diff --git a/tests/test_cases/expected_kdl/string_escaped_literal_whitespace.kdl b/tests/test_cases/expected_kdl/string_escaped_literal_whitespace.kdl new file mode 100644 index 0000000..3169ad9 --- /dev/null +++ b/tests/test_cases/expected_kdl/string_escaped_literal_whitespace.kdl @@ -0,0 +1 @@ +node "Hello World Stuff" diff --git a/tests/test_cases/expected_kdl/string_prop.kdl b/tests/test_cases/expected_kdl/string_prop.kdl index a0d0062..282aa3b 100644 --- a/tests/test_cases/expected_kdl/string_prop.kdl +++ b/tests/test_cases/expected_kdl/string_prop.kdl @@ -1 +1 @@ -node prop="val" +node prop=val diff --git a/tests/test_cases/expected_kdl/underscore_before_number.kdl b/tests/test_cases/expected_kdl/underscore_before_number.kdl new file mode 100644 index 0000000..788656b --- /dev/null +++ b/tests/test_cases/expected_kdl/underscore_before_number.kdl @@ -0,0 +1 @@ +node _15 diff --git a/tests/test_cases/expected_kdl/underscore_in_exponent.kdl b/tests/test_cases/expected_kdl/underscore_in_exponent.kdl new file mode 100644 index 0000000..a5b975d --- /dev/null +++ b/tests/test_cases/expected_kdl/underscore_in_exponent.kdl @@ -0,0 +1 @@ +node 1.0E-100 diff --git a/tests/test_cases/expected_kdl/unicode_equals_signs.kdl b/tests/test_cases/expected_kdl/unicode_equals_signs.kdl new file mode 100644 index 0000000..4ab6443 --- /dev/null +++ b/tests/test_cases/expected_kdl/unicode_equals_signs.kdl @@ -0,0 +1 @@ +node p1=val1 p2=val2 p3=val3 diff --git a/tests/test_cases/expected_kdl/unusual_bare_id_chars_in_quoted_id.kdl b/tests/test_cases/expected_kdl/unusual_bare_id_chars_in_quoted_id.kdl index d2dcd19..8321632 100644 --- a/tests/test_cases/expected_kdl/unusual_bare_id_chars_in_quoted_id.kdl +++ b/tests/test_cases/expected_kdl/unusual_bare_id_chars_in_quoted_id.kdl @@ -1 +1 @@ -foo123~!@#$%^&*.:'|?+ "weeee" +foo123~!@$%^&*.:'|?+<>, weeee diff --git a/tests/test_cases/expected_kdl/unusual_chars_in_bare_id.kdl b/tests/test_cases/expected_kdl/unusual_chars_in_bare_id.kdl index d2dcd19..8321632 100644 --- a/tests/test_cases/expected_kdl/unusual_chars_in_bare_id.kdl +++ b/tests/test_cases/expected_kdl/unusual_chars_in_bare_id.kdl @@ -1 +1 @@ -foo123~!@#$%^&*.:'|?+ "weeee" +foo123~!@$%^&*.:'|?+<>, weeee diff --git a/tests/test_cases/expected_kdl/vertical_tab_whitespace.kdl b/tests/test_cases/expected_kdl/vertical_tab_whitespace.kdl new file mode 100644 index 0000000..1b3db2c --- /dev/null +++ b/tests/test_cases/expected_kdl/vertical_tab_whitespace.kdl @@ -0,0 +1 @@ +node arg diff --git a/tests/test_cases/input/all_escapes.kdl b/tests/test_cases/input/all_escapes.kdl index 5bb1dc3..5c49748 100644 --- a/tests/test_cases/input/all_escapes.kdl +++ b/tests/test_cases/input/all_escapes.kdl @@ -1 +1 @@ -node "\"\\\/\b\f\n\r\t" +node "\"\\\b\f\n\r\t\s" diff --git a/tests/test_cases/input/all_node_fields.kdl b/tests/test_cases/input/all_node_fields.kdl index fc8a9e4..9f4ceb5 100644 --- a/tests/test_cases/input/all_node_fields.kdl +++ b/tests/test_cases/input/all_node_fields.kdl @@ -1,3 +1,3 @@ -node "arg" prop="val" { +node arg prop=val { inner_node } diff --git a/tests/test_cases/input/arg_and_prop_same_name.kdl b/tests/test_cases/input/arg_and_prop_same_name.kdl index b830f56..ee5ace5 100644 --- a/tests/test_cases/input/arg_and_prop_same_name.kdl +++ b/tests/test_cases/input/arg_and_prop_same_name.kdl @@ -1 +1 @@ -node "arg" arg="val" \ No newline at end of file +node arg arg=val diff --git a/tests/test_cases/input/arg_bare.kdl b/tests/test_cases/input/arg_bare.kdl new file mode 100644 index 0000000..2fa9785 --- /dev/null +++ b/tests/test_cases/input/arg_bare.kdl @@ -0,0 +1 @@ +node a diff --git a/tests/test_cases/input/arg_false_type.kdl b/tests/test_cases/input/arg_false_type.kdl index 895945d..92003d9 100644 --- a/tests/test_cases/input/arg_false_type.kdl +++ b/tests/test_cases/input/arg_false_type.kdl @@ -1 +1 @@ -node (type)false +node (type)#false diff --git a/tests/test_cases/input/arg_null_type.kdl b/tests/test_cases/input/arg_null_type.kdl index 476c5cd..cd66101 100644 --- a/tests/test_cases/input/arg_null_type.kdl +++ b/tests/test_cases/input/arg_null_type.kdl @@ -1 +1 @@ -node (type)null +node (type)#null diff --git a/tests/test_cases/input/arg_raw_string_type.kdl b/tests/test_cases/input/arg_raw_string_type.kdl index 2808d53..c722312 100644 --- a/tests/test_cases/input/arg_raw_string_type.kdl +++ b/tests/test_cases/input/arg_raw_string_type.kdl @@ -1 +1 @@ -node (type)"str" +node (type)#"str"# diff --git a/tests/test_cases/input/arg_string_type.kdl b/tests/test_cases/input/arg_string_type.kdl index 1a141b2..2808d53 100644 --- a/tests/test_cases/input/arg_string_type.kdl +++ b/tests/test_cases/input/arg_string_type.kdl @@ -1 +1 @@ -node (type)"str" \ No newline at end of file +node (type)"str" diff --git a/tests/test_cases/input/arg_true_type.kdl b/tests/test_cases/input/arg_true_type.kdl index 6d1f9bc..20243a3 100644 --- a/tests/test_cases/input/arg_true_type.kdl +++ b/tests/test_cases/input/arg_true_type.kdl @@ -1 +1 @@ -node (type)true +node (type)#true diff --git a/tests/test_cases/input/arg_type.kdl b/tests/test_cases/input/arg_type.kdl index a0b84cf..79a093d 100644 --- a/tests/test_cases/input/arg_type.kdl +++ b/tests/test_cases/input/arg_type.kdl @@ -1 +1 @@ -node (type)"arg" +node (type)arg diff --git a/tests/test_cases/input/backslash_in_bare_id.kdl b/tests/test_cases/input/backslash_in_bare_id.kdl deleted file mode 100644 index 5615277..0000000 --- a/tests/test_cases/input/backslash_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123\bar "weeee" diff --git a/tests/test_cases/input/bare_arg.kdl b/tests/test_cases/input/bare_arg.kdl deleted file mode 100644 index ec2a21f..0000000 --- a/tests/test_cases/input/bare_arg.kdl +++ /dev/null @@ -1 +0,0 @@ -node a \ No newline at end of file diff --git a/tests/test_cases/input/bare_emoji.kdl b/tests/test_cases/input/bare_emoji.kdl index 60707c8..c67d0b9 100644 --- a/tests/test_cases/input/bare_emoji.kdl +++ b/tests/test_cases/input/bare_emoji.kdl @@ -1 +1 @@ -😁 "happy!" +😁 happy! diff --git a/tests/test_cases/input/bare_ident_dot.kdl b/tests/test_cases/input/bare_ident_dot.kdl new file mode 100644 index 0000000..5c32f67 --- /dev/null +++ b/tests/test_cases/input/bare_ident_dot.kdl @@ -0,0 +1 @@ +node . \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_numeric.kdl b/tests/test_cases/input/bare_ident_numeric.kdl new file mode 100644 index 0000000..053af21 --- /dev/null +++ b/tests/test_cases/input/bare_ident_numeric.kdl @@ -0,0 +1 @@ +node 0n \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_numeric_dot.kdl b/tests/test_cases/input/bare_ident_numeric_dot.kdl new file mode 100644 index 0000000..b97afcf --- /dev/null +++ b/tests/test_cases/input/bare_ident_numeric_dot.kdl @@ -0,0 +1 @@ +node .0n \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_numeric_sign.kdl b/tests/test_cases/input/bare_ident_numeric_sign.kdl new file mode 100644 index 0000000..6cadc35 --- /dev/null +++ b/tests/test_cases/input/bare_ident_numeric_sign.kdl @@ -0,0 +1 @@ +node +0n \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_sign.kdl b/tests/test_cases/input/bare_ident_sign.kdl new file mode 100644 index 0000000..b609706 --- /dev/null +++ b/tests/test_cases/input/bare_ident_sign.kdl @@ -0,0 +1 @@ +node + \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_sign_dot.kdl b/tests/test_cases/input/bare_ident_sign_dot.kdl new file mode 100644 index 0000000..d50adcf --- /dev/null +++ b/tests/test_cases/input/bare_ident_sign_dot.kdl @@ -0,0 +1 @@ +node +. \ No newline at end of file diff --git a/tests/test_cases/input/blank_prop_type.kdl b/tests/test_cases/input/blank_prop_type.kdl index 898f90d..e00c6d2 100644 --- a/tests/test_cases/input/blank_prop_type.kdl +++ b/tests/test_cases/input/blank_prop_type.kdl @@ -1 +1 @@ -node key=("")true \ No newline at end of file +node key=("")#true diff --git a/tests/test_cases/input/block_comment.kdl b/tests/test_cases/input/block_comment.kdl index e6eddb9..f6c39ac 100644 --- a/tests/test_cases/input/block_comment.kdl +++ b/tests/test_cases/input/block_comment.kdl @@ -1 +1 @@ -node /* comment */ "arg" \ No newline at end of file +node /* comment */ arg diff --git a/tests/test_cases/input/block_comment_after_node.kdl b/tests/test_cases/input/block_comment_after_node.kdl index e7777ed..071ff21 100644 --- a/tests/test_cases/input/block_comment_after_node.kdl +++ b/tests/test_cases/input/block_comment_after_node.kdl @@ -1 +1 @@ -node /* hey */ "arg" +node /* hey */ arg diff --git a/tests/test_cases/input/bom_initial.kdl b/tests/test_cases/input/bom_initial.kdl new file mode 100644 index 0000000..e52e8bf --- /dev/null +++ b/tests/test_cases/input/bom_initial.kdl @@ -0,0 +1 @@ +node arg diff --git a/tests/test_cases/input/bom_later.kdl b/tests/test_cases/input/bom_later.kdl new file mode 100644 index 0000000..6aeff8d --- /dev/null +++ b/tests/test_cases/input/bom_later.kdl @@ -0,0 +1 @@ +node arg diff --git a/tests/test_cases/input/boolean_arg.kdl b/tests/test_cases/input/boolean_arg.kdl index f099893..e0cdf1a 100644 --- a/tests/test_cases/input/boolean_arg.kdl +++ b/tests/test_cases/input/boolean_arg.kdl @@ -1 +1 @@ -node false true \ No newline at end of file +node #false #true diff --git a/tests/test_cases/input/boolean_prop.kdl b/tests/test_cases/input/boolean_prop.kdl index 61e3111..f89da9b 100644 --- a/tests/test_cases/input/boolean_prop.kdl +++ b/tests/test_cases/input/boolean_prop.kdl @@ -1 +1 @@ -node prop1=true prop2=false \ No newline at end of file +node prop1=#true prop2=#false diff --git a/tests/test_cases/input/brackets_in_bare_id.kdl b/tests/test_cases/input/brackets_in_bare_id.kdl index b0d39c5..ebb78d2 100644 --- a/tests/test_cases/input/brackets_in_bare_id.kdl +++ b/tests/test_cases/input/brackets_in_bare_id.kdl @@ -1 +1 @@ -foo123{bar}foo "weeee" +foo123{bar}foo weeee diff --git a/tests/test_cases/input/chevrons_in_bare_id.kdl b/tests/test_cases/input/chevrons_in_bare_id.kdl index 4b6610e..58b2436 100644 --- a/tests/test_cases/input/chevrons_in_bare_id.kdl +++ b/tests/test_cases/input/chevrons_in_bare_id.kdl @@ -1 +1 @@ -foo123foo "weeee" +foo123foo weeee diff --git a/tests/test_cases/input/comma_in_bare_id.kdl b/tests/test_cases/input/comma_in_bare_id.kdl index 656df91..86c78fd 100644 --- a/tests/test_cases/input/comma_in_bare_id.kdl +++ b/tests/test_cases/input/comma_in_bare_id.kdl @@ -1 +1 @@ -foo123,bar "weeee" +foo123,bar weeee diff --git a/tests/test_cases/input/comment_after_arg_type.kdl b/tests/test_cases/input/comment_after_arg_type.kdl index f88b7c1..d493f6e 100644 --- a/tests/test_cases/input/comment_after_arg_type.kdl +++ b/tests/test_cases/input/comment_after_arg_type.kdl @@ -1 +1 @@ -node (type)/*huh*/10 +node (type)/*hey*/10 diff --git a/tests/test_cases/input/comment_after_node_type.kdl b/tests/test_cases/input/comment_after_node_type.kdl index 55ab980..a5939b4 100644 --- a/tests/test_cases/input/comment_after_node_type.kdl +++ b/tests/test_cases/input/comment_after_node_type.kdl @@ -1 +1 @@ -(type)/*huh*/node +(type)/*hey*/node diff --git a/tests/test_cases/input/comment_after_prop_type.kdl b/tests/test_cases/input/comment_after_prop_type.kdl index c9b1858..6805673 100644 --- a/tests/test_cases/input/comment_after_prop_type.kdl +++ b/tests/test_cases/input/comment_after_prop_type.kdl @@ -1 +1 @@ -node key=(type)/*huh*/10 +node key=(type)/*hey*/10 diff --git a/tests/test_cases/input/comment_and_newline.kdl b/tests/test_cases/input/comment_and_newline.kdl new file mode 100644 index 0000000..d1bb77f --- /dev/null +++ b/tests/test_cases/input/comment_and_newline.kdl @@ -0,0 +1,2 @@ +node1 // +node2 diff --git a/tests/test_cases/input/comment_in_arg_type.kdl b/tests/test_cases/input/comment_in_arg_type.kdl index 39742ac..1166a43 100644 --- a/tests/test_cases/input/comment_in_arg_type.kdl +++ b/tests/test_cases/input/comment_in_arg_type.kdl @@ -1 +1 @@ -node (type/*huh*/)10 +node (type/*hey*/)10 diff --git a/tests/test_cases/input/comment_in_node_type.kdl b/tests/test_cases/input/comment_in_node_type.kdl index 8cda2e5..7cc9b26 100644 --- a/tests/test_cases/input/comment_in_node_type.kdl +++ b/tests/test_cases/input/comment_in_node_type.kdl @@ -1 +1 @@ -(type/*huh*/)node +(type/*hey*/)node diff --git a/tests/test_cases/input/comment_in_prop_type.kdl b/tests/test_cases/input/comment_in_prop_type.kdl index 10adb3b..0587da9 100644 --- a/tests/test_cases/input/comment_in_prop_type.kdl +++ b/tests/test_cases/input/comment_in_prop_type.kdl @@ -1 +1 @@ -node key=(type/*huh*/)10 +node key=(type/*hey*/)10 diff --git a/tests/test_cases/input/commented_arg.kdl b/tests/test_cases/input/commented_arg.kdl index e389cd2..0e6157f 100644 --- a/tests/test_cases/input/commented_arg.kdl +++ b/tests/test_cases/input/commented_arg.kdl @@ -1 +1 @@ -node /- "arg1" "arg2" \ No newline at end of file +node /- arg1 arg2 diff --git a/tests/test_cases/input/commented_child.kdl b/tests/test_cases/input/commented_child.kdl index da29663..8e873f7 100644 --- a/tests/test_cases/input/commented_child.kdl +++ b/tests/test_cases/input/commented_child.kdl @@ -1,3 +1,3 @@ -node "arg" /- { +node arg /- { inner_node } diff --git a/tests/test_cases/input/commented_line.kdl b/tests/test_cases/input/commented_line.kdl index b438cd5..bc8582c 100644 --- a/tests/test_cases/input/commented_line.kdl +++ b/tests/test_cases/input/commented_line.kdl @@ -1,2 +1,2 @@ // node_1 -node_2 +node_2 \ No newline at end of file diff --git a/tests/test_cases/input/commented_node.kdl b/tests/test_cases/input/commented_node.kdl index c9e5d12..1460d67 100644 --- a/tests/test_cases/input/commented_node.kdl +++ b/tests/test_cases/input/commented_node.kdl @@ -1,2 +1,3 @@ /- node_1 node_2 +/- node_3 diff --git a/tests/test_cases/input/commented_prop.kdl b/tests/test_cases/input/commented_prop.kdl index acedc83..046fd9d 100644 --- a/tests/test_cases/input/commented_prop.kdl +++ b/tests/test_cases/input/commented_prop.kdl @@ -1 +1 @@ -node /- prop="val" "arg" \ No newline at end of file +node /- prop=val arg diff --git a/tests/test_cases/input/crlf_between_nodes.kdl b/tests/test_cases/input/crlf_between_nodes.kdl index 1c5b5f3..148f7bc 100644 --- a/tests/test_cases/input/crlf_between_nodes.kdl +++ b/tests/test_cases/input/crlf_between_nodes.kdl @@ -1,2 +1,2 @@ -node1 -node2 +node1 +node2 diff --git a/tests/test_cases/input/dash_dash.kdl b/tests/test_cases/input/dash_dash.kdl index 759ddc5..9f6111a 100644 --- a/tests/test_cases/input/dash_dash.kdl +++ b/tests/test_cases/input/dash_dash.kdl @@ -1 +1 @@ -node -- \ No newline at end of file +node -- diff --git a/tests/test_cases/input/emoji.kdl b/tests/test_cases/input/emoji.kdl index 3ed56e2..88df78a 100644 --- a/tests/test_cases/input/emoji.kdl +++ b/tests/test_cases/input/emoji.kdl @@ -1 +1 @@ -node "😀" +node 😀 diff --git a/tests/test_cases/input/empty_child.kdl b/tests/test_cases/input/empty_child.kdl index a166b33..be1cc03 100644 --- a/tests/test_cases/input/empty_child.kdl +++ b/tests/test_cases/input/empty_child.kdl @@ -1,2 +1,2 @@ node { -} +} \ No newline at end of file diff --git a/tests/test_cases/input/empty_child_different_lines.kdl b/tests/test_cases/input/empty_child_different_lines.kdl index a166b33..be1cc03 100644 --- a/tests/test_cases/input/empty_child_different_lines.kdl +++ b/tests/test_cases/input/empty_child_different_lines.kdl @@ -1,2 +1,2 @@ node { -} +} \ No newline at end of file diff --git a/tests/test_cases/input/empty_child_whitespace.kdl b/tests/test_cases/input/empty_child_whitespace.kdl index ca9eee3..405df30 100644 --- a/tests/test_cases/input/empty_child_whitespace.kdl +++ b/tests/test_cases/input/empty_child_whitespace.kdl @@ -1,3 +1,3 @@ node { - } + } \ No newline at end of file diff --git a/tests/test_cases/input/empty_line_comment.kdl b/tests/test_cases/input/empty_line_comment.kdl new file mode 100644 index 0000000..e62ef84 --- /dev/null +++ b/tests/test_cases/input/empty_line_comment.kdl @@ -0,0 +1,2 @@ +// +node \ No newline at end of file diff --git a/tests/test_cases/input/empty_prop_type.kdl b/tests/test_cases/input/empty_prop_type.kdl index 0515094..233480b 100644 --- a/tests/test_cases/input/empty_prop_type.kdl +++ b/tests/test_cases/input/empty_prop_type.kdl @@ -1 +1 @@ -node key=()false +node key=()#false diff --git a/tests/test_cases/input/empty_quoted_node_id.kdl b/tests/test_cases/input/empty_quoted_node_id.kdl index 2aeb594..94694bc 100644 --- a/tests/test_cases/input/empty_quoted_node_id.kdl +++ b/tests/test_cases/input/empty_quoted_node_id.kdl @@ -1 +1 @@ -"" "arg" \ No newline at end of file +"" arg diff --git a/tests/test_cases/input/empty_quoted_prop_key.kdl b/tests/test_cases/input/empty_quoted_prop_key.kdl index e6e1310..e541793 100644 --- a/tests/test_cases/input/empty_quoted_prop_key.kdl +++ b/tests/test_cases/input/empty_quoted_prop_key.kdl @@ -1 +1 @@ -node ""="empty" +node ""=empty diff --git a/tests/test_cases/input/eof_after_escape.kdl b/tests/test_cases/input/eof_after_escape.kdl new file mode 100644 index 0000000..eed8d72 --- /dev/null +++ b/tests/test_cases/input/eof_after_escape.kdl @@ -0,0 +1 @@ +node \ diff --git a/tests/test_cases/input/err_backslash_in_bare_id.kdl b/tests/test_cases/input/err_backslash_in_bare_id.kdl new file mode 100644 index 0000000..2ea1a4b --- /dev/null +++ b/tests/test_cases/input/err_backslash_in_bare_id.kdl @@ -0,0 +1 @@ +foo123\bar weeee diff --git a/tests/test_cases/input/escaped_whitespace.kdl b/tests/test_cases/input/escaped_whitespace.kdl new file mode 100644 index 0000000..797784a --- /dev/null +++ b/tests/test_cases/input/escaped_whitespace.kdl @@ -0,0 +1,15 @@ +// All of these strings are the same +node \ + "Hello\n\tWorld" \ + " + Hello + World + " \ + "Hello\n\ \tWorld" \ + "Hello\n\ + \tWorld" \ + "Hello\n\t\ + World" + +// Note that this file deliberately mixes space and newline indentation for +// test purposes diff --git a/tests/test_cases/input/escline.kdl b/tests/test_cases/input/escline.kdl index 9868dd2..bcd1a1a 100644 --- a/tests/test_cases/input/escline.kdl +++ b/tests/test_cases/input/escline.kdl @@ -1,2 +1,2 @@ node \ - "arg" + arg diff --git a/tests/test_cases/input/escline_comment_node.kdl b/tests/test_cases/input/escline_comment_node.kdl deleted file mode 100644 index 8cfdf4f..0000000 --- a/tests/test_cases/input/escline_comment_node.kdl +++ /dev/null @@ -1,3 +0,0 @@ -node1 - \// hey - node2 diff --git a/tests/test_cases/input/escline_line_comment.kdl b/tests/test_cases/input/escline_line_comment.kdl index 588161b..dc81b72 100644 --- a/tests/test_cases/input/escline_line_comment.kdl +++ b/tests/test_cases/input/escline_line_comment.kdl @@ -1,4 +1,3 @@ node \ // comment - "arg" \// comment - "arg2 -" + arg \// comment + arg2 diff --git a/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl b/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl new file mode 100644 index 0000000..e120167 --- /dev/null +++ b/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl @@ -0,0 +1 @@ +floats inf -inf nan diff --git a/tests/test_cases/input/floating_point_keywords.kdl b/tests/test_cases/input/floating_point_keywords.kdl new file mode 100644 index 0000000..973a259 --- /dev/null +++ b/tests/test_cases/input/floating_point_keywords.kdl @@ -0,0 +1 @@ +floats #inf #-inf #nan diff --git a/tests/test_cases/input/hash_in_id.kdl b/tests/test_cases/input/hash_in_id.kdl new file mode 100644 index 0000000..e1119be --- /dev/null +++ b/tests/test_cases/input/hash_in_id.kdl @@ -0,0 +1 @@ +foo#bar weee diff --git a/tests/test_cases/input/hex.kdl b/tests/test_cases/input/hex.kdl index 890ceaf..ec764dd 100644 --- a/tests/test_cases/input/hex.kdl +++ b/tests/test_cases/input/hex.kdl @@ -1 +1 @@ -node 0x1234567890abcdef +node 0xabcdef1234567890 \ No newline at end of file diff --git a/tests/test_cases/input/hex_int.kdl b/tests/test_cases/input/hex_int.kdl index 28e2597..c2f421a 100644 --- a/tests/test_cases/input/hex_int.kdl +++ b/tests/test_cases/input/hex_int.kdl @@ -1 +1 @@ -node 0x1234567890ABCDEF +node 0xABCDEF0123456789abcdef diff --git a/tests/test_cases/input/initial_slashdash.kdl b/tests/test_cases/input/initial_slashdash.kdl new file mode 100644 index 0000000..aadeeb7 --- /dev/null +++ b/tests/test_cases/input/initial_slashdash.kdl @@ -0,0 +1,2 @@ +/-node here +another-node diff --git a/tests/test_cases/input/just_child.kdl b/tests/test_cases/input/just_child.kdl index ee79536..444022e 100644 --- a/tests/test_cases/input/just_child.kdl +++ b/tests/test_cases/input/just_child.kdl @@ -1,3 +1,3 @@ node { - inner_node -} + inner_node +} \ No newline at end of file diff --git a/tests/test_cases/input/just_space_in_prop_type.kdl b/tests/test_cases/input/just_space_in_prop_type.kdl index a00603c..e42645f 100644 --- a/tests/test_cases/input/just_space_in_prop_type.kdl +++ b/tests/test_cases/input/just_space_in_prop_type.kdl @@ -1 +1 @@ -node key=()0x10 +node key=( )0x10 diff --git a/tests/test_cases/input/leading_newline.kdl b/tests/test_cases/input/leading_newline.kdl index bf12fe6..fce4a83 100644 --- a/tests/test_cases/input/leading_newline.kdl +++ b/tests/test_cases/input/leading_newline.kdl @@ -1,2 +1,2 @@ -node +node \ No newline at end of file diff --git a/tests/test_cases/input/multiline_comment.kdl b/tests/test_cases/input/multiline_comment.kdl index b9dab39..5fbb80b 100644 --- a/tests/test_cases/input/multiline_comment.kdl +++ b/tests/test_cases/input/multiline_comment.kdl @@ -1,4 +1,4 @@ node /* some comments -*/ "arg" +*/ arg diff --git a/tests/test_cases/input/multiline_nodes.kdl b/tests/test_cases/input/multiline_nodes.kdl index 9bf4bfd..eae83d1 100644 --- a/tests/test_cases/input/multiline_nodes.kdl +++ b/tests/test_cases/input/multiline_nodes.kdl @@ -1,3 +1,3 @@ node \ - "arg1" \// comment - "arg2" + arg1 \// comment + arg2 diff --git a/tests/test_cases/input/multiline_raw_string.kdl b/tests/test_cases/input/multiline_raw_string.kdl new file mode 100644 index 0000000..eaa212e --- /dev/null +++ b/tests/test_cases/input/multiline_raw_string.kdl @@ -0,0 +1,5 @@ +node #" +hey +everyone +how goes? +"# diff --git a/tests/test_cases/input/multiline_raw_string_indented.kdl b/tests/test_cases/input/multiline_raw_string_indented.kdl new file mode 100644 index 0000000..67ef76d --- /dev/null +++ b/tests/test_cases/input/multiline_raw_string_indented.kdl @@ -0,0 +1,5 @@ +node #" + hey + everyone + how goes? + "# diff --git a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl new file mode 100644 index 0000000..c5650e9 --- /dev/null +++ b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl @@ -0,0 +1,5 @@ +node #" + hey + everyone + how goes? + "# diff --git a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl new file mode 100644 index 0000000..c0f4f56 --- /dev/null +++ b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl @@ -0,0 +1,5 @@ +node #" + hey + everyone + how goes? + "# diff --git a/tests/test_cases/input/multiline_string.kdl b/tests/test_cases/input/multiline_string.kdl index a437c1d..e3a6cc1 100644 --- a/tests/test_cases/input/multiline_string.kdl +++ b/tests/test_cases/input/multiline_string.kdl @@ -1,4 +1,5 @@ -node " hey +node " +hey everyone how goes? " diff --git a/tests/test_cases/input/multiline_string_indented.kdl b/tests/test_cases/input/multiline_string_indented.kdl new file mode 100644 index 0000000..ce9ca16 --- /dev/null +++ b/tests/test_cases/input/multiline_string_indented.kdl @@ -0,0 +1,5 @@ +node " + hey + everyone + how goes? + " diff --git a/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl b/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl new file mode 100644 index 0000000..1c2ca85 --- /dev/null +++ b/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl @@ -0,0 +1,5 @@ +node " + hey + everyone + how goes? + " diff --git a/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl b/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl new file mode 100644 index 0000000..86a2867 --- /dev/null +++ b/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl @@ -0,0 +1,5 @@ +node " + hey + everyone + how goes? + " diff --git a/tests/test_cases/input/nested_block_comment.kdl b/tests/test_cases/input/nested_block_comment.kdl index d7f765c..d9966a9 100644 --- a/tests/test_cases/input/nested_block_comment.kdl +++ b/tests/test_cases/input/nested_block_comment.kdl @@ -1 +1 @@ -node /* hi /* there */ everyone */ "arg" \ No newline at end of file +node /* hi /* there */ everyone */ arg diff --git a/tests/test_cases/input/nested_children.kdl b/tests/test_cases/input/nested_children.kdl index e44720d..40d2742 100644 --- a/tests/test_cases/input/nested_children.kdl +++ b/tests/test_cases/input/nested_children.kdl @@ -2,4 +2,4 @@ node1 { node2 { node } -} +} \ No newline at end of file diff --git a/tests/test_cases/input/nested_comments.kdl b/tests/test_cases/input/nested_comments.kdl index 8b3aad6..7541c39 100644 --- a/tests/test_cases/input/nested_comments.kdl +++ b/tests/test_cases/input/nested_comments.kdl @@ -1 +1 @@ -node /*/* nested */*/ "arg" \ No newline at end of file +node /*/* nested */*/ arg diff --git a/tests/test_cases/input/nested_multiline_block_comment.kdl b/tests/test_cases/input/nested_multiline_block_comment.kdl index 1d1c654..f1087e1 100644 --- a/tests/test_cases/input/nested_multiline_block_comment.kdl +++ b/tests/test_cases/input/nested_multiline_block_comment.kdl @@ -3,4 +3,4 @@ hey /* how's */ it going - */ "arg" + */ arg diff --git a/tests/test_cases/input/newlines_in_block_comment.kdl b/tests/test_cases/input/newlines_in_block_comment.kdl index f46c3d5..690461b 100644 --- a/tests/test_cases/input/newlines_in_block_comment.kdl +++ b/tests/test_cases/input/newlines_in_block_comment.kdl @@ -1,3 +1,3 @@ node /* hey so I was thinking -about newts */ "arg" +about newts */ arg diff --git a/tests/test_cases/input/no_integer_digit.kdl b/tests/test_cases/input/no_integer_digit.kdl new file mode 100644 index 0000000..bac8026 --- /dev/null +++ b/tests/test_cases/input/no_integer_digit.kdl @@ -0,0 +1 @@ +node .1 \ No newline at end of file diff --git a/tests/test_cases/input/no_solidus_escape.kdl b/tests/test_cases/input/no_solidus_escape.kdl new file mode 100644 index 0000000..2dbc2d1 --- /dev/null +++ b/tests/test_cases/input/no_solidus_escape.kdl @@ -0,0 +1 @@ +node "\/" diff --git a/tests/test_cases/input/node_false.kdl b/tests/test_cases/input/node_false.kdl index ef60c44..3bab782 100644 --- a/tests/test_cases/input/node_false.kdl +++ b/tests/test_cases/input/node_false.kdl @@ -1 +1 @@ -node false +node #false diff --git a/tests/test_cases/input/node_true.kdl b/tests/test_cases/input/node_true.kdl index 4b02a06..de00dcd 100644 --- a/tests/test_cases/input/node_true.kdl +++ b/tests/test_cases/input/node_true.kdl @@ -1 +1 @@ -node true +node #true diff --git a/tests/test_cases/input/null_arg.kdl b/tests/test_cases/input/null_arg.kdl index a5ce001..bed8dbf 100644 --- a/tests/test_cases/input/null_arg.kdl +++ b/tests/test_cases/input/null_arg.kdl @@ -1 +1 @@ -node null \ No newline at end of file +node #null diff --git a/tests/test_cases/input/null_prop.kdl b/tests/test_cases/input/null_prop.kdl index 847256f..c463e98 100644 --- a/tests/test_cases/input/null_prop.kdl +++ b/tests/test_cases/input/null_prop.kdl @@ -1 +1 @@ -node prop=null \ No newline at end of file +node prop=#null diff --git a/tests/test_cases/input/only_cr.kdl b/tests/test_cases/input/only_cr.kdl index 139597f..67c3297 100644 --- a/tests/test_cases/input/only_cr.kdl +++ b/tests/test_cases/input/only_cr.kdl @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/tests/test_cases/input/only_line_comment_crlf.kdl b/tests/test_cases/input/only_line_comment_crlf.kdl index fef83a9..b1653b8 100644 --- a/tests/test_cases/input/only_line_comment_crlf.kdl +++ b/tests/test_cases/input/only_line_comment_crlf.kdl @@ -1 +1 @@ -// comment +// comment diff --git a/tests/test_cases/input/optional_child_semicolon.kdl b/tests/test_cases/input/optional_child_semicolon.kdl new file mode 100644 index 0000000..5381491 --- /dev/null +++ b/tests/test_cases/input/optional_child_semicolon.kdl @@ -0,0 +1 @@ +node {foo;bar;baz} diff --git a/tests/test_cases/input/parens_in_bare_id.kdl b/tests/test_cases/input/parens_in_bare_id.kdl index 92459d8..ff9b439 100644 --- a/tests/test_cases/input/parens_in_bare_id.kdl +++ b/tests/test_cases/input/parens_in_bare_id.kdl @@ -1 +1 @@ -foo123(bar)foo "weeee" +foo123(bar)foo weeee diff --git a/tests/test_cases/input/parse_all_arg_types.kdl b/tests/test_cases/input/parse_all_arg_types.kdl index 30b9072..92dffb1 100644 --- a/tests/test_cases/input/parse_all_arg_types.kdl +++ b/tests/test_cases/input/parse_all_arg_types.kdl @@ -1 +1 @@ -node 1 1.0 1.0e10 1.0e-10 0x01 0o07 0b10 "arg" r"arg\\" true false null \ No newline at end of file +node 1 1.0 1.0e10 1.0e-10 0x01 0o07 0b10 arg "arg" #"arg\"# #true #false #null diff --git a/tests/test_cases/input/preserve_node_order.kdl b/tests/test_cases/input/preserve_node_order.kdl index 24c817f..5c36850 100644 --- a/tests/test_cases/input/preserve_node_order.kdl +++ b/tests/test_cases/input/preserve_node_order.kdl @@ -1,3 +1,3 @@ node2 node5 -node1 +node1 \ No newline at end of file diff --git a/tests/test_cases/input/prop_false_type.kdl b/tests/test_cases/input/prop_false_type.kdl index 3377323..eb544ef 100644 --- a/tests/test_cases/input/prop_false_type.kdl +++ b/tests/test_cases/input/prop_false_type.kdl @@ -1 +1 @@ -node key=(type)false +node key=(type)#false diff --git a/tests/test_cases/input/prop_identifier_type.kdl b/tests/test_cases/input/prop_identifier_type.kdl new file mode 100644 index 0000000..7df052b --- /dev/null +++ b/tests/test_cases/input/prop_identifier_type.kdl @@ -0,0 +1 @@ +node key=(type)str diff --git a/tests/test_cases/input/prop_null_type.kdl b/tests/test_cases/input/prop_null_type.kdl index bafaddc..1c25b6f 100644 --- a/tests/test_cases/input/prop_null_type.kdl +++ b/tests/test_cases/input/prop_null_type.kdl @@ -1 +1 @@ -node key=(type)null +node key=(type)#null diff --git a/tests/test_cases/input/prop_raw_string_type.kdl b/tests/test_cases/input/prop_raw_string_type.kdl index a038cfa..6822ab3 100644 --- a/tests/test_cases/input/prop_raw_string_type.kdl +++ b/tests/test_cases/input/prop_raw_string_type.kdl @@ -1 +1 @@ -node key=(type)r"str" +node key=(type)#"str"# diff --git a/tests/test_cases/input/prop_true_type.kdl b/tests/test_cases/input/prop_true_type.kdl index c4eebb6..01404b8 100644 --- a/tests/test_cases/input/prop_true_type.kdl +++ b/tests/test_cases/input/prop_true_type.kdl @@ -1 +1 @@ -node key=(type)true +node key=(type)#true diff --git a/tests/test_cases/input/prop_type.kdl b/tests/test_cases/input/prop_type.kdl index d69294f..01404b8 100644 --- a/tests/test_cases/input/prop_type.kdl +++ b/tests/test_cases/input/prop_type.kdl @@ -1 +1 @@ -node key=(type)true \ No newline at end of file +node key=(type)#true diff --git a/tests/test_cases/input/question_mark_at_start_of_int.kdl b/tests/test_cases/input/question_mark_at_start_of_int.kdl deleted file mode 100644 index ba82916..0000000 --- a/tests/test_cases/input/question_mark_at_start_of_int.kdl +++ /dev/null @@ -1 +0,0 @@ -node ?10 \ No newline at end of file diff --git a/tests/test_cases/input/question_mark_before_number.kdl b/tests/test_cases/input/question_mark_before_number.kdl index 532ef22..7745a9e 100644 --- a/tests/test_cases/input/question_mark_before_number.kdl +++ b/tests/test_cases/input/question_mark_before_number.kdl @@ -1 +1 @@ -node ?15 \ No newline at end of file +node ?15 diff --git a/tests/test_cases/input/quote_in_bare_id.kdl b/tests/test_cases/input/quote_in_bare_id.kdl index 405f763..0d8a664 100644 --- a/tests/test_cases/input/quote_in_bare_id.kdl +++ b/tests/test_cases/input/quote_in_bare_id.kdl @@ -1 +1 @@ -foo123"bar "weeee" +foo123"bar weeee diff --git a/tests/test_cases/input/quoted_prop_name.kdl b/tests/test_cases/input/quoted_prop_name.kdl index 73ec6dd..8ee5e08 100644 --- a/tests/test_cases/input/quoted_prop_name.kdl +++ b/tests/test_cases/input/quoted_prop_name.kdl @@ -1 +1 @@ -node "0prop"="val" \ No newline at end of file +node "0prop"=val diff --git a/tests/test_cases/input/quoted_prop_type.kdl b/tests/test_cases/input/quoted_prop_type.kdl index 0e2b920..beca5f2 100644 --- a/tests/test_cases/input/quoted_prop_type.kdl +++ b/tests/test_cases/input/quoted_prop_type.kdl @@ -1 +1 @@ -node key=("type/")true +node key=("type/")#true diff --git a/tests/test_cases/input/raw_arg_type.kdl b/tests/test_cases/input/raw_arg_type.kdl index c5739b1..20243a3 100644 --- a/tests/test_cases/input/raw_arg_type.kdl +++ b/tests/test_cases/input/raw_arg_type.kdl @@ -1 +1 @@ -node (type)true \ No newline at end of file +node (type)#true diff --git a/tests/test_cases/input/raw_node_name.kdl b/tests/test_cases/input/raw_node_name.kdl index 0d38371..f2705c7 100644 --- a/tests/test_cases/input/raw_node_name.kdl +++ b/tests/test_cases/input/raw_node_name.kdl @@ -1 +1 @@ -r"\node" \ No newline at end of file +#"\node"# diff --git a/tests/test_cases/input/raw_prop_type.kdl b/tests/test_cases/input/raw_prop_type.kdl index d69294f..01404b8 100644 --- a/tests/test_cases/input/raw_prop_type.kdl +++ b/tests/test_cases/input/raw_prop_type.kdl @@ -1 +1 @@ -node key=(type)true \ No newline at end of file +node key=(type)#true diff --git a/tests/test_cases/input/raw_string_arg.kdl b/tests/test_cases/input/raw_string_arg.kdl index 3c07898..05cf37e 100644 --- a/tests/test_cases/input/raw_string_arg.kdl +++ b/tests/test_cases/input/raw_string_arg.kdl @@ -1,3 +1,2 @@ -node_1 r"arg\n" -node_2 r#""arg\n"and stuff"# -node_3 r##"#"arg\n"#and stuff"## +node_1 #""arg\n"and #stuff"# +node_2 ##"#"arg\n"#and #stuff"## diff --git a/tests/test_cases/input/raw_string_backslash.kdl b/tests/test_cases/input/raw_string_backslash.kdl index 0f7ca45..0405248 100644 --- a/tests/test_cases/input/raw_string_backslash.kdl +++ b/tests/test_cases/input/raw_string_backslash.kdl @@ -1 +1 @@ -node r"\n" +node #"\n"# diff --git a/tests/test_cases/input/raw_string_hash_no_esc.kdl b/tests/test_cases/input/raw_string_hash_no_esc.kdl index c8fa3c4..ce24c79 100644 --- a/tests/test_cases/input/raw_string_hash_no_esc.kdl +++ b/tests/test_cases/input/raw_string_hash_no_esc.kdl @@ -1 +1 @@ -node r"#" +node #"#"# diff --git a/tests/test_cases/input/raw_string_just_backslash.kdl b/tests/test_cases/input/raw_string_just_backslash.kdl index 9aefa73..f4e1cac 100644 --- a/tests/test_cases/input/raw_string_just_backslash.kdl +++ b/tests/test_cases/input/raw_string_just_backslash.kdl @@ -1 +1 @@ -node r"\" +node #"\"# diff --git a/tests/test_cases/input/raw_string_just_quote.kdl b/tests/test_cases/input/raw_string_just_quote.kdl index b8333ca..e81bf12 100644 --- a/tests/test_cases/input/raw_string_just_quote.kdl +++ b/tests/test_cases/input/raw_string_just_quote.kdl @@ -1 +1 @@ -node r#"""# +node #"""# diff --git a/tests/test_cases/input/raw_string_multiple_hash.kdl b/tests/test_cases/input/raw_string_multiple_hash.kdl index e6d054c..6317f36 100644 --- a/tests/test_cases/input/raw_string_multiple_hash.kdl +++ b/tests/test_cases/input/raw_string_multiple_hash.kdl @@ -1 +1 @@ -node r###""#"##"### +node ###""#"##"### diff --git a/tests/test_cases/input/raw_string_newline.kdl b/tests/test_cases/input/raw_string_newline.kdl index ef39d3c..0cc85c0 100644 --- a/tests/test_cases/input/raw_string_newline.kdl +++ b/tests/test_cases/input/raw_string_newline.kdl @@ -1,4 +1,4 @@ -node r" +node #" hello world -" +"# diff --git a/tests/test_cases/input/raw_string_prop.kdl b/tests/test_cases/input/raw_string_prop.kdl index 850ed42..cc59232 100644 --- a/tests/test_cases/input/raw_string_prop.kdl +++ b/tests/test_cases/input/raw_string_prop.kdl @@ -1,3 +1,2 @@ -node_1 prop=r"arg\n" -node_2 prop=r#""arg"\n"# -node_3 prop=r##"#"arg"#\n"## +node_1 prop=#""arg#"\n"# +node_2 prop=##"#"arg#"#\n"## diff --git a/tests/test_cases/input/raw_string_quote.kdl b/tests/test_cases/input/raw_string_quote.kdl index cd7419c..004b62f 100644 --- a/tests/test_cases/input/raw_string_quote.kdl +++ b/tests/test_cases/input/raw_string_quote.kdl @@ -1 +1 @@ -node r#"a"b"# \ No newline at end of file +node #"a"b"# diff --git a/tests/test_cases/input/repeated_arg.kdl b/tests/test_cases/input/repeated_arg.kdl index beab120..6525757 100644 --- a/tests/test_cases/input/repeated_arg.kdl +++ b/tests/test_cases/input/repeated_arg.kdl @@ -1 +1 @@ -node "arg" "arg" \ No newline at end of file +node arg arg diff --git a/tests/test_cases/input/same_args.kdl b/tests/test_cases/input/same_args.kdl deleted file mode 100644 index c412de8..0000000 --- a/tests/test_cases/input/same_args.kdl +++ /dev/null @@ -1 +0,0 @@ -node "whee" "whee" \ No newline at end of file diff --git a/tests/test_cases/input/semicolon_in_child.kdl b/tests/test_cases/input/semicolon_in_child.kdl index fa3e748..ec6fff1 100644 --- a/tests/test_cases/input/semicolon_in_child.kdl +++ b/tests/test_cases/input/semicolon_in_child.kdl @@ -1,3 +1,3 @@ node1 { node2; -} +} \ No newline at end of file diff --git a/tests/test_cases/input/single_arg.kdl b/tests/test_cases/input/single_arg.kdl index e5161d1..1b3db2c 100644 --- a/tests/test_cases/input/single_arg.kdl +++ b/tests/test_cases/input/single_arg.kdl @@ -1 +1 @@ -node "arg" \ No newline at end of file +node arg diff --git a/tests/test_cases/input/single_prop.kdl b/tests/test_cases/input/single_prop.kdl index 4c29c14..282aa3b 100644 --- a/tests/test_cases/input/single_prop.kdl +++ b/tests/test_cases/input/single_prop.kdl @@ -1 +1 @@ -node prop="val" \ No newline at end of file +node prop=val diff --git a/tests/test_cases/input/slash_in_bare_id.kdl b/tests/test_cases/input/slash_in_bare_id.kdl index 1139c88..d26d325 100644 --- a/tests/test_cases/input/slash_in_bare_id.kdl +++ b/tests/test_cases/input/slash_in_bare_id.kdl @@ -1 +1 @@ -foo123/bar "weeee" +foo123/bar weeee diff --git a/tests/test_cases/input/slashdash_arg_after_newline_esc.kdl b/tests/test_cases/input/slashdash_arg_after_newline_esc.kdl index 059b3e1..5a4a9fd 100644 --- a/tests/test_cases/input/slashdash_arg_after_newline_esc.kdl +++ b/tests/test_cases/input/slashdash_arg_after_newline_esc.kdl @@ -1,2 +1,2 @@ node \ - /- "arg" "arg2" + /- arg arg2 diff --git a/tests/test_cases/input/slashdash_arg_before_newline_esc.kdl b/tests/test_cases/input/slashdash_arg_before_newline_esc.kdl index f58e4a7..70206aa 100644 --- a/tests/test_cases/input/slashdash_arg_before_newline_esc.kdl +++ b/tests/test_cases/input/slashdash_arg_before_newline_esc.kdl @@ -1,2 +1,2 @@ node /- \ - "arg" + arg diff --git a/tests/test_cases/input/slashdash_full_node.kdl b/tests/test_cases/input/slashdash_full_node.kdl index 3ca9ac5..4df7b55 100644 --- a/tests/test_cases/input/slashdash_full_node.kdl +++ b/tests/test_cases/input/slashdash_full_node.kdl @@ -1,2 +1,3 @@ -/- node 1.0 "a" b="b +/- node 1.0 "a" b=" +b " diff --git a/tests/test_cases/input/slashdash_in_slashdash.kdl b/tests/test_cases/input/slashdash_in_slashdash.kdl index 141f098..cb43150 100644 --- a/tests/test_cases/input/slashdash_in_slashdash.kdl +++ b/tests/test_cases/input/slashdash_in_slashdash.kdl @@ -1,2 +1,2 @@ /- node1 /- 1.0 -node2 +node2 \ No newline at end of file diff --git a/tests/test_cases/input/slashdash_node_in_child.kdl b/tests/test_cases/input/slashdash_node_in_child.kdl index fce03d4..77fd44a 100644 --- a/tests/test_cases/input/slashdash_node_in_child.kdl +++ b/tests/test_cases/input/slashdash_node_in_child.kdl @@ -1,3 +1,3 @@ node1 { /- node2 -} +} \ No newline at end of file diff --git a/tests/test_cases/input/slashdash_node_with_child.kdl b/tests/test_cases/input/slashdash_node_with_child.kdl index 0486213..d3063dd 100644 --- a/tests/test_cases/input/slashdash_node_with_child.kdl +++ b/tests/test_cases/input/slashdash_node_with_child.kdl @@ -1,3 +1,3 @@ /- node { node2 -} +} \ No newline at end of file diff --git a/tests/test_cases/input/slashdash_prop.kdl b/tests/test_cases/input/slashdash_prop.kdl index 3d7b806..2b81f5f 100644 --- a/tests/test_cases/input/slashdash_prop.kdl +++ b/tests/test_cases/input/slashdash_prop.kdl @@ -1 +1 @@ -node /- key="value" "arg" +node /- key=value arg diff --git a/tests/test_cases/input/slashdash_raw_prop_key.kdl b/tests/test_cases/input/slashdash_raw_prop_key.kdl index c9ad5ad..9b0978b 100644 --- a/tests/test_cases/input/slashdash_raw_prop_key.kdl +++ b/tests/test_cases/input/slashdash_raw_prop_key.kdl @@ -1 +1 @@ -node /- key="value" +node /- key=value diff --git a/tests/test_cases/input/slashdash_repeated_prop.kdl b/tests/test_cases/input/slashdash_repeated_prop.kdl index b427175..c94411a 100644 --- a/tests/test_cases/input/slashdash_repeated_prop.kdl +++ b/tests/test_cases/input/slashdash_repeated_prop.kdl @@ -1 +1 @@ -node arg="correct" /- arg="wrong" +node arg=correct /- arg=wrong diff --git a/tests/test_cases/input/space_after_prop_type.kdl b/tests/test_cases/input/space_after_prop_type.kdl index a891dfd..023a75c 100644 --- a/tests/test_cases/input/space_after_prop_type.kdl +++ b/tests/test_cases/input/space_after_prop_type.kdl @@ -1 +1 @@ -node key=(type) false +node key=(type) #false diff --git a/tests/test_cases/input/space_around_prop_marker.kdl b/tests/test_cases/input/space_around_prop_marker.kdl new file mode 100644 index 0000000..52150d8 --- /dev/null +++ b/tests/test_cases/input/space_around_prop_marker.kdl @@ -0,0 +1 @@ +node foo = bar diff --git a/tests/test_cases/input/space_in_arg_type.kdl b/tests/test_cases/input/space_in_arg_type.kdl index 2f9ca24..e2fb065 100644 --- a/tests/test_cases/input/space_in_arg_type.kdl +++ b/tests/test_cases/input/space_in_arg_type.kdl @@ -1 +1 @@ -node (type )false +node (type )#false diff --git a/tests/test_cases/input/space_in_prop_type.kdl b/tests/test_cases/input/space_in_prop_type.kdl index 4e9c750..0a18c97 100644 --- a/tests/test_cases/input/space_in_prop_type.kdl +++ b/tests/test_cases/input/space_in_prop_type.kdl @@ -1 +1 @@ -node key=(type )false +node key=(type )#false diff --git a/tests/test_cases/input/square_bracket_in_bare_id.kdl b/tests/test_cases/input/square_bracket_in_bare_id.kdl index 2dd54e9..62f34e2 100644 --- a/tests/test_cases/input/square_bracket_in_bare_id.kdl +++ b/tests/test_cases/input/square_bracket_in_bare_id.kdl @@ -1 +1 @@ -foo123[bar]foo "weeee" +foo123[bar]foo weeee diff --git a/tests/test_cases/input/string_escaped_literal_whitespace.kdl b/tests/test_cases/input/string_escaped_literal_whitespace.kdl new file mode 100644 index 0000000..1f12126 --- /dev/null +++ b/tests/test_cases/input/string_escaped_literal_whitespace.kdl @@ -0,0 +1,2 @@ +node "Hello \ +World \ Stuff" diff --git a/tests/test_cases/input/trailing_crlf.kdl b/tests/test_cases/input/trailing_crlf.kdl index 64f5a0a..aff78f7 100644 --- a/tests/test_cases/input/trailing_crlf.kdl +++ b/tests/test_cases/input/trailing_crlf.kdl @@ -1 +1 @@ -node +node diff --git a/tests/test_cases/input/unbalanced_raw_hashes.kdl b/tests/test_cases/input/unbalanced_raw_hashes.kdl index 7deb72f..d0213f2 100644 --- a/tests/test_cases/input/unbalanced_raw_hashes.kdl +++ b/tests/test_cases/input/unbalanced_raw_hashes.kdl @@ -1 +1 @@ -node r##"foo"# +node ##"foo"# diff --git a/tests/test_cases/input/underscore_at_start_of_int.kdl b/tests/test_cases/input/underscore_at_start_of_int.kdl deleted file mode 100644 index b854b60..0000000 --- a/tests/test_cases/input/underscore_at_start_of_int.kdl +++ /dev/null @@ -1 +0,0 @@ -node _15 \ No newline at end of file diff --git a/tests/test_cases/input/unicode_delete.kdl b/tests/test_cases/input/unicode_delete.kdl new file mode 100644 index 0000000..3fb52ed --- /dev/null +++ b/tests/test_cases/input/unicode_delete.kdl @@ -0,0 +1,2 @@ +// 0x007F (Delete) +node1 arg diff --git a/tests/test_cases/input/unicode_equals_signs.kdl b/tests/test_cases/input/unicode_equals_signs.kdl new file mode 100644 index 0000000..37d8e02 --- /dev/null +++ b/tests/test_cases/input/unicode_equals_signs.kdl @@ -0,0 +1,4 @@ +node \ + p1﹦val1 \ // U+FE66 + p2=val2 \ // U+FF1D + p3🟰val3 // U+1F7F0 diff --git a/tests/test_cases/input/unicode_fsi.kdl b/tests/test_cases/input/unicode_fsi.kdl new file mode 100644 index 0000000..7aece14 --- /dev/null +++ b/tests/test_cases/input/unicode_fsi.kdl @@ -0,0 +1,2 @@ +// 0x2068 +node1 ⁨arg diff --git a/tests/test_cases/input/unicode_lre.kdl b/tests/test_cases/input/unicode_lre.kdl new file mode 100644 index 0000000..33342ae --- /dev/null +++ b/tests/test_cases/input/unicode_lre.kdl @@ -0,0 +1,2 @@ +// 0x202A +node1 ‪arg diff --git a/tests/test_cases/input/unicode_lri.kdl b/tests/test_cases/input/unicode_lri.kdl new file mode 100644 index 0000000..adec826 --- /dev/null +++ b/tests/test_cases/input/unicode_lri.kdl @@ -0,0 +1,2 @@ +// 0x2066 +node1⁦arg diff --git a/tests/test_cases/input/unicode_lrm.kdl b/tests/test_cases/input/unicode_lrm.kdl new file mode 100644 index 0000000..ff37cad --- /dev/null +++ b/tests/test_cases/input/unicode_lrm.kdl @@ -0,0 +1,2 @@ +// 0x200E +node ‎arg diff --git a/tests/test_cases/input/unicode_lro.kdl b/tests/test_cases/input/unicode_lro.kdl new file mode 100644 index 0000000..b084ded --- /dev/null +++ b/tests/test_cases/input/unicode_lro.kdl @@ -0,0 +1,2 @@ +// 0x202D +node ‭arg diff --git a/tests/test_cases/input/unicode_pdf.kdl b/tests/test_cases/input/unicode_pdf.kdl new file mode 100644 index 0000000..9b94fad --- /dev/null +++ b/tests/test_cases/input/unicode_pdf.kdl @@ -0,0 +1,2 @@ +// 0x202C +node ‬arg diff --git a/tests/test_cases/input/unicode_pdi.kdl b/tests/test_cases/input/unicode_pdi.kdl new file mode 100644 index 0000000..d92d2d7 --- /dev/null +++ b/tests/test_cases/input/unicode_pdi.kdl @@ -0,0 +1,2 @@ +// 0x2069 +node ⁩arg diff --git a/tests/test_cases/input/unicode_rle.kdl b/tests/test_cases/input/unicode_rle.kdl new file mode 100644 index 0000000..3b46610 --- /dev/null +++ b/tests/test_cases/input/unicode_rle.kdl @@ -0,0 +1,2 @@ +// 0x202B +node1 ‫arg diff --git a/tests/test_cases/input/unicode_rli.kdl b/tests/test_cases/input/unicode_rli.kdl new file mode 100644 index 0000000..92902ed --- /dev/null +++ b/tests/test_cases/input/unicode_rli.kdl @@ -0,0 +1,2 @@ +// 0x2067 +node1 ⁧arg diff --git a/tests/test_cases/input/unicode_rlm.kdl b/tests/test_cases/input/unicode_rlm.kdl new file mode 100644 index 0000000..bfa63c8 --- /dev/null +++ b/tests/test_cases/input/unicode_rlm.kdl @@ -0,0 +1,2 @@ +// 0x200F +node ‏arg diff --git a/tests/test_cases/input/unicode_rlo.kdl b/tests/test_cases/input/unicode_rlo.kdl new file mode 100644 index 0000000..98c848b --- /dev/null +++ b/tests/test_cases/input/unicode_rlo.kdl @@ -0,0 +1,2 @@ +// 0x202E +node ‮arg diff --git a/tests/test_cases/input/unicode_under_0x20.kdl b/tests/test_cases/input/unicode_under_0x20.kdl new file mode 100644 index 0000000..967a87a --- /dev/null +++ b/tests/test_cases/input/unicode_under_0x20.kdl @@ -0,0 +1,2 @@ +// 0x0019 +node1 arg diff --git a/tests/test_cases/input/unusual_bare_id_chars_in_quoted_id.kdl b/tests/test_cases/input/unusual_bare_id_chars_in_quoted_id.kdl index e37de20..d3262b8 100644 --- a/tests/test_cases/input/unusual_bare_id_chars_in_quoted_id.kdl +++ b/tests/test_cases/input/unusual_bare_id_chars_in_quoted_id.kdl @@ -1 +1 @@ -"foo123~!@#$%^&*.:'|?+" "weeee" \ No newline at end of file +"foo123~!@$%^&*.:'|?+<>," weeee diff --git a/tests/test_cases/input/unusual_chars_in_bare_id.kdl b/tests/test_cases/input/unusual_chars_in_bare_id.kdl index d2dcd19..8321632 100644 --- a/tests/test_cases/input/unusual_chars_in_bare_id.kdl +++ b/tests/test_cases/input/unusual_chars_in_bare_id.kdl @@ -1 +1 @@ -foo123~!@#$%^&*.:'|?+ "weeee" +foo123~!@$%^&*.:'|?+<>, weeee diff --git a/tests/test_cases/input/vertical_tab_whitespace.kdl b/tests/test_cases/input/vertical_tab_whitespace.kdl new file mode 100644 index 0000000..507d3a0 --- /dev/null +++ b/tests/test_cases/input/vertical_tab_whitespace.kdl @@ -0,0 +1 @@ +node arg