├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── kdl ├── __init__.py ├── cli.py ├── converters.py ├── errors.py ├── parsefuncs.py ├── parsing.py ├── printing.py ├── py.typed ├── result.py ├── stream.py ├── t.py └── types.py ├── kdlreformat.py ├── lint ├── mypy.ini ├── pyproject.toml ├── release.py ├── requirements-dev.txt ├── requirements.txt ├── semver.txt ├── setup.py ├── test_upstream.py └── upstream_tests ├── README.md └── test_cases ├── expected_kdl ├── all_escapes.kdl ├── all_node_fields.kdl ├── arg_and_prop_same_name.kdl ├── arg_bare.kdl ├── arg_false_type.kdl ├── arg_float_type.kdl ├── arg_hex_type.kdl ├── arg_null_type.kdl ├── arg_raw_string_type.kdl ├── arg_string_type.kdl ├── arg_true_type.kdl ├── arg_type.kdl ├── arg_zero_type.kdl ├── asterisk_in_block_comment.kdl ├── bare_emoji.kdl ├── bare_ident_dot.kdl ├── bare_ident_sign.kdl ├── bare_ident_sign_dot.kdl ├── binary.kdl ├── binary_trailing_underscore.kdl ├── binary_underscore.kdl ├── blank_arg_type.kdl ├── blank_node_type.kdl ├── blank_prop_type.kdl ├── block_comment.kdl ├── block_comment_after_node.kdl ├── block_comment_before_node.kdl ├── block_comment_before_node_no_space.kdl ├── block_comment_newline.kdl ├── bom_initial.kdl ├── boolean_arg.kdl ├── boolean_prop.kdl ├── chevrons_in_bare_id.kdl ├── comma_in_bare_id.kdl ├── comment_after_arg_type.kdl ├── comment_after_node_type.kdl ├── comment_after_prop_type.kdl ├── comment_and_newline.kdl ├── comment_in_arg_type.kdl ├── comment_in_node_type.kdl ├── comment_in_prop_type.kdl ├── commented_arg.kdl ├── commented_child.kdl ├── commented_line.kdl ├── commented_node.kdl ├── commented_prop.kdl ├── crlf_between_nodes.kdl ├── dash_dash.kdl ├── emoji.kdl ├── empty.kdl ├── empty_child.kdl ├── empty_child_different_lines.kdl ├── empty_child_same_line.kdl ├── empty_child_whitespace.kdl ├── empty_line_comment.kdl ├── empty_quoted_node_id.kdl ├── empty_quoted_prop_key.kdl ├── empty_string_arg.kdl ├── eof_after_escape.kdl ├── esc_multiple_newlines.kdl ├── esc_newline_in_string.kdl ├── esc_unicode_in_string.kdl ├── escaped_whitespace.kdl ├── escline.kdl ├── escline_after_semicolon.kdl ├── escline_alone.kdl ├── escline_empty_line.kdl ├── escline_end_of_node.kdl ├── escline_in_child_block.kdl ├── escline_line_comment.kdl ├── escline_node.kdl ├── escline_node_type.kdl ├── escline_slashdash.kdl ├── false_prefix_in_bare_id.kdl ├── false_prefix_in_prop_key.kdl ├── floating_point_keywords.kdl ├── hex.kdl ├── hex_int.kdl ├── hex_int_underscores.kdl ├── hex_leading_zero.kdl ├── initial_slashdash.kdl ├── int_multiple_underscore.kdl ├── just_block_comment.kdl ├── just_child.kdl ├── just_newline.kdl ├── just_node_id.kdl ├── just_space.kdl ├── leading_newline.kdl ├── leading_zero_binary.kdl ├── leading_zero_int.kdl ├── leading_zero_oct.kdl ├── multiline_comment.kdl ├── multiline_nodes.kdl ├── multiline_raw_string.kdl ├── multiline_raw_string_containing_quotes.kdl ├── multiline_raw_string_empty.kdl ├── multiline_raw_string_empty_indented.kdl ├── multiline_raw_string_indented.kdl ├── multiline_string.kdl ├── multiline_string_containing_quotes.kdl ├── multiline_string_double_backslash.kdl ├── multiline_string_empty.kdl ├── multiline_string_empty_indented.kdl ├── multiline_string_escape_delimiter.kdl ├── multiline_string_escape_in_closing_line.kdl ├── multiline_string_escape_in_closing_line_shallow.kdl ├── multiline_string_escape_newline_at_end.kdl ├── multiline_string_indented.kdl ├── multiline_string_whitespace_only.kdl ├── negative_exponent.kdl ├── negative_float.kdl ├── negative_int.kdl ├── nested_block_comment.kdl ├── nested_children.kdl ├── nested_comments.kdl ├── nested_multiline_block_comment.kdl ├── newline_between_nodes.kdl ├── newlines_in_block_comment.kdl ├── no_decimal_exponent.kdl ├── node_false.kdl ├── node_true.kdl ├── node_type.kdl ├── null_arg.kdl ├── null_prefix_in_bare_id.kdl ├── null_prefix_in_prop_key.kdl ├── null_prop.kdl ├── numeric_arg.kdl ├── numeric_prop.kdl ├── octal.kdl ├── only_cr.kdl ├── only_line_comment.kdl ├── only_line_comment_crlf.kdl ├── only_line_comment_newline.kdl ├── optional_child_semicolon.kdl ├── parse_all_arg_types.kdl ├── positive_exponent.kdl ├── positive_int.kdl ├── preserve_duplicate_nodes.kdl ├── preserve_node_order.kdl ├── prop_false_type.kdl ├── prop_float_type.kdl ├── prop_hex_type.kdl ├── prop_identifier_type.kdl ├── prop_null_type.kdl ├── prop_raw_string_type.kdl ├── prop_string_type.kdl ├── prop_true_type.kdl ├── prop_type.kdl ├── prop_zero_type.kdl ├── question_mark_before_number.kdl ├── quoted_arg_type.kdl ├── quoted_node_name.kdl ├── quoted_node_type.kdl ├── quoted_numeric.kdl ├── quoted_prop_name.kdl ├── quoted_prop_type.kdl ├── r_node.kdl ├── raw_arg_type.kdl ├── raw_node_name.kdl ├── raw_node_type.kdl ├── raw_prop_type.kdl ├── raw_string_arg.kdl ├── raw_string_backslash.kdl ├── raw_string_hash_no_esc.kdl ├── raw_string_just_backslash.kdl ├── raw_string_multiple_hash.kdl ├── raw_string_newline.kdl ├── raw_string_prop.kdl ├── raw_string_quote.kdl ├── repeated_arg.kdl ├── repeated_prop.kdl ├── same_name_nodes.kdl ├── sci_notation_large.kdl ├── sci_notation_small.kdl ├── semicolon_after_child.kdl ├── semicolon_in_child.kdl ├── semicolon_separated.kdl ├── semicolon_separated_nodes.kdl ├── semicolon_terminated.kdl ├── single_arg.kdl ├── single_prop.kdl ├── slashdash_arg_after_newline_esc.kdl ├── slashdash_arg_before_newline_esc.kdl ├── slashdash_child.kdl ├── slashdash_empty_child.kdl ├── slashdash_escline_before_arg_type.kdl ├── slashdash_escline_before_children.kdl ├── slashdash_escline_before_node.kdl ├── slashdash_false_node.kdl ├── slashdash_full_node.kdl ├── slashdash_in_slashdash.kdl ├── slashdash_multi_line_comment_entry.kdl ├── slashdash_multi_line_comment_inline.kdl ├── slashdash_multiple_child_blocks.kdl ├── slashdash_negative_number.kdl ├── slashdash_newline_before_children.kdl ├── slashdash_newline_before_entry.kdl ├── slashdash_newline_before_node.kdl ├── slashdash_node_in_child.kdl ├── slashdash_node_with_child.kdl ├── slashdash_only_node.kdl ├── slashdash_only_node_with_space.kdl ├── slashdash_prop.kdl ├── slashdash_raw_prop_key.kdl ├── slashdash_repeated_prop.kdl ├── slashdash_single_line_comment_entry.kdl ├── slashdash_single_line_comment_node.kdl ├── space_after_arg_type.kdl ├── space_after_node_type.kdl ├── space_after_prop_type.kdl ├── space_around_prop_marker.kdl ├── space_in_arg_type.kdl ├── space_in_node_type.kdl ├── space_in_prop_type.kdl ├── string_arg.kdl ├── string_escaped_literal_whitespace.kdl ├── string_prop.kdl ├── tab_space.kdl ├── trailing_crlf.kdl ├── trailing_underscore_hex.kdl ├── trailing_underscore_octal.kdl ├── true_prefix_in_bare_id.kdl ├── true_prefix_in_prop_key.kdl ├── two_nodes.kdl ├── underscore_before_number.kdl ├── underscore_in_exponent.kdl ├── underscore_in_float.kdl ├── underscore_in_fraction.kdl ├── underscore_in_int.kdl ├── underscore_in_octal.kdl ├── unicode_silly.kdl ├── unusual_bare_id_chars_in_quoted_id.kdl ├── unusual_chars_in_bare_id.kdl ├── vertical_tab_whitespace.kdl ├── zero_float.kdl └── zero_int.kdl └── input ├── all_escapes.kdl ├── all_node_fields.kdl ├── arg_and_prop_same_name.kdl ├── arg_bare.kdl ├── arg_false_type.kdl ├── arg_float_type.kdl ├── arg_hex_type.kdl ├── arg_null_type.kdl ├── arg_raw_string_type.kdl ├── arg_string_type.kdl ├── arg_true_type.kdl ├── arg_type.kdl ├── arg_zero_type.kdl ├── asterisk_in_block_comment.kdl ├── bare_emoji.kdl ├── bare_ident_dot.kdl ├── bare_ident_numeric_dot_fail.kdl ├── bare_ident_numeric_fail.kdl ├── bare_ident_numeric_sign_fail.kdl ├── bare_ident_sign.kdl ├── bare_ident_sign_dot.kdl ├── binary.kdl ├── binary_trailing_underscore.kdl ├── binary_underscore.kdl ├── blank_arg_type.kdl ├── blank_node_type.kdl ├── blank_prop_type.kdl ├── block_comment.kdl ├── block_comment_after_node.kdl ├── block_comment_before_node.kdl ├── block_comment_before_node_no_space.kdl ├── block_comment_newline.kdl ├── bom_initial.kdl ├── bom_later_fail.kdl ├── boolean_arg.kdl ├── boolean_prop.kdl ├── braces_in_bare_id_fail.kdl ├── brackets_in_bare_id_fail.kdl ├── chevrons_in_bare_id.kdl ├── comma_in_bare_id.kdl ├── comment_after_arg_type.kdl ├── comment_after_node_type.kdl ├── comment_after_prop_type.kdl ├── comment_and_newline.kdl ├── comment_in_arg_type.kdl ├── comment_in_node_type.kdl ├── comment_in_prop_type.kdl ├── commented_arg.kdl ├── commented_child.kdl ├── commented_line.kdl ├── commented_node.kdl ├── commented_prop.kdl ├── crlf_between_nodes.kdl ├── dash_dash.kdl ├── dot_but_no_fraction_before_exponent_fail.kdl ├── dot_but_no_fraction_fail.kdl ├── dot_in_exponent_fail.kdl ├── dot_zero_fail.kdl ├── emoji.kdl ├── empty.kdl ├── empty_arg_type_fail.kdl ├── empty_child.kdl ├── empty_child_different_lines.kdl ├── empty_child_same_line.kdl ├── empty_child_whitespace.kdl ├── empty_line_comment.kdl ├── empty_node_type_fail.kdl ├── empty_prop_type_fail.kdl ├── empty_quoted_node_id.kdl ├── empty_quoted_prop_key.kdl ├── empty_string_arg.kdl ├── eof_after_escape.kdl ├── err_backslash_in_bare_id_fail.kdl ├── esc_multiple_newlines.kdl ├── esc_newline_in_string.kdl ├── esc_unicode_in_string.kdl ├── escaped_whitespace.kdl ├── escline.kdl ├── escline_after_semicolon.kdl ├── escline_alone.kdl ├── escline_empty_line.kdl ├── escline_end_of_node.kdl ├── escline_in_child_block.kdl ├── escline_line_comment.kdl ├── escline_node.kdl ├── escline_node_type.kdl ├── escline_slashdash.kdl ├── false_prefix_in_bare_id.kdl ├── false_prefix_in_prop_key.kdl ├── false_prop_key_fail.kdl ├── floating_point_keyword_identifier_strings_fail.kdl ├── floating_point_keywords.kdl ├── hash_in_id_fail.kdl ├── hex.kdl ├── hex_int.kdl ├── hex_int_underscores.kdl ├── hex_leading_zero.kdl ├── illegal_char_in_binary_fail.kdl ├── illegal_char_in_hex_fail.kdl ├── illegal_char_in_octal_fail.kdl ├── initial_slashdash.kdl ├── int_multiple_underscore.kdl ├── just_block_comment.kdl ├── just_child.kdl ├── just_newline.kdl ├── just_node_id.kdl ├── just_space.kdl ├── just_space_in_arg_type_fail.kdl ├── just_space_in_node_type_fail.kdl ├── just_space_in_prop_type_fail.kdl ├── just_type_no_arg_fail.kdl ├── just_type_no_node_id_fail.kdl ├── just_type_no_prop_fail.kdl ├── leading_newline.kdl ├── leading_zero_binary.kdl ├── leading_zero_int.kdl ├── leading_zero_oct.kdl ├── legacy_raw_string_fail.kdl ├── legacy_raw_string_hash_fail.kdl ├── multiline_comment.kdl ├── multiline_nodes.kdl ├── multiline_raw_string.kdl ├── multiline_raw_string_containing_quotes.kdl ├── multiline_raw_string_empty.kdl ├── multiline_raw_string_empty_indented.kdl ├── multiline_raw_string_indented.kdl ├── multiline_raw_string_non_matching_prefix_character_error_fail.kdl ├── multiline_raw_string_non_matching_prefix_count_error_fail.kdl ├── multiline_raw_string_single_line_err_fail.kdl ├── multiline_raw_string_single_quote_err_fail.kdl ├── multiline_string.kdl ├── multiline_string_containing_quotes.kdl ├── multiline_string_double_backslash.kdl ├── multiline_string_empty.kdl ├── multiline_string_empty_indented.kdl ├── multiline_string_escape_delimiter.kdl ├── multiline_string_escape_in_closing_line.kdl ├── multiline_string_escape_in_closing_line_shallow.kdl ├── multiline_string_escape_newline_at_end.kdl ├── multiline_string_escape_newline_at_end_fail.kdl ├── multiline_string_final_whitespace_escape_fail.kdl ├── multiline_string_indented.kdl ├── multiline_string_non_literal_prefix_fail.kdl ├── multiline_string_non_matching_prefix_character_error_fail.kdl ├── multiline_string_non_matching_prefix_count_error_fail.kdl ├── multiline_string_single_line_err_fail.kdl ├── multiline_string_single_quote_err_fail.kdl ├── multiline_string_whitespace_only.kdl ├── multiple_dots_in_float_before_exponent_fail.kdl ├── multiple_dots_in_float_fail.kdl ├── multiple_es_in_float_fail.kdl ├── multiple_x_in_hex_fail.kdl ├── negative_exponent.kdl ├── negative_float.kdl ├── negative_int.kdl ├── nested_block_comment.kdl ├── nested_children.kdl ├── nested_comments.kdl ├── nested_multiline_block_comment.kdl ├── newline_between_nodes.kdl ├── newlines_in_block_comment.kdl ├── no_decimal_exponent.kdl ├── no_digits_in_hex_fail.kdl ├── no_integer_digit_fail.kdl ├── no_solidus_escape_fail.kdl ├── node_false.kdl ├── node_true.kdl ├── node_type.kdl ├── null_arg.kdl ├── null_prefix_in_bare_id.kdl ├── null_prefix_in_prop_key.kdl ├── null_prop.kdl ├── null_prop_key_fail.kdl ├── numeric_arg.kdl ├── numeric_prop.kdl ├── octal.kdl ├── only_cr.kdl ├── only_line_comment.kdl ├── only_line_comment_crlf.kdl ├── only_line_comment_newline.kdl ├── optional_child_semicolon.kdl ├── parens_in_bare_id_fail.kdl ├── parse_all_arg_types.kdl ├── positive_exponent.kdl ├── positive_int.kdl ├── preserve_duplicate_nodes.kdl ├── preserve_node_order.kdl ├── prop_false_type.kdl ├── prop_float_type.kdl ├── prop_hex_type.kdl ├── prop_identifier_type.kdl ├── prop_null_type.kdl ├── prop_raw_string_type.kdl ├── prop_string_type.kdl ├── prop_true_type.kdl ├── prop_type.kdl ├── prop_zero_type.kdl ├── question_mark_before_number.kdl ├── quote_in_bare_id_fail.kdl ├── quoted_arg_type.kdl ├── quoted_node_name.kdl ├── quoted_node_type.kdl ├── quoted_numeric.kdl ├── quoted_prop_name.kdl ├── quoted_prop_type.kdl ├── r_node.kdl ├── raw_arg_type.kdl ├── raw_node_name.kdl ├── raw_node_type.kdl ├── raw_prop_type.kdl ├── raw_string_arg.kdl ├── raw_string_backslash.kdl ├── raw_string_hash_no_esc.kdl ├── raw_string_just_backslash.kdl ├── raw_string_just_quote_fail.kdl ├── raw_string_multiple_hash.kdl ├── raw_string_newline.kdl ├── raw_string_prop.kdl ├── raw_string_quote.kdl ├── repeated_arg.kdl ├── repeated_prop.kdl ├── same_name_nodes.kdl ├── sci_notation_large.kdl ├── sci_notation_small.kdl ├── semicolon_after_child.kdl ├── semicolon_in_child.kdl ├── semicolon_separated.kdl ├── semicolon_separated_nodes.kdl ├── semicolon_terminated.kdl ├── single_arg.kdl ├── single_prop.kdl ├── slash_in_bare_id_fail.kdl ├── slashdash_after_arg_type_fail.kdl ├── slashdash_after_node_type_fail.kdl ├── slashdash_after_prop_key_fail.kdl ├── slashdash_after_prop_val_type_fail.kdl ├── slashdash_after_type_fail.kdl ├── slashdash_arg_after_newline_esc.kdl ├── slashdash_arg_before_newline_esc.kdl ├── slashdash_before_children_end_fail.kdl ├── slashdash_before_eof_fail.kdl ├── slashdash_before_prop_value_fail.kdl ├── slashdash_before_semicolon_fail.kdl ├── slashdash_between_child_blocks_fail.kdl ├── slashdash_child.kdl ├── slashdash_child_block_before_entry_err_fail.kdl ├── slashdash_empty_child.kdl ├── slashdash_escline_before_arg_type.kdl ├── slashdash_escline_before_children.kdl ├── slashdash_escline_before_node.kdl ├── slashdash_false_node.kdl ├── slashdash_full_node.kdl ├── slashdash_in_slashdash.kdl ├── slashdash_inside_arg_type_fail.kdl ├── slashdash_inside_node_type_fail.kdl ├── slashdash_multi_line_comment_entry.kdl ├── slashdash_multi_line_comment_inline.kdl ├── slashdash_multiple_child_blocks.kdl ├── slashdash_negative_number.kdl ├── slashdash_newline_before_children.kdl ├── slashdash_newline_before_entry.kdl ├── slashdash_newline_before_node.kdl ├── slashdash_node_in_child.kdl ├── slashdash_node_with_child.kdl ├── slashdash_only_node.kdl ├── slashdash_only_node_with_space.kdl ├── slashdash_prop.kdl ├── slashdash_raw_prop_key.kdl ├── slashdash_repeated_prop.kdl ├── slashdash_single_line_comment_entry.kdl ├── slashdash_single_line_comment_node.kdl ├── space_after_arg_type.kdl ├── space_after_node_type.kdl ├── space_after_prop_type.kdl ├── space_around_prop_marker.kdl ├── space_in_arg_type.kdl ├── space_in_node_type.kdl ├── space_in_prop_type.kdl ├── square_bracket_in_bare_id_fail.kdl ├── string_arg.kdl ├── string_escaped_literal_whitespace.kdl ├── string_prop.kdl ├── tab_space.kdl ├── trailing_crlf.kdl ├── trailing_underscore_hex.kdl ├── trailing_underscore_octal.kdl ├── true_prefix_in_bare_id.kdl ├── true_prefix_in_prop_key.kdl ├── true_prop_key_fail.kdl ├── two_nodes.kdl ├── type_before_prop_key_fail.kdl ├── unbalanced_raw_hashes_fail.kdl ├── underscore_at_start_of_fraction_fail.kdl ├── underscore_at_start_of_hex_fail.kdl ├── underscore_before_number.kdl ├── underscore_in_exponent.kdl ├── underscore_in_float.kdl ├── underscore_in_fraction.kdl ├── underscore_in_int.kdl ├── underscore_in_octal.kdl ├── unicode_delete_fail.kdl ├── unicode_escaped_h1_fail.kdl ├── unicode_escaped_h2_fail.kdl ├── unicode_escaped_h3_fail.kdl ├── unicode_escaped_h4_fail.kdl ├── unicode_escaped_l1_fail.kdl ├── unicode_escaped_l2_fail.kdl ├── unicode_escaped_l3_fail.kdl ├── unicode_fsi_fail.kdl ├── unicode_lre_fail.kdl ├── unicode_lri_fail.kdl ├── unicode_lrm_fail.kdl ├── unicode_lro_fail.kdl ├── unicode_pdf_fail.kdl ├── unicode_pdi_fail.kdl ├── unicode_rle_fail.kdl ├── unicode_rli_fail.kdl ├── unicode_rlm_fail.kdl ├── unicode_rlo_fail.kdl ├── unicode_silly.kdl ├── unicode_under_0x20_fail.kdl ├── unterminated_empty_node_fail.kdl ├── unusual_bare_id_chars_in_quoted_id.kdl ├── unusual_chars_in_bare_id.kdl ├── vertical_tab_whitespace.kdl ├── zero_float.kdl ├── zero_int.kdl ├── zero_space_before_first_arg_fail.kdl ├── zero_space_before_prop_fail.kdl ├── zero_space_before_second_arg_fail.kdl └── zero_space_before_slashdash_arg_fail.kdl /.gitignore: -------------------------------------------------------------------------------- 1 | secrets.json 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | pip-wheel-metadata/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 97 | __pypackages__/ 98 | 99 | # Celery stuff 100 | celerybeat-schedule 101 | celerybeat.pid 102 | 103 | # SageMath parsed files 104 | *.sage.py 105 | 106 | # Environments 107 | .env 108 | .venv 109 | env/ 110 | venv/ 111 | ENV/ 112 | env.bak/ 113 | venv.bak/ 114 | 115 | # Spyder project settings 116 | .spyderproject 117 | .spyproject 118 | 119 | # Rope project settings 120 | .ropeproject 121 | 122 | # mkdocs documentation 123 | /site 124 | 125 | # mypy 126 | .mypy_cache/ 127 | .dmypy.json 128 | dmypy.json 129 | 130 | # Pyre type checker 131 | .pyre/ 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Tab Atkins Jr. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include kdl/py.typed -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KDL-py 2 | 3 | A handwritten Python 3.7+ implemenation of a parser 4 | for the [KDL Document Language](https://kdl.dev), 5 | fully compliant with KDL 2.0.0. 6 | 7 | [KDL](https://kdl.dev) is, as the name suggests, a document language, 8 | filling approximately the same niche as JSON/YAML/XML/etc 9 | to be a simple but powerful language for config files. 10 | It combines the best of several of these languages, 11 | while avoiding their pitfalls: 12 | more general than JSON and more powerful than XML, 13 | while avoiding the verbosity of XML 14 | or the explosive complexity of YAML. 15 | 16 | kdl-py, in particular, is focused on *ease-of-use*, 17 | supporting things like date/times, ip addresses, urls, uuids, regexes, and binary data 18 | directly in your KDL document 19 | (via powerful but simple tagged values), 20 | and parsing them into native Python types automatically, 21 | or doing the reverse and letting you build KDL document trees 22 | with these values directly, 23 | and automatically and safely serializing them into KDL text 24 | for later parsing! 25 | 26 | You can customize parsing and serialization further for your application very easily, 27 | by providing node or value "converters" 28 | to turn plain KDL values or nodes 29 | into application-specific types, 30 | and then turning them back into KDL text automatically 31 | merely by adding a `.to_kdl()` method to your classes. 32 | 33 | ## Installing 34 | 35 | ```sh 36 | pipx install kdl-py 37 | ``` 38 | 39 | When installed, a `kdlreformat` command-line program is also made available, 40 | which can canonicalize a KDL document. See [below](#kdlreformat) for options. 41 | 42 | ## Using 43 | 44 | The `kdl.parse(str, parseConfig|None)` function parses, you guessed it, a string of KDL into a KDL document object: 45 | 46 | ```py3 47 | >>> import kdl 48 | >>> doc = kdl.parse(''' 49 | ... node_name arg { 50 | ... child_node foo=1 bar=#true 51 | ... } 52 | ... ''') 53 | >>> 54 | >>> doc 55 | Document( 56 | nodes=[ 57 | Node( 58 | name='node', 59 | args=['arg'], 60 | nodes=[ 61 | Node( 62 | name='child', 63 | props=OrderedDict([ 64 | ('foo', 1.0), 65 | ('bar', True) 66 | ]) 67 | ) 68 | ] 69 | ) 70 | ] 71 | ) 72 | ``` 73 | 74 | You can also create a `kdl.Parser()` object and call its `.parse()` method; `Parser` objects can set up parsing and printing options that'll apply by default. See below for how to configure parsing options. 75 | 76 | Either way, you'll get back a `kdl.Document` object, which is fully mutable. By default, untagged KDL values are represented with native Python objects. 77 | 78 | ```py3 79 | >>> doc.nodes[0].nodes[0].props["foo"] = 2 80 | >>> 81 | >>> print(doc) 82 | node_name arg { 83 | child_node foo=2 bar=#true 84 | } 85 | 86 | ``` 87 | 88 | Stringifying a `kdl.Document` object will produce a valid KDL document back. You can also call `doc.print(printConfig|None)` to customize the printing with a `PrintConfig` object, described below. See below for how to configure printing options. 89 | 90 | ### Inserting Native Values 91 | 92 | kdl-py allows a number of native Python objects to be used directly in KDL documents by default, 93 | and allows you to customize your own objects for use. 94 | 95 | kdl-py automatically recognizes and correctly serializes the following objects: 96 | 97 | * `bool`: as untagged `true` or `false` 98 | * `None`: as untagged `null` 99 | * `int`, `float`: as untagged decimal number 100 | * `str`: as untagged string 101 | * `bytes`: as `(base64)`-tagged string 102 | * `decimal.Decimal`: as `(decimal)`-tagged string 103 | * `datetime`, `date`, and `time`: as `(date-time)`, `(date)`, or `(time)`-tagged strings 104 | * `ipaddress.IPv4Address` and `ipaddress.IPv6Address`: as `(ipv4)` or `(ipv6)`-tagged strings 105 | * `urllib.parse.ParseResult` (the result of calling `urllib.parse.urlparse()`): as `(url)`-tagged string 106 | * `uuid.UUID`: as `(uuid)`-tagged string 107 | * `re.Pattern` (the result of calling `re.compile()`): as `(regex)`-tagged raw string 108 | 109 | All of the tags used above are reserved and predefined by the [KDL specification](https://github.com/kdl-org/kdl/blob/main/SPEC.md#reserved-type-annotations-for-numbers-without-decimals). 110 | 111 | In addition, any value with a `.to_kdl()` method 112 | can be used in a kdl-py document. 113 | The method will be called when the document is stringified, 114 | and must return one of the kdl-py types, 115 | or any of the native types defined above. 116 | 117 | (For *parsing* KDL into these native types, 118 | or your own types, 119 | see the `ParseConfig` section, below.) 120 | 121 | ## Customizing Parsing 122 | 123 | Parsing can be controlled via a `kdl.ParseConfig` object, 124 | which can be provided in three ways. 125 | In order of importance: 126 | 127 | 1. Passing a `ParseConfig` object to `kdl.parse(str, ParseConfig|None)` 128 | or `parser.parse(str, ParseConfig|None)` 129 | (if you've constructed a `kdl.Parser`). 130 | 2. Creating a `kdl.Parser(parseConfig|None, printConfig|None)`, 131 | which automatically applies it to its `.parse()` method if not overriden. 132 | 3. Fiddling with the `kdl.parsing.defaults` object, 133 | which is used if nothing else provides a config. 134 | 135 | A `ParseConfig` object has the following properties: 136 | 137 | * `nativeUntaggedValues: bool = True` 138 | 139 | Controls whether the parser produces native Python objects (`str`, `int`, `float`, `bool`, `None`) when parsing untagged values (those without a `(foo)` prefix), or always produces kdl-py objects (such as `kdl.String`, `kdl.Decimal`, etc). 140 | 141 | * `nativeTaggedValues: bool = True` 142 | 143 | Controls whether the parser produces native Python objects 144 | when parsing *tagged* values, 145 | for some of [KDL's predefined tags](https://github.com/kdl-org/kdl/blob/main/SPEC.md#reserved-type-annotations-for-numbers-without-decimals): 146 | 147 | * `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64` on numbers: 148 | Checks that the value is in the specified range, 149 | then converts it to an `int`. 150 | (It will serialize back out as an ordinary untagged number.) 151 | * `f32`, `f64` on numbers: 152 | Converts it to a `float`. 153 | (It will serialize back out as an ordinary untagged number.) 154 | * `decimal64`, `decimal128` on numbers, and `decimal` on strings: 155 | Converts it to a `decimal.Decimal` object. 156 | (Always reserializes to a `(decimal)`-tagged string.) 157 | * `date-time`, `date`, `time` on strings: 158 | Converts to a `datetime`, `time`, or `date` object. 159 | * `ipv4`, `ipv6` on strings: 160 | Converts it to an `ipaddress.IPv4Address` or `ipaddress.IPv6Address` object. 161 | * `url` on strings: 162 | Converts it to a `urllib.parse.ParseResult` tuple. 163 | * `uuid` on strings: 164 | Converts it to a `uuid.UUID` object. 165 | * `regex` on strings: 166 | Converts it to a `re.Pattern` object. 167 | (It will serialize back out as a raw string.) 168 | * `base64` on strings: 169 | Converts it to a `bytes` object. 170 | 171 | 172 | * `valueConverters: Dict[ValueKey, Callable] = {}` 173 | 174 | A dictionary of ValueKey->converter functions, 175 | letting you parse values 176 | (like `(date)"2021-01-01"`) 177 | into whatever types you'd like. 178 | 179 | Whenever the parser encounters a value, 180 | it will attempt to find an entry in this dict 181 | whose [`ValueKey`](#ValueKey) matches the value. 182 | If it succeeds, 183 | it will call the associated converter function with two arguments: 184 | the fully-constructed kdl-py object, 185 | and a `ParseFragment` object giving you access 186 | to the precise characters parsed from the document 187 | (for the value; the tag, if any, won't be included, as you can get it from the object itself). 188 | Whatever you return will be inserted into the document 189 | instead of the originally-parsed value. 190 | 191 | You can produce KDL values 192 | (such as parsing `(hex)"0x12.e5"` into a `kdl.Decimal`, 193 | since KDL doesn't support fractional hex values), 194 | or produce any other Python type. 195 | If you return a non-KDL type, 196 | you probably want to ensure it has a `.to_kdl()` method 197 | (or is one of the supported built-in types), 198 | so it can be serialized back into a KDL document. 199 | 200 | Note that only *one* conversion can happen to a given value. 201 | Your converters are checked 202 | in the dictionary's iteration order, 203 | then if none of them succeeded 204 | it will attempt to run the `nativeUntaggedValues` or `nativeTaggedValues` behaviors, 205 | if they're turned on. 206 | If a converter returns `NotImplemented`, 207 | it will continue looking for a matching converter. 208 | 209 | 210 | * `nodeConverters: Dict[NodeKey, Callable] = {}` 211 | 212 | Similar to `valueConverters`, 213 | except it uses [`NodeKey`s](#NodeKey), 214 | and it converts `kdl.Node`s instead. 215 | 216 | There is no native conversion of nodes; 217 | if none of your converters successfully run, 218 | the node will be inserted as-is. 219 | 220 | 221 | ### ParseFragment 222 | 223 | `kdl.ParseFragment` is passed to your custom converters, 224 | specified in `kdl.ParseConfig.tags`, 225 | giving you direct access to the input characters 226 | before any additional processing was done on them. 227 | This is useful, for example, 228 | to handle numeric types 229 | that might have lost precision in the normal parse. 230 | 231 | It exposes a `.fragment` property, 232 | containing the raw text of the value 233 | (after the tag, if any). 234 | 235 | It also exposes a `.error(str)` method, 236 | which takes a custom error message 237 | and returns a `kdl.ParseError` 238 | with the `ParseFragment`'s location already built in, 239 | ready for you to `raise`. 240 | This should be used if your conversion fails for any reason, 241 | so your errors look the same as native parse errors. 242 | 243 | ## Customizing Printing 244 | 245 | Like parsing, printing a kdl-py `Document` back to a KDL string can be controlled by a `kdl.PrintConfig` object, 246 | which can be provided in three ways. 247 | In order of importance: 248 | 249 | 1. Passing a `PrintConfig` object to `doc.print(PrintConfig|None)`. 250 | 2. Setting `doc.printConfig` to a `PrintConfig`. 251 | (This is done automatically for any documents produced by a `Parser`, 252 | if you pass the `printConfig` option to the constructor.) 253 | 3. Fiddling with the `kdl.printing.defaults` object, 254 | which is used if nothing else provides a config. 255 | 256 | A `PrintConfig` object has the following properties: 257 | 258 | * `indent: str = "\t"` 259 | 260 | The string used for each indent level. 261 | Defaults to tabs, 262 | but can be set to a sequence of spaces if desired 263 | (or anything else). 264 | 265 | * `semicolons: bool = False` 266 | 267 | Whether or not nodes are ended with semicolons. 268 | (The printer always ends nodes with a newline anyway, 269 | so this is purely a stylistic choice.) 270 | 271 | * `printNullArgs: bool = True` 272 | 273 | When `False`, automatically skips over any "null"/`None` arguments. 274 | This will corrupt documents that use the "null" keyword intentionally, 275 | but can be useful if you'd prefer to use a `None` value 276 | as a signal that the argument has been removed. 277 | 278 | * `printNullProps: bool = True` 279 | 280 | Identical to `printNullArgs`, 281 | but applies to properties rather than arguments. 282 | 283 | * `respectStringType: bool = True` 284 | 285 | When `True`, the printer will output strings as the same type they were in the input, 286 | either raw (`r#"foo"#`) or normal (`"foo"`). 287 | When `False`, the printer always outputs normal strings. 288 | 289 | Note that this only has an effect on `kdl.String` and `kdl.RawString` objects; 290 | if the document contains Python `str` objects, 291 | they will always output as normal strings. 292 | 293 | * `respectRadix: bool = True` 294 | 295 | Similar to `respectStringType`, 296 | when `True` the printer will output numbers as the radix they were in the input, 297 | like `0x1b` for hex numbers. 298 | When `False`, the printer always outputs decimal numbers. 299 | 300 | Again, this only has an effect on kdl-py objects; 301 | native Python numbers are printed as normal for Python. 302 | 303 | * `exponent: str = "e"` 304 | 305 | What character to use for the exponent part of decimal numbers, 306 | when printed with scientific notation. 307 | Should only be set to "e" or "E". 308 | 309 | Like the previous options, this only has an effect on kdl-py objects; 310 | native Python numbers are printed as normal for Python. 311 | 312 | ## Full API Reference 313 | 314 | * `kdl.parse(str, config: kdl.ParseConfig|None) -> kdl.Document` 315 | * `kdl.Parser(parseConfig: kdl.ParseConfig|None, printConfig: kdl.PrintConfig|None)` 316 | * `parser.parse(str, config: kdl.ParseConfig|None) -> kdl.Document` 317 | * `parser.print(config: kdl.PrintConfig|None) -> str` 318 | * `kdl.Document(nodes: list[kdl.Node]?, printConfig: kdl.PrintConfig|None)` 319 | * `doc.print(PrintConfig|None) -> str` 320 | * `doc[NodeKey] -> Node` returns the first child node matching the [`NodeKey`](#NodeKey). Raises a `KeyError` if nothing matches the `NodeKey`, similar to a `dict`. 321 | * `doc.get(NodeKey, default: T = None) -> kdl.Node | T` returns the first child node matching the [`NodeKey`](#NodeKey). Returns the default value if nothing matches. 322 | * `doc.getAll(NodeKey) -> Iterable[kdl.Node]` returns all child nodes matching the [`NodeKey`](#NodeKey) 323 | * `kdl.Node(name: str, tag: str|None, args: list[Any]?, props: dict[str, Any]?, nodes: list[kdl.Node]?)` 324 | * `node[NodeKey] -> Node` returns the first child node matching the [`NodeKey`](#NodeKey). Raises a `KeyError` if nothing matches the `NodeKey`, similar to a `dict`. 325 | * `node.get(NodeKey, default: T = None) -> kdl.Node | T` returns the first child node matching the [`NodeKey`](#NodeKey). Returns the default value if nothing matches. 326 | * `node.getAll(NodeKey) -> Iterable[kdl.Node]` returns all child nodes matching the [`NodeKey`](#NodeKey) 327 | * `node.getProps(ValueKey) -> Iterable[tuple[str, Any]]` returns an iterator of `(name, value)` pairs for the properties whose value matches the [`ValueKey`](#ValueKey) 328 | (Note: for this purpose, non-KDL values, such as `int`, have no tag, and can only meaningfully be tested via a `TypeKey`.) 329 | * `node.getArgs(ValueKey) -> Iterable[Any]` returns an iterator of the arguments that match the [`ValueKey`](#ValueKey) 330 | (Same disclaimer as `.getProps()`.) 331 | * `node.matchesKey(NodeKey) -> bool` returns whether the node matches the [`NodeKey`](#NodeKey) 332 | 333 | * `kdl.Value` ‡ 334 | * `val.matchesKey(ValueKey) -> bool` returns whether the value matches the [`ValueKey`](#ValueKey) 335 | * `kdl.Binary(value: int, tag: str|None)` 336 | * `kdl.Octal(value: int, tag: str|None)` 337 | * `kdl.Decimal(mantissa: int|float, exponent: int|None, tag: str|None)` 338 | * `dec.value`: readonly, `mantissa * (10**exponent)` 339 | * `kdl.Hex(value: int, tag: str|None)` 340 | * `kdl.Bool(value: bool, tag: str|None)` 341 | * `kdl.Null(tag: str|None)` 342 | * `null.value`: readonly, always `None` 343 | * `kdl.RawString(value: str, tag: str|None)` 344 | * `kdl.String(value: str, tag: str|None)` 345 | * `kdl.ExactValue(chars: str, tag: str|None)` † 346 | * `kdl.Numberish`, `kdl.Stringish` ‡ 347 | * `kdl.ParseConfig(...)` see above for options 348 | * `kdl.parsing.defaults`: default `ParseConfig` 349 | * `kdl.PrintConfig(...)` see above for options 350 | * `kdl.printing.defaults`: default `PrintConfig` 351 | * `kdl.ParseError`: thrown for all parsing errors 352 | * `error.msg: str`: hopefully informative 353 | * `error.line: int`: 1-indexed 354 | * `error.col: int`: 1-indexed 355 | * `kdl.ParseFragment`: passed to converter functions 356 | * `pf.fragment`: slice from the source string 357 | * `pf.error(msg: str)` returns a `kdl.ParseError` with error location set properly already 358 | * `kdl.nodeMatchesKey(val: Any, key: kdl.NodeKey) -> bool` 359 | * `kdl.valueMatchesKey(val: Any, key: kdl.ValueKey) -> bool` 360 | * `kdl.tagMatchesKey(val: str|None, key: kdl.TagKey) -> bool` 361 | * `kdl.nameMatchesKey(val: str|None, key: kdl.NameKey) -> bool` 362 | * `kdl.typeMatchesKey(val: str|None, key: kdl.TypeKey) -> bool` 363 | * Functions implementing the tag/name/type matching 364 | used by the `node.matchesKey()` and `value.matchesKey()` methods, 365 | in case you want to use the same filtering yourself. 366 | 367 | † Not produced by the parser. 368 | Can be returned by a user's `.to_kdl()` method 369 | if they want to produce a value *precisely* in a particular syntax, 370 | in a way that the built-in kdl-py classes don't. 371 | 372 | ‡ Not produced by the parser. 373 | These are abstract base classes to help in type testing: 374 | `Value` matches all eight value classes, 375 | `Numberish` matches all four numeric value classes, 376 | and `Stringish` matches both string value classes. 377 | 378 | A few type aliases also exist, 379 | used by the module in a few places 380 | and potentially useful for your code: 381 | 382 | * `kdl.KDLAny`: a `Document`, `Node`, or any of the `Value` subtypes 383 | * `kdl.KDLValue`: any of the `Value` subtypes 384 | * `kdl.KDLishValue`: a `KDLValue` or one of the supported Python native types [see "Inserting Native Types"](#inserting-native-types) 385 | * `kdl.ValueKey`, `kdl.NodeKey`, `kdl.TagKey`, `kdl.NameKey`, `kdl.TypeKey`: 386 | the types for [`ValueKey`s](#ValueKey) and [`NodeKey`s](#NodeKey) 387 | (and their individual pieces) 388 | 389 | These aliases only exist when `typing.TYPE_CHECKING` is true, 390 | so they're *only* useful for writing types; 391 | they won't be visible at runtime. 392 | 393 | ### `NodeKey` 394 | 395 | A few data structures and functions take a `NodeKey` 396 | to match against a node, 397 | based on its name and/or tag. 398 | 399 | A `NodeKey` is either a `NameKey` or a `(TagKey, NameKey)` tuple, 400 | matching against the node's name and/or tag. 401 | 402 | `NameKey`s and `TagKey`s can be: 403 | 404 | * `None`: 405 | When matched against a tag, only succeeds against a `None` tag 406 | (aka a tagless node like `foo`). 407 | When matched against a name, automatically succeeds, 408 | since nodes are guaranteed to have a name. 409 | * `...`: 410 | Always succeeds. 411 | Use this when, say, 412 | you want to match against a particular tag, regardless of the nodename, 413 | like `("my-tag", ...)`. 414 | * a `str`: 415 | Succeeds if the tag/name is that exact string. 416 | * a `re.Pattern` (a regex, such as `re.compile(r".*foo")`: 417 | Succeeds if the regex matches the tag/name. 418 | Note that this uses `.match()` semantics, 419 | automatically anchoring against the start of the string; 420 | prepend your regex with `.*?` if you want it to match anywhere. 421 | * a function, taking a `str | None` and returning a `bool`: 422 | Succeeds if the function, 423 | when called with the tag/name, 424 | returns True. 425 | 426 | So, for example, 427 | `doc.getAll("foo")` would return all nodes whose name is "foo", 428 | regardless of tag. 429 | `doc.getAll(("my-tag", ...))` would return all nodes whose tag is "my-tag", 430 | regardless of the node name. 431 | `doc.getAll(re.compile(r"-"))` would return all nodes whose name starts with "-". 432 | Etc. 433 | 434 | ### `ValueKey` 435 | 436 | Similarly to `NodeKey`, a few things take a `ValueKey` 437 | to match against values, 438 | based on its tag and/or type. 439 | 440 | A `ValueKey` is either a `TagKey` or a `(TagKey, TypeKey)` tuple, 441 | matching against the value's tag and/or type. 442 | 443 | `TagKey` works identically to how it appears in [`NodeKey`](#NodeKey). 444 | `TypeKey` is either `...`, which matches any type, 445 | or the same sort of argument you'd pass as the second argument to `isinstance()`. 446 | 447 | For example, 448 | a `"foo"` key would match any values with the tag "foo", like `(foo)1` or `(foo)"bar"`. 449 | A `(..., kdl.Numberish)` will match any value that's a "number" type: a Hex, Octal, Binary, or Decimal, regardless of its tag. 450 | Etc. 451 | 452 | 453 | ## `kdlreformat` 454 | 455 | The `kdlreformat` command-line program is installed by default 456 | when you install this module from pypi. 457 | It can also be run manually from the `kdlreformat.py` file 458 | at the root of this repository 459 | (or from the `kdl.cli.cli()` function) 460 | 461 | ``` 462 | usage: kdlreformat [-h] [--indent INDENT] [--semicolons] [--radix] 463 | [--no-radix] [--raw-strings] [--no-raw-strings] 464 | [--exponent EXPONENT] 465 | [infile] [outfile] 466 | 467 | KDL parser/printer, letting you easily reformat KDL files into a canonical 468 | representation. 469 | 470 | positional arguments: 471 | infile 472 | outfile 473 | 474 | optional arguments: 475 | -h, --help show this help message and exit 476 | --indent INDENT How many spaces for each level of indent. -1 indicates 477 | to indent with tabs. 478 | --semicolons Whether to end nodes with semicolons or not. 479 | --radix Output numeric values in the radix used by the input. 480 | (0x1a outputs as 0x1a) 481 | --no-radix Convert all numeric arguments to decimal. (0x1a outputs 482 | as 26) 483 | --raw-strings Output string values in the string type used by the 484 | input. 485 | --no-raw-strings Convert all string arguments into plain strings. 486 | --exponent EXPONENT What character to use ('e' or 'E') for indicating 487 | exponents on scinot numbers. 488 | ``` 489 | -------------------------------------------------------------------------------- /kdl/__init__.py: -------------------------------------------------------------------------------- 1 | import typing 2 | 3 | from . import parsing as parsing, printing as printing 4 | from .cli import cli as cli 5 | from .errors import ParseError as ParseError, ParseFragment as ParseFragment 6 | from .parsefuncs import parse as parse 7 | from .parsing import ParseConfig as ParseConfig, Parser as Parser 8 | from .printing import PrintConfig as PrintConfig 9 | from .types import ( 10 | Binary as Binary, 11 | Bool as Bool, 12 | Decimal as Decimal, 13 | Document as Document, 14 | ExactValue as ExactValue, 15 | Hex as Hex, 16 | Node as Node, 17 | Null as Null, 18 | Numberish as Numberish, 19 | Octal as Octal, 20 | RawString as RawString, 21 | String as String, 22 | Stringish as Stringish, 23 | Value as Value, 24 | nameMatchesKey as nameMatchesKey, 25 | tagMatchesKey as tagMatchesKey, 26 | valueMatchesKey as valueMatchesKey, 27 | ) 28 | 29 | if typing.TYPE_CHECKING: 30 | from .t import ( 31 | KDLAny as KDLAny, 32 | KDLishValue as KDLishValue, 33 | KDLValue as KDLValue, 34 | NameKey as NameKey, 35 | NodeKey as NodeKey, 36 | TagKey as TagKey, 37 | TypeKey as TypeKey, 38 | ValueKey as ValueKey, 39 | ) 40 | -------------------------------------------------------------------------------- /kdl/cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | 4 | from . import parsefuncs, parsing, printing 5 | 6 | 7 | def cli() -> None: 8 | cliParser = argparse.ArgumentParser( 9 | description="KDL parser/printer, letting you easily reformat KDL files into a canonical representation.", 10 | ) 11 | cliParser.add_argument( 12 | "infile", 13 | nargs="?", 14 | type=argparse.FileType("r", encoding="utf-8"), 15 | default=sys.stdin, 16 | ) 17 | cliParser.add_argument( 18 | "outfile", 19 | nargs="?", 20 | type=argparse.FileType("w", encoding="utf-8"), 21 | default=sys.stdout, 22 | ) 23 | cliParser.add_argument( 24 | "--indent", 25 | dest="indent", 26 | type=int, 27 | action="store", 28 | default="-1", 29 | help="How many spaces for each level of indent. -1 indicates to indent with tabs.", 30 | ) 31 | cliParser.add_argument( 32 | "--semicolons", 33 | dest="semicolons", 34 | action="store_true", 35 | default=False, 36 | help="Whether to end nodes with semicolons or not.", 37 | ) 38 | cliParser.add_argument( 39 | "--radix", 40 | dest="respectRadix", 41 | action="store_true", 42 | help="Output numeric values in the radix used by the input. (0x1a outputs as 0x1a)", 43 | ) 44 | cliParser.add_argument( 45 | "--no-radix", 46 | dest="respectRadix", 47 | action="store_false", 48 | help="Convert all numeric arguments to decimal. (0x1a outputs as 26)", 49 | ) 50 | cliParser.add_argument( 51 | "--raw-strings", 52 | dest="respectStringType", 53 | action="store_true", 54 | help="Output string values in the string type used by the input.", 55 | ) 56 | cliParser.add_argument( 57 | "--no-raw-strings", 58 | dest="respectStringType", 59 | action="store_false", 60 | help="Convert all string arguments into plain strings.", 61 | ) 62 | cliParser.add_argument( 63 | "--exponent", 64 | dest="exponent", 65 | type=expFromString, 66 | action="store", 67 | default="e", 68 | help="What character to use ('e' or 'E') for indicating exponents on scinot numbers.", 69 | ) 70 | cliParser.set_defaults(respectRadix=True, respectStringType=True) 71 | options = cliParser.parse_args() 72 | parseConfig = parsing.ParseConfig( 73 | nativeUntaggedValues=False, 74 | nativeTaggedValues=False, 75 | ) 76 | printConfig = printing.PrintConfig( 77 | indent=" " * options.indent if options.indent >= 0 else "\t", 78 | semicolons=options.semicolons, 79 | respectRadix=options.respectRadix, 80 | respectStringType=options.respectStringType, 81 | exponent=options.exponent, 82 | ) 83 | 84 | with options.infile as fh: 85 | doc = parsefuncs.parse(fh.read(), parseConfig) 86 | with options.outfile as fh: 87 | fh.write(doc.print(printConfig)) 88 | 89 | 90 | def expFromString(s: str) -> str: 91 | if s in ("e", "E"): 92 | return s 93 | msg = f"Expected 'e' or 'E' for an exponent; got '{s}'" 94 | raise argparse.ArgumentTypeError(msg) 95 | -------------------------------------------------------------------------------- /kdl/converters.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import base64 4 | import datetime 5 | import decimal 6 | import ipaddress 7 | import re 8 | import urllib.parse 9 | import uuid 10 | 11 | from . import t, types 12 | 13 | if t.TYPE_CHECKING: 14 | from .errors import ParseFragment 15 | 16 | 17 | def toNative(val: t.Value, pf: ParseFragment) -> t.KDLishValue: 18 | if isinstance(val, types.Numberish): 19 | if val.tag == "i8": 20 | return i8(val, pf) 21 | if val.tag == "i16": 22 | return i16(val, pf) 23 | if val.tag == "i32": 24 | return i32(val, pf) 25 | if val.tag == "i64": 26 | return i64(val, pf) 27 | if val.tag == "u8": 28 | return u8(val, pf) 29 | if val.tag == "u16": 30 | return u16(val, pf) 31 | if val.tag == "u32": 32 | return u32(val, pf) 33 | if val.tag == "u64": 34 | return u64(val, pf) 35 | if val.tag in ("f32", "f64"): 36 | return int(val.value) 37 | if val.tag in ("decimal64", "decimal128"): 38 | return decim(val, pf) 39 | if isinstance(val, types.Stringish): 40 | if val.tag == "date-time": 41 | return dateTime(val, pf) 42 | if val.tag == "time": 43 | return time(val, pf) 44 | if val.tag == "date": 45 | return date(val, pf) 46 | if val.tag == "decimal": 47 | return decim(val, pf) 48 | if val.tag == "ipv4": 49 | return ipv4(val, pf) 50 | if val.tag == "ipv6": 51 | return ipv6(val, pf) 52 | if val.tag == "url": 53 | return url(val, pf) 54 | if val.tag == "uuid": 55 | return _uuid(val, pf) 56 | if val.tag == "regex": 57 | return regex(val, pf) 58 | if val.tag == "base64": 59 | return b64(val, pf) 60 | return val 61 | 62 | 63 | def i8(val: t.Numberish, pf: ParseFragment) -> int: 64 | limit = 2**7 65 | if not (-limit <= val.value < limit): 66 | msg = f"{val.value} doesn't fit in an i8." 67 | raise pf.error(msg) 68 | return int(val.value) 69 | 70 | 71 | def i16(val: t.Numberish, pf: ParseFragment) -> int: 72 | limit = 2**15 73 | if not (-limit <= val.value < limit): 74 | msg = f"{val.value} doesn't fit in an i16." 75 | raise pf.error(msg) 76 | return int(val.value) 77 | 78 | 79 | def i32(val: t.Numberish, pf: ParseFragment) -> int: 80 | limit = 2**31 81 | if not (-limit <= val.value < limit): 82 | msg = f"{val.value} doesn't fit in an i32." 83 | raise pf.error(msg) 84 | return int(val.value) 85 | 86 | 87 | def i64(val: t.Numberish, pf: ParseFragment) -> int: 88 | limit = 2**63 89 | if not (-limit <= val.value < limit): 90 | msg = f"{val.value} doesn't fit in an i64." 91 | raise pf.error(msg) 92 | return int(val.value) 93 | 94 | 95 | def u8(val: t.Numberish, pf: ParseFragment) -> int: 96 | limit = 2**8 97 | if not (0 <= val.value < limit): 98 | msg = f"{val.value} doesn't fit in a u8." 99 | raise pf.error(msg) 100 | return int(val.value) 101 | 102 | 103 | def u16(val: t.Numberish, pf: ParseFragment) -> int: 104 | limit = 2**16 105 | if not (0 <= val.value < limit): 106 | msg = f"{val.value} doesn't fit in a u16." 107 | raise pf.error(msg) 108 | return int(val.value) 109 | 110 | 111 | def u32(val: t.Numberish, pf: ParseFragment) -> int: 112 | limit = 2**32 113 | if not (0 <= val.value < limit): 114 | msg = f"{val.value} doesn't fit in a u32." 115 | raise pf.error(msg) 116 | return int(val.value) 117 | 118 | 119 | def u64(val: t.Numberish, pf: ParseFragment) -> int: 120 | limit = 2**64 121 | if not (0 <= val.value < limit): 122 | msg = f"{val.value} doesn't fit in a u64." 123 | raise pf.error(msg) 124 | return int(val.value) 125 | 126 | 127 | def decim(val: t.Value, pf: ParseFragment) -> decimal.Decimal: 128 | if isinstance(val, types.Numberish): 129 | chars = pf.fragment.replace("_", "") 130 | else: 131 | chars = val.value 132 | try: 133 | return decimal.Decimal(chars) 134 | except decimal.InvalidOperation as exc: 135 | msg = f"Couldn't parse a decimal from {pf.fragment}." 136 | raise pf.error(msg) from exc 137 | 138 | 139 | def dateTime(val: t.Stringish, pf: ParseFragment) -> datetime.datetime: 140 | try: 141 | return datetime.datetime.fromisoformat(val.value) 142 | except ValueError as exc: 143 | msg = f"Couldn't parse a date-time from {pf.fragment}." 144 | raise pf.error(msg) from exc 145 | 146 | 147 | def time(val: t.Stringish, pf: ParseFragment) -> datetime.time: 148 | try: 149 | return datetime.time.fromisoformat(val.value) 150 | except ValueError as exc: 151 | msg = f"Couldn't parse a date-time from {pf.fragment}." 152 | raise pf.error(msg) from exc 153 | 154 | 155 | def date(val: t.Stringish, pf: ParseFragment) -> datetime.date: 156 | try: 157 | return datetime.date.fromisoformat(val.value) 158 | except ValueError as exc: 159 | msg = f"Couldn't parse a date from {pf.fragment}." 160 | raise pf.error(msg) from exc 161 | 162 | 163 | def ipv4(val: t.Stringish, pf: ParseFragment) -> ipaddress.IPv4Address: 164 | try: 165 | return ipaddress.IPv4Address(val.value) 166 | except ipaddress.AddressValueError as exc: 167 | msg = f"Couldn't parse an IPv4 address from {pf.fragment}." 168 | raise pf.error(msg) from exc 169 | 170 | 171 | def ipv6(val: t.Stringish, pf: ParseFragment) -> ipaddress.IPv6Address: 172 | try: 173 | return ipaddress.IPv6Address(val.value) 174 | except ipaddress.AddressValueError as exc: 175 | msg = f"Couldn't parse an IPv6 address from {pf.fragment}." 176 | raise pf.error(msg) from exc 177 | 178 | 179 | def url(val: t.Stringish, pf: ParseFragment) -> urllib.parse.ParseResult: 180 | try: 181 | return t.cast("urllib.parse.ParseResult", urllib.parse.urlparse(val.value)) 182 | except ValueError as exc: 183 | msg = f"Couldn't parse a url from {pf.fragment}." 184 | raise pf.error(msg) from exc 185 | 186 | 187 | def _uuid(val: t.Stringish, pf: ParseFragment) -> uuid.UUID: 188 | try: 189 | return uuid.UUID(val.value) 190 | except Exception as exc: 191 | msg = f"Couldn't parse a UUID from {pf.fragment}." 192 | raise pf.error(msg) from exc 193 | 194 | 195 | def regex(val: t.Stringish, pf: ParseFragment) -> re.Pattern: 196 | try: 197 | return re.compile(val.value) 198 | except Exception as exc: 199 | msg = f"Couldn't parse a regex from {pf.fragment}." 200 | raise pf.error(msg) from exc 201 | 202 | 203 | def b64(val: t.Stringish, pf: ParseFragment) -> bytes: 204 | try: 205 | return base64.b64decode(val.value.encode("utf-8"), validate=True) 206 | except Exception as exc: 207 | msg = "Couldn't parse base64." 208 | raise pf.error(msg) from exc 209 | -------------------------------------------------------------------------------- /kdl/errors.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from . import t 4 | 5 | 6 | class ParseError(Exception): 7 | def __init__(self, s: t.Stream, i: int, details: str) -> None: 8 | 9 | self.msg = f"{s.loc(i)} {details}" 10 | if len(self.msg) > 78: 11 | self.msg = f"{s.loc(i)}\n {details}" 12 | super().__init__(self.msg) 13 | 14 | 15 | class ParseFragment: 16 | def __init__(self, fragment: str, s: t.Stream, i: int) -> None: 17 | self.fragment = fragment 18 | self._s = s 19 | self._i = i 20 | 21 | def error(self, msg: str) -> ParseError: 22 | return ParseError(self._s, self._i, msg) 23 | -------------------------------------------------------------------------------- /kdl/parsing.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass, field 4 | 5 | from . import parsefuncs, t 6 | 7 | if t.TYPE_CHECKING: 8 | from .errors import ParseFragment 9 | from .types import Node, Value 10 | 11 | ValueConverterT: t.TypeAlias = t.Callable[[Value, ParseFragment], t.Any] 12 | NodeConverterT: t.TypeAlias = t.Callable[[Node, ParseFragment], t.Any] 13 | 14 | 15 | class Parser: 16 | def __init__( 17 | self, 18 | parseConfig: ParseConfig | None = None, 19 | printConfig: t.PrintConfig | None = None, 20 | ) -> None: 21 | self.parseConfig = parseConfig 22 | self.printConfig = printConfig 23 | 24 | def parse(self, chars: str, config: ParseConfig | None = None) -> t.Document: 25 | doc = parsefuncs.parse(chars, config or self.parseConfig or defaults) 26 | doc.printConfig = self.printConfig 27 | return doc 28 | 29 | 30 | @dataclass 31 | class ParseConfig: 32 | nativeUntaggedValues: bool = True 33 | nativeTaggedValues: bool = True 34 | valueConverters: dict[t.ValueKey, ValueConverterT] = field(default_factory=dict) 35 | nodeConverters: dict[t.NodeKey, NodeConverterT] = field( 36 | default_factory=dict, 37 | ) 38 | 39 | 40 | defaults = ParseConfig() 41 | -------------------------------------------------------------------------------- /kdl/printing.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | 4 | @dataclass 5 | class PrintConfig: 6 | indent: str = "\t" 7 | semicolons: bool = False 8 | printNulls: bool = True 9 | respectRadix: bool = True 10 | respectStringType: bool = True 11 | exponent: str = "e" 12 | sortEntries: bool = False 13 | 14 | 15 | defaults = PrintConfig() 16 | -------------------------------------------------------------------------------- /kdl/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tabatkins/kdlpy/d9a220762fb9f55e4f59296256221084c26f54da/kdl/py.typed -------------------------------------------------------------------------------- /kdl/result.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from . import t 6 | 7 | if t.TYPE_CHECKING: 8 | from .stream import Stream 9 | 10 | 11 | class Failure: 12 | pass 13 | 14 | 15 | @dataclass 16 | class ParseFailure(Failure): 17 | details: str 18 | s: Stream 19 | index: int 20 | 21 | def __str__(self) -> str: 22 | return f"{self.s.loc(self.index)} {self.details}" 23 | 24 | 25 | ResultT_co = t.TypeVar("ResultT_co", covariant=True) 26 | 27 | 28 | @dataclass 29 | class Result(t.Generic[ResultT_co]): 30 | value: ResultT_co | None 31 | i: int 32 | err: Failure | None = None 33 | 34 | @property 35 | def valid(self) -> bool: 36 | return self.err is None 37 | 38 | @staticmethod 39 | def fail(index: int) -> Result[ResultT_co]: 40 | return Result(None, index, Failure()) 41 | 42 | @staticmethod 43 | def parseerror(s: Stream, index: int, details: str) -> Result[ResultT_co]: 44 | return Result(None, index, ParseFailure(details, s, index)) 45 | 46 | @property 47 | def vi(self) -> tuple[ResultT_co | None, int]: 48 | # Returns a tuple of the value and index for easy 49 | # destructuring. 50 | # If error, value is None for simple detection; 51 | # use .vie if None is a valid value. 52 | if self.err: 53 | value = None 54 | else: 55 | value = self.value 56 | return (value, self.i) 57 | 58 | @property 59 | def vie(self) -> tuple[ResultT_co | None, int, Failure | None]: 60 | # Like .vi, but returns the error as the third tuple item. 61 | if self.err: 62 | value = None 63 | else: 64 | value = self.value 65 | return (value, self.i, self.err) 66 | -------------------------------------------------------------------------------- /kdl/stream.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | import bisect 5 | import re 6 | 7 | from . import t 8 | 9 | if t.TYPE_CHECKING: 10 | from .result import Result 11 | 12 | 13 | @dataclass 14 | class Stream: 15 | _chars: str 16 | _len: int 17 | _lineBreaks: list[int] 18 | startLine: int 19 | config: t.ParseConfig 20 | 21 | def __init__(self, chars: str, config: t.ParseConfig, startLine: int = 1) -> None: 22 | self._chars = chars 23 | self._len = len(chars) 24 | self._lineBreaks = [] 25 | self.startLine = startLine 26 | self.config = config 27 | for i, char in enumerate(chars): 28 | if char == "\n": 29 | self._lineBreaks.append(i) 30 | 31 | def __getitem__(self, key: int | slice) -> str: 32 | if isinstance(key, int): 33 | if key < 0: 34 | return "" 35 | else: 36 | if key.start < 0: 37 | key = slice(0, key.stop, key.step) 38 | if key.stop < 0: 39 | key = slice(key.start, 0, key.step) 40 | try: 41 | return self._chars[key] 42 | except IndexError: 43 | return "" 44 | 45 | def eof(self, index: int) -> bool: 46 | return index >= self._len 47 | 48 | def __len__(self) -> int: 49 | return self._len 50 | 51 | def line(self, index: int) -> int: 52 | # Zero-based line index 53 | lineIndex = bisect.bisect_left(self._lineBreaks, index) 54 | return lineIndex + self.startLine 55 | 56 | def col(self, index: int) -> int: 57 | lineIndex = bisect.bisect_left(self._lineBreaks, index) 58 | if lineIndex == 0: 59 | return index + 1 60 | startOfCol = self._lineBreaks[lineIndex - 1] 61 | return index - startOfCol 62 | 63 | def loc(self, index: int) -> str: 64 | return f"{self.line(index)}:{self.col(index)}" 65 | 66 | def skipTo(self, start: int, text: str) -> Result[str]: 67 | # Skip forward until encountering `text`. 68 | # Produces the text encountered before this point. 69 | i = start 70 | textLen = len(text) 71 | while not self.eof(i): 72 | if self[i : i + textLen] == text: 73 | break 74 | i += 1 75 | if self[i : i + textLen] == text: 76 | return Result(self[start:i], i) 77 | else: 78 | return Result.fail(start) 79 | 80 | def matchRe(self, start: int, pattern: re.Pattern) -> Result[re.Match]: 81 | match = pattern.match(self._chars, start) 82 | if match: 83 | return Result(match, match.end()) 84 | else: 85 | return Result.fail(start) 86 | 87 | def searchRe(self, start: int, pattern: re.Pattern) -> Result[re.Match]: 88 | match = pattern.search(self._chars, start) 89 | if match: 90 | return Result(match, match.end()) 91 | else: 92 | return Result.fail(start) 93 | -------------------------------------------------------------------------------- /kdl/t.py: -------------------------------------------------------------------------------- 1 | # pylint: skip-file 2 | # ruff: noqa 3 | # Module for holding types, for easy importing into the rest of the codebase 4 | from __future__ import annotations 5 | 6 | from typing import TYPE_CHECKING, cast, Generic, overload, TypeVar 7 | 8 | if TYPE_CHECKING: 9 | import re 10 | import sys 11 | from types import EllipsisType, UnionType 12 | from typing import ( 13 | Any, 14 | Callable, 15 | Iterable, 16 | Literal, 17 | TypeAlias, 18 | ) 19 | 20 | from .types import ( 21 | Binary, 22 | Bool, 23 | Decimal, 24 | Document, 25 | ExactValue, 26 | Hex, 27 | Node, 28 | Null, 29 | Numberish, 30 | Octal, 31 | RawString, 32 | String, 33 | Stringish, 34 | Value, 35 | ) 36 | 37 | from .parsing import ParseConfig 38 | from .printing import PrintConfig 39 | from .stream import Stream 40 | 41 | TagKey = str | None | EllipsisType | re.Pattern | Callable[[str | None], bool] 42 | NameKey = str | None | EllipsisType | re.Pattern | Callable[[str | None], bool] 43 | NodeKey = NameKey | tuple[TagKey, NameKey] 44 | 45 | if sys.version_info >= (3, 10): 46 | _ClassInfo: TypeAlias = type | UnionType | tuple["_ClassInfo", ...] 47 | else: 48 | _ClassInfo: TypeAlias = type | tuple["_ClassInfo", ...] 49 | TypeKey: TypeAlias = EllipsisType | _ClassInfo 50 | ValueKey = TagKey | tuple[TagKey, TypeKey] 51 | 52 | KDLAny: TypeAlias = Document | Node | "KDLValue" 53 | KDLValue: TypeAlias = ( 54 | Value | Binary | Bool | Decimal | ExactValue | Hex | Null | Numberish | Octal | RawString | String | Stringish 55 | ) 56 | 57 | import datetime 58 | import decimal 59 | import ipaddress 60 | import urllib 61 | import uuid 62 | 63 | KDLishValue: TypeAlias = ( 64 | KDLValue 65 | | None 66 | | bool 67 | | String 68 | | int 69 | | float 70 | | decimal.Decimal 71 | | datetime.time 72 | | datetime.date 73 | | datetime.datetime 74 | | ipaddress.IPv4Address 75 | | ipaddress.IPv6Address 76 | | urllib.parse.ParseResult 77 | | uuid.UUID 78 | | re.Pattern 79 | | bytes 80 | ) 81 | -------------------------------------------------------------------------------- /kdl/types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | import re 5 | from abc import ABCMeta, abstractmethod 6 | from dataclasses import dataclass 7 | 8 | from . import printing, t 9 | 10 | if t.TYPE_CHECKING: 11 | VT = t.TypeVar("VT") 12 | LooseEntry = tuple[str | None, t.Any] 13 | 14 | 15 | @dataclass 16 | class Document: 17 | nodes: list[Node] = dataclasses.field(default_factory=list) 18 | printConfig: t.PrintConfig | None = None 19 | 20 | def print(self, config: t.PrintConfig | None = None) -> str: 21 | config = config or self.printConfig or printing.defaults 22 | s = "" 23 | for node in self.nodes: 24 | node = toKdlNode(node) 25 | s += node.print(config, 0) 26 | if s == "": 27 | # always end a kdl doc with a newline 28 | s = "\n" 29 | return s 30 | 31 | @t.overload 32 | def get(self, key: t.NodeKey) -> Node | None: # noqa: F811 33 | ... 34 | 35 | @t.overload 36 | def get(self, key: t.NodeKey, default: VT) -> Node | VT: # noqa: F811 37 | ... 38 | 39 | def get( # noqa: F811 40 | self, 41 | key: t.NodeKey, 42 | default: VT | None = None, 43 | ) -> Node | VT | None: 44 | try: 45 | return self[key] 46 | except KeyError: 47 | return default 48 | 49 | def __getitem__(self, key: t.NodeKey) -> Node: 50 | for node in self.nodes: 51 | if node.matchesKey(key): 52 | return node 53 | raise KeyError(key) 54 | 55 | def getAll( 56 | self, 57 | key: t.NodeKey, 58 | ) -> t.Iterable[Node]: 59 | for node in self.nodes: 60 | if nodeMatchesKey(node, key): 61 | yield node 62 | 63 | def __str__(self) -> str: 64 | return self.print() 65 | 66 | 67 | @dataclass 68 | class Node: 69 | name: str 70 | tag: str | None = None 71 | entries: list[LooseEntry] = dataclasses.field(default_factory=list) 72 | nodes: list[Node] = dataclasses.field(default_factory=list) 73 | 74 | def print( 75 | self, 76 | config: t.PrintConfig | None = None, 77 | indentLevel: int = 0, 78 | ) -> str: 79 | if config is None: 80 | config = printing.defaults 81 | 82 | s = config.indent * indentLevel 83 | 84 | if self.tag is not None: 85 | s += f"({printIdent(self.tag)})" 86 | 87 | s += printIdent(self.name) 88 | 89 | entries: t.Iterable[tuple[str | None, t.Any]] 90 | if config.sortEntries: 91 | entries = sorted(self.entries, key=lambda x: x[0] or "") 92 | else: 93 | entries = self.entries 94 | for name, value in entries: 95 | value = toKdlValue(value) 96 | if not config.printNulls and isinstance(value, Null): 97 | continue 98 | if name is None: 99 | s += f" {value.print(config)}" 100 | else: 101 | s += f" {printIdent(name)}={value.print(config)}" 102 | 103 | if self.nodes: 104 | childrenText = "" 105 | for child in self.nodes: 106 | child = toKdlNode(child) 107 | childrenText += child.print(config=config, indentLevel=indentLevel + 1) 108 | if childrenText: 109 | s += " {\n" 110 | s += childrenText 111 | s += config.indent * indentLevel + "}" 112 | if config.semicolons: 113 | s += ";\n" 114 | else: 115 | s += "\n" 116 | return s 117 | 118 | @t.overload 119 | def get(self, key: t.NodeKey) -> Node | None: # noqa: F811 120 | ... 121 | 122 | @t.overload 123 | def get(self, key: t.NodeKey, default: VT) -> Node | VT: # noqa: F811 124 | ... 125 | 126 | def get( # noqa: F811 127 | self, 128 | key: t.NodeKey, 129 | default: VT | None = None, 130 | ) -> Node | VT | None: 131 | try: 132 | return self[key] 133 | except KeyError: 134 | return default 135 | 136 | def __getitem__(self, key: t.NodeKey) -> Node: 137 | for node in self.nodes: 138 | if node.matchesKey(key): 139 | return node 140 | raise KeyError(key) 141 | 142 | def getAll( 143 | self, 144 | key: t.NodeKey, 145 | ) -> t.Iterable[Node]: 146 | for node in self.nodes: 147 | if nodeMatchesKey(node, key): 148 | yield node 149 | 150 | def matchesKey(self, key: t.NodeKey) -> bool: 151 | return nodeMatchesKey(self, key) 152 | 153 | def getEntries(self, key: t.ValueKey) -> t.Iterable[LooseEntry]: 154 | for name, val in self.entries: 155 | if valueMatchesKey(val, key): 156 | yield name, val 157 | 158 | def getProps(self, key: t.ValueKey) -> t.Iterable[tuple[str, t.Any]]: 159 | for name, val in self.entries: 160 | if name is not None and valueMatchesKey(val, key): 161 | yield name, val 162 | 163 | def getArgs(self, key: t.ValueKey) -> t.Iterable[t.Any]: 164 | for name, val in self.entries: 165 | if name is None and valueMatchesKey(val, key): 166 | yield val 167 | 168 | def __str__(self) -> str: 169 | return self.print() 170 | 171 | 172 | class Value(metaclass=ABCMeta): 173 | value: t.Any 174 | tag: str | None 175 | 176 | @abstractmethod 177 | def print(self, config: t.PrintConfig | None = None) -> str: 178 | pass 179 | 180 | def matchesKey(self, key: t.ValueKey) -> bool: 181 | return valueMatchesKey(self, key) 182 | 183 | 184 | @dataclass 185 | class ExactValue(Value): 186 | # Not produced by anything in the parser, 187 | # but used when a native type needs a precise output 188 | # not captured by the native semantics, 189 | # like precise number formatting. 190 | # .chars *must* be a valid KDL value 191 | chars: str 192 | tag: str | None = None 193 | 194 | def print(self, config: t.PrintConfig | None = None) -> str: 195 | return printTag(self.tag) + self.chars 196 | 197 | def __str__(self) -> str: 198 | return self.print() 199 | 200 | 201 | class Numberish(Value, metaclass=ABCMeta): 202 | pass 203 | 204 | 205 | @dataclass 206 | class Binary(Numberish): 207 | value: int 208 | tag: str | None = None 209 | 210 | def print(self, config: t.PrintConfig | None = None) -> str: 211 | if config is None: 212 | config = printing.defaults 213 | s = printTag(self.tag) 214 | if config.respectRadix: 215 | s += bin(self.value) 216 | else: 217 | s += str(self.value) 218 | return s 219 | 220 | def __str__(self) -> str: 221 | return self.print() 222 | 223 | 224 | @dataclass 225 | class Octal(Numberish): 226 | value: int 227 | tag: str | None = None 228 | 229 | def print(self, config: t.PrintConfig | None = None) -> str: 230 | if config is None: 231 | config = printing.defaults 232 | s = printTag(self.tag) 233 | if config.respectRadix: 234 | s += oct(self.value) 235 | else: 236 | s += str(self.value) 237 | return s 238 | 239 | def __str__(self) -> str: 240 | return self.print() 241 | 242 | 243 | @dataclass 244 | class Decimal(Numberish): 245 | mantissa: int | float 246 | exponent: int = 0 247 | tag: str | None = None 248 | 249 | @property 250 | def value(self) -> float: 251 | return self.mantissa * (10.0**self.exponent) 252 | 253 | def print(self, config: t.PrintConfig | None = None) -> str: 254 | if config is None: 255 | config = printing.defaults 256 | s = printTag(self.tag) + str(self.mantissa) 257 | if self.exponent != 0: 258 | s += config.exponent 259 | if self.exponent > 0: 260 | s += "+" 261 | s += str(self.exponent) 262 | return s 263 | 264 | def __str__(self) -> str: 265 | return self.print() 266 | 267 | 268 | @dataclass 269 | class Infinity(Numberish): 270 | value: float 271 | tag: str | None = None 272 | 273 | def print(self, config: t.PrintConfig | None = None) -> str: 274 | if config is None: 275 | config = printing.defaults 276 | if self.value == float("inf"): 277 | return printTag(self.tag) + "#inf" 278 | else: 279 | return printTag(self.tag) + "#-inf" 280 | 281 | def __str__(self) -> str: 282 | return self.print() 283 | 284 | 285 | @dataclass 286 | class NaN(Numberish): 287 | value: float = float("nan") 288 | tag: str | None = None 289 | 290 | def print(self, config: t.PrintConfig | None = None) -> str: 291 | return printTag(self.tag) + "#nan" 292 | 293 | def __str__(self) -> str: 294 | return self.print() 295 | 296 | 297 | @dataclass 298 | class Hex(Numberish): 299 | value: int 300 | tag: str | None = None 301 | 302 | def print(self, config: t.PrintConfig | None = None) -> str: 303 | if config is None: 304 | config = printing.defaults 305 | s = printTag(self.tag) 306 | if config.respectRadix: 307 | s += hex(self.value) 308 | else: 309 | s += str(self.value) 310 | return s 311 | 312 | def __str__(self) -> str: 313 | return self.print() 314 | 315 | 316 | @dataclass 317 | class Bool(Value): 318 | value: bool 319 | tag: str | None = None 320 | 321 | def print(self, config: t.PrintConfig | None = None) -> str: 322 | if config is None: 323 | config = printing.defaults 324 | if self.value: 325 | return printTag(self.tag) + "#true" 326 | else: 327 | return printTag(self.tag) + "#false" 328 | 329 | def __str__(self) -> str: 330 | return self.print() 331 | 332 | 333 | @dataclass 334 | class Null(Value): 335 | tag: str | None = None 336 | 337 | @property 338 | def value(self) -> None: 339 | return None 340 | 341 | def print(self, config: t.PrintConfig | None = None) -> str: 342 | if config is None: 343 | config = printing.defaults 344 | return printTag(self.tag) + "#null" 345 | 346 | def __str__(self) -> str: 347 | return self.print() 348 | 349 | 350 | class Stringish(Value, metaclass=ABCMeta): 351 | pass 352 | 353 | 354 | @dataclass 355 | class RawString(Stringish): 356 | value: str 357 | tag: str | None = None 358 | 359 | def print(self, config: t.PrintConfig | None = None) -> str: 360 | if config is None: 361 | config = printing.defaults 362 | if config.respectStringType: 363 | hashes = "#" * findRequiredHashCount(self.value) 364 | return f'{printTag(self.tag)}r{hashes}"{self.value}"{hashes}' 365 | else: 366 | return f'{printTag(self.tag)}"{escapedFromRaw(self.value)}"' 367 | 368 | def __str__(self) -> str: 369 | return self.print() 370 | 371 | 372 | def findRequiredHashCount(chars: str) -> int: 373 | for i in range(0, 100): 374 | ender = '"' + ("#" * i) 375 | if ender not in chars: 376 | return i 377 | assert False, "A raw string requires more than 100 hashes???" 378 | 379 | 380 | @dataclass 381 | class String(Stringish): 382 | value: str 383 | tag: str | None = None 384 | multiline: bool = False 385 | 386 | def print(self, config: t.PrintConfig | None = None) -> str: 387 | if config is None: 388 | config = printing.defaults 389 | if self.multiline: 390 | return "" 391 | elif isBareIdent(self.value): 392 | return printTag(self.tag) + self.value 393 | else: 394 | return f'{printTag(self.tag)}"{escapedFromRaw(self.value)}"' 395 | 396 | def __str__(self) -> str: 397 | return self.print() 398 | 399 | 400 | def toKdlNode(val: t.Any) -> Node: 401 | if isinstance(val, Node): 402 | return val 403 | if not callable(getattr(val, "to_kdl", None)): 404 | msg = f"Can't convert object to KDL for serialization. Got:\n{val!r}" 405 | raise Exception( 406 | msg, 407 | ) 408 | node = val.to_kdl() 409 | if not isinstance(node, Node): 410 | msg = f"Expected object to convert to KDL Node. Got:\n{val!r}" 411 | raise Exception(msg) 412 | return node 413 | 414 | 415 | def toKdlValue(val: t.Any) -> t.KDLValue: 416 | """ 417 | Converts any KDLish value (a KDLValue, a primitive, 418 | an object corresponding to a built-in tag, 419 | or an object with .to_kdl() that returns one of the above) 420 | into a KDLValue 421 | """ 422 | import base64 423 | import datetime 424 | import decimal 425 | import ipaddress 426 | import urllib 427 | import uuid 428 | 429 | if isinstance(val, Value): 430 | return val 431 | if val is None: 432 | return Null() 433 | if isinstance(val, bool): 434 | return Bool(val) 435 | if isinstance(val, str): 436 | return String(val) 437 | if isinstance(val, (int, float)): 438 | return Decimal(val) 439 | if isinstance(val, decimal.Decimal): 440 | return String(str(val), "decimal") 441 | if isinstance(val, datetime.datetime): 442 | return String(val.isoformat(), "date-time") 443 | if isinstance(val, datetime.time): 444 | return String(val.isoformat(), "time") 445 | if isinstance(val, datetime.date): 446 | return String(val.isoformat(), "date") 447 | if isinstance(val, ipaddress.IPv4Address): 448 | return String(str(val), "ipv4") 449 | if isinstance(val, ipaddress.IPv6Address): 450 | return String(str(val), "ipv6") 451 | if isinstance(val, urllib.parse.ParseResult): 452 | return String(urllib.parse.urlunparse(val), "url") 453 | if isinstance(val, uuid.UUID): 454 | return String(str(val), "uuid") 455 | if isinstance(val, re.Pattern): 456 | return RawString(val.pattern, "regex") 457 | if isinstance(val, bytes): 458 | return String(base64.b64encode(val).decode("utf-8"), "base-64") 459 | 460 | if not callable(getattr(val, "to_kdl", None)): 461 | msg = f"Can't convert object to KDL for serialization. Got:\n{val!r}" 462 | raise Exception( 463 | msg, 464 | ) 465 | 466 | convertedVal = val.to_kdl() 467 | if isKdlishValue(convertedVal): 468 | return toKdlValue(convertedVal) 469 | else: 470 | msg = f"Expected object to convert to KDL value or compatible primitive. Got:\n{val!r}" 471 | raise Exception(msg) 472 | 473 | 474 | def isKdlishValue(val: t.Any) -> bool: 475 | import datetime 476 | import decimal 477 | import ipaddress 478 | import urllib 479 | import uuid 480 | 481 | if val is None: 482 | return True 483 | return isinstance( 484 | val, 485 | ( 486 | str, 487 | int, 488 | float, 489 | bool, 490 | decimal.Decimal, 491 | datetime.time, 492 | datetime.date, 493 | datetime.datetime, 494 | ipaddress.IPv4Address, 495 | ipaddress.IPv6Address, 496 | urllib.parse.ParseResult, 497 | uuid.UUID, 498 | re.Pattern, 499 | bytes, 500 | Value, 501 | ), 502 | ) 503 | 504 | 505 | def printTag(tag: str | None) -> str: 506 | if tag is not None: 507 | return f"({printIdent(tag)})" 508 | else: 509 | return "" 510 | 511 | 512 | def nodeMatchesKey(node: t.Any, key: t.NodeKey) -> bool: 513 | if not isinstance(node, Node): 514 | node = node.to_kdl() 515 | if isinstance(key, tuple): 516 | tagKey, nameKey = key 517 | return tagMatchesKey(node.tag, tagKey) and nameMatchesKey(node.name, nameKey) 518 | else: 519 | return nameMatchesKey(node.name, key) 520 | 521 | 522 | def valueMatchesKey(value: t.Any, key: t.ValueKey) -> bool: 523 | # Need to allow for both Value and values that were converted to other types 524 | # non-Value objects are untagged, by definition 525 | if isinstance(value, Value): 526 | tag = value.tag 527 | else: 528 | tag = None 529 | if isinstance(key, tuple): 530 | tagKey, typeKey = key 531 | return tagMatchesKey(tag, tagKey) and typeMatchesKey(value, typeKey) 532 | else: 533 | return tagMatchesKey(tag, key) 534 | 535 | 536 | def tagMatchesKey(val: str | None, key: t.TagKey) -> bool: 537 | if key == Ellipsis: 538 | return True 539 | elif key is None: 540 | return val is None 541 | elif isinstance(key, str): 542 | return val == key 543 | elif isinstance(key, re.Pattern): 544 | if val is None: 545 | return False 546 | return bool(key.match(val)) 547 | elif callable(key): 548 | return bool(key(val)) 549 | msg = f"Invalid TagKey {key!r}" 550 | raise Exception(msg) 551 | 552 | 553 | def nameMatchesKey(val: str, key: t.NameKey) -> bool: 554 | if key == Ellipsis: 555 | return True 556 | elif key is None: 557 | return True 558 | elif isinstance(key, str): 559 | return val == key 560 | elif isinstance(key, re.Pattern): 561 | return bool(key.match(val)) 562 | elif callable(key): 563 | return bool(key(val)) 564 | msg = f"Invalid NameKey {key!r}" 565 | raise Exception(msg) 566 | 567 | 568 | def typeMatchesKey(val: Value, key: t.TypeKey) -> bool: 569 | if key == Ellipsis: 570 | return True 571 | try: 572 | return isinstance(val, t.cast("t._ClassInfo", key)) 573 | except Exception as e: 574 | msg = f"Invalid TypeKey {key!r}" 575 | raise Exception(msg) from e 576 | 577 | 578 | def escapedFromRaw(chars: str) -> str: 579 | return ( 580 | chars.replace("\\", "\\\\") 581 | .replace('"', '\\"') 582 | # don't escape a forward slash when printing 583 | .replace("\b", "\\b") 584 | .replace("\f", "\\f") 585 | .replace("\n", "\\n") 586 | .replace("\r", "\\r") 587 | .replace("\t", "\\t") 588 | ) 589 | 590 | 591 | def printIdent(chars: str) -> str: 592 | if isBareIdent(chars): 593 | return chars 594 | return f'"{escapedFromRaw(chars)}"' 595 | 596 | 597 | def isBareIdent(chars: str) -> bool: 598 | if not chars: 599 | return False 600 | if any(not isIdentChar(x) for x in chars): 601 | return False 602 | if chars[0] in "0123456789": 603 | return False 604 | if len(chars) > 1 and chars[0] in "+-" and chars[1] in "0123456789": 605 | return False 606 | if chars.lower() in ("true", "false", "null", "inf", "-inf", "nan"): 607 | return False 608 | return True 609 | 610 | 611 | def isIdentChar(ch: str) -> bool: 612 | if not ch: 613 | return False 614 | # reserved characters 615 | if ch in r"(){}[]/\"#;=": 616 | return False 617 | if isWSChar(ch): 618 | return False 619 | if isNewline(ch): 620 | return False 621 | if isDisallowedLiteral(ch): 622 | return False 623 | return True 624 | 625 | 626 | def isDisallowedLiteral(ch: str) -> bool: 627 | if not ch: 628 | return False 629 | cp = ord(ch) 630 | if 0x0 <= cp <= 0x08: 631 | return True 632 | if 0xE <= cp <= 0x1F: 633 | return True 634 | if cp == 0x7F: 635 | return True 636 | if 0xD800 <= cp <= 0xDFFF: 637 | return True 638 | if 0x200E <= cp <= 0x200F: 639 | return True 640 | if 0x202A <= cp <= 0x202E: 641 | return True 642 | if 0x2066 <= cp <= 0x2069: 643 | return True 644 | if cp == 0xFEFF: 645 | return True 646 | 647 | return False 648 | 649 | 650 | def isWSChar(ch: str) -> bool: 651 | if not ch: 652 | return False 653 | cp = ord(ch) 654 | if cp in (0x9, 0xB, 0x20, 0xA0, 0x1680): 655 | return True 656 | if 0x2000 <= cp <= 0x200A: 657 | return True 658 | if cp in (0x202F, 0x205F, 0x3000): 659 | return True 660 | return False 661 | 662 | 663 | def isNewline(ch: str) -> bool: 664 | if not ch: 665 | return False 666 | cp = ord(ch) 667 | if cp in (0xA, 0xD, 0x85, 0xC, 0x2028, 0x2029): 668 | return True 669 | return False 670 | -------------------------------------------------------------------------------- /kdlreformat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import kdl 4 | 5 | if __name__ == "__main__": 6 | kdl.cli() 7 | -------------------------------------------------------------------------------- /lint: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | echo "¶ Running ruff..." && ruff check --fix kdl && echo "¶ Running black..." && black kdl && echo "¶ Running mypy..." && mypy kdl && echo "¶ Running pylint..." && pylint kdl && echo "✔ All lints passed!" -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | exclude = (build) 3 | files = **/*.py 4 | python_version = 3.10 5 | warn_unused_configs = True 6 | disallow_untyped_defs = True 7 | no_implicit_optional = True 8 | warn_redundant_casts = True 9 | warn_unused_ignores = True 10 | warn_return_any = True 11 | disable_error_code = used-before-def 12 | 13 | [mypy-pygments.*] 14 | ignore_missing_imports = True 15 | 16 | [mypy-lxml.*] 17 | ignore_missing_imports = True 18 | 19 | [mypy-html5lib.*] 20 | ignore_missing_imports = True 21 | 22 | [mypy-PIL.*] 23 | ignore_missing_imports = True 24 | 25 | [mypy-isodate.*] 26 | ignore_missing_imports = True 27 | 28 | [mypy-alive_progress.*] 29 | ignore_missing_imports = True 30 | 31 | [mypy-widlparser.*] 32 | no_implicit_optional = False -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 120 3 | 4 | [tool.pylint."MESSAGES CONTROL"] 5 | disable = [ 6 | "arguments-differ", 7 | "broad-except", 8 | "broad-exception-raised", # Only available in later pylint 9 | "c-extension-no-member", # seems to be weird false pos 10 | "consider-iterating-dictionary", # lol no 11 | "consider-using-f-string", # don't care 12 | "duplicate-code", # dont' care 13 | "eval-used", # needed 14 | "exec-used", # needed 15 | "fixme", 16 | "global-statement", # needed 17 | "import-outside-toplevel", # needed 18 | "inconsistent-return-statements", # don't care 19 | "invalid-name", # SUPER don't care 20 | "keyword-arg-before-vararg", # literally nonsensical 21 | "line-too-long", # black takes care of my line lengths 22 | "missing-class-docstring", 23 | "missing-function-docstring", 24 | "missing-module-docstring", 25 | "missing-timeout", # TODO: fix 26 | "no-else-break", # i prefer this actually 27 | "no-else-continue", # ditto 28 | "no-else-raise", # ditto 29 | "no-else-return", # ditto 30 | "pointless-string-statement", # fine as alt comment syntax 31 | "redefined-builtin", 32 | "superfluous-parens", # don't care 33 | "too-few-public-methods", # dumb 34 | "too-many-arguments", # dumb 35 | "too-many-boolean-expressions", # needed 36 | "too-many-branches", # needed 37 | "too-many-instance-attributes", # dumb 38 | "too-many-lines", 39 | "too-many-locals", # dumb 40 | "too-many-nested-blocks", 41 | "too-many-return-statements", 42 | "too-many-statements", 43 | "unnecessary-lambda", 44 | "unsubscriptable-object", # false positives 45 | "unsupported-binary-operation", # false pos on type sigs, plus mypy catches anyway 46 | "use-dict-literal", # don't care 47 | "useless-import-alias", # need it for rust 48 | "useless-return", # need it for mypy 49 | "cyclic-import", # one single import, not actually a problem 50 | ] 51 | 52 | [tool.ruff] 53 | target-version = "py37" 54 | line-length = 120 55 | 56 | [too.ruff.lint] 57 | ignore = [ 58 | "E501", 59 | # bare except is fine 60 | "E722", 61 | # don't care 62 | "E741", 63 | # don't care 64 | "E743", 65 | # handling unused imports elsewhere 66 | "F401", 67 | # ditto 68 | "F405", 69 | # flake8 doesn't understand typing overloads 70 | "F811", 71 | # caught by pylint and I'm not silencing two things 72 | "F821", 73 | "N802", 74 | "N803", 75 | "N806", 76 | "N812", 77 | "N815", 78 | "N816", 79 | "N999", 80 | # I use Any sparingly and only when necessary already 81 | "ANN401", 82 | # assert is for type annotations 83 | "S101", 84 | # Not doing any secure crypto, just hashing 85 | "S324", 86 | # these are all dumb 87 | "PLR2004", 88 | "PLC1901", 89 | "PLR0911", 90 | "PLR0912", 91 | "PLR0913", 92 | "PLR0915", 93 | "PLR5501", 94 | # I do this on purpose a lot 95 | "PLW2901", 96 | # Disable multiline string concatenation entirely 97 | "ISC003", 98 | # I violate all of these for readability on purpose 99 | "SIM102", 100 | "SIM103", 101 | "SIM108", 102 | "SIM114", 103 | # I have no idea what these are guarding against. 104 | "RUF001", 105 | "RUF002", 106 | "RUF003", 107 | # Nah, I'm fine with it as written. 108 | "RUF005", 109 | # I'm fine with both of these 110 | "S602", 111 | "S607", 112 | ] 113 | select = [ 114 | "ANN", 115 | "E", 116 | "F", 117 | "N", 118 | "W", 119 | "I", 120 | "YTT", 121 | "S", 122 | "PL", 123 | "COM", 124 | "C4", 125 | # Activate later: "DTZ", 126 | "EM", 127 | "EXE", 128 | "INP", 129 | "T20", 130 | "RSE", 131 | "ISC", 132 | "SIM", 133 | # Activate later: "PTH", 134 | # Active later: "TRY", 135 | "RUF" 136 | ] 137 | 138 | [tool.ruff.lint.per-file-ignores] 139 | 140 | [tool.ruff.lint.flake8-implicit-str-concat] 141 | allow-multiline = false 142 | -------------------------------------------------------------------------------- /release.py: -------------------------------------------------------------------------------- 1 | # type: ignore 2 | 3 | import argparse 4 | import json 5 | import os 6 | import subprocess 7 | import sys 8 | 9 | 10 | def createRelease(): 11 | if not inProjectRoot("kdlpy"): 12 | print("Run this command from inside the kdlpy project root folder.") 13 | sys.exit(1) 14 | 15 | treeDirty = ( 16 | subprocess.check_output("git diff --stat", shell=True).decode(encoding="utf-8") 17 | != "" 18 | ) 19 | if treeDirty: 20 | print( 21 | "Working tree is dirty. Finish committing files or stash, then try again.", 22 | ) 23 | sys.exit(1) 24 | 25 | with open("semver.txt") as fh: 26 | currentVersion = fh.read().strip() 27 | semver = parseSemver(currentVersion) 28 | 29 | try: 30 | with open("secrets.json") as fh: 31 | secrets = json.load(fh) 32 | except OSError: 33 | print("Error trying to load the secrets.json file.") 34 | raise 35 | 36 | args = argparse.ArgumentParser(description="Releases a new version to pypi.org.") 37 | args.add_argument( 38 | "bump", 39 | choices=["break", "feature", "bugfix"], 40 | help="Which type of release is this?", 41 | ) 42 | args.add_argument( 43 | "--test", 44 | dest="test", 45 | action="store_true", 46 | help="Upload to test.pypi.org instead.", 47 | ) 48 | options, _ = args.parse_known_args() 49 | 50 | # Bump the semver 51 | if options.bump == "break": 52 | semver[0] += 1 53 | semver[1] = 0 54 | semver[2] = 0 55 | elif options.bump == "feature": 56 | semver[1] += 1 57 | semver[2] = 0 58 | elif options.bump == "bugfix": 59 | semver[2] += 1 60 | newVersion = ".".join(str(x) for x in semver) 61 | print(f"Bumping to {newVersion}...") 62 | 63 | # Update the semver 64 | with open("semver.txt", "w") as fh: 65 | fh.write(newVersion) 66 | 67 | try: 68 | # Clear out the build artifacts, build it, upload, and clean up again. 69 | subprocess.call("rm -r build dist", shell=True) 70 | subprocess.check_call("pyproject-build", shell=True) 71 | if options.test: 72 | subprocess.check_call( 73 | " ".join( 74 | [ 75 | "twine upload", 76 | "--repository-url https://test.pypi.org/legacy/", 77 | "--username __token__", 78 | "--password", 79 | secrets["test.pypi.org release key"], 80 | "dist/*", 81 | ], 82 | ), 83 | shell=True, 84 | ) 85 | else: 86 | subprocess.check_call( 87 | " ".join( 88 | [ 89 | "twine upload", 90 | "--username __token__", 91 | "--password", 92 | secrets["pypi.org release key"], 93 | "dist/*", 94 | ], 95 | ), 96 | shell=True, 97 | ) 98 | subprocess.call("rm -r build dist", shell=True) 99 | except: 100 | # roll back the semver 101 | with open("semver.txt", "w") as fh: 102 | fh.write(currentVersion) 103 | raise 104 | 105 | # Clean up with a final commit of the changed version files 106 | subprocess.check_call( 107 | "git add semver.txt", 108 | shell=True, 109 | ) 110 | subprocess.check_call(f"git commit -m 'Bump semver to {newVersion}'", shell=True) 111 | subprocess.check_call("git push", shell=True) 112 | 113 | 114 | def inProjectRoot(projectName): 115 | # Checks whether the cwd is in the project root 116 | try: 117 | remotes = subprocess.check_output( 118 | "git remote -v", stderr=subprocess.DEVNULL, shell=True, 119 | ).decode("utf-8") 120 | if projectName in remotes: 121 | return os.path.isdir(".git") 122 | else: 123 | return False 124 | except subprocess.CalledProcessError: 125 | return False 126 | 127 | 128 | def parseSemver(s): 129 | # TODO: replace with the semver module 130 | return [int(x) for x in s.strip().split(".")] 131 | 132 | 133 | if __name__ == "__main__": 134 | createRelease() 135 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | -e ./ 3 | 4 | black==24.10.0 5 | pylint==3.3.2 6 | ruff==0.8.2 7 | mypy==1.13.0 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -i https://pypi.org/simple -------------------------------------------------------------------------------- /semver.txt: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | with open("README.md") as fh: 4 | long_description = fh.read() 5 | with open("semver.txt") as fh: 6 | semver = fh.read().strip() 7 | """ 8 | with open("requirements.txt") as fh: 9 | install_requires = [x.strip() for x in fh.read().strip().split("\n")] 10 | """ 11 | 12 | setup( 13 | name="kdl-py", 14 | version=semver, 15 | author="Tab Atkins-Bittner", 16 | description="A parser for the KDL language.", 17 | long_description=long_description, 18 | long_description_content_type="text/markdown", 19 | url="https://github.com/tabatkins/kdlpy/", 20 | packages=find_packages(), 21 | include_package_data=True, 22 | install_requires=[], 23 | python_requires=">=3.7", 24 | classifiers=[ 25 | "Development Status :: 5 - Production/Stable", 26 | "License :: OSI Approved :: MIT License", 27 | "Operating System :: OS Independent", 28 | "Programming Language :: Python :: 3.7", 29 | "Topic :: Software Development :: Documentation", 30 | ], 31 | entry_points={"console_scripts": ["kdlreformat = kdl:cli"]}, 32 | ) 33 | -------------------------------------------------------------------------------- /test_upstream.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | import os 5 | import pprint 6 | import sys 7 | from typing import Set, Tuple 8 | 9 | # Force the local kdl module into the environment 10 | sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) 11 | import kdl 12 | 13 | THIS_DIR = os.path.dirname(os.path.realpath(__file__)) 14 | TEST_DIR = os.path.join(THIS_DIR, "upstream_tests", "test_cases", "input") 15 | GOLDEN_DIR = os.path.join(THIS_DIR, "upstream_tests", "test_cases", "expected_kdl") 16 | 17 | 18 | def main() -> None: 19 | cli = argparse.ArgumentParser() 20 | cli.add_argument("-v", dest="verbose", action="count", default=0) 21 | cli.add_argument("test", nargs="?", default=None, help="Run a single test, and get a diff.") 22 | options = cli.parse_args() 23 | 24 | printConfig = kdl.PrintConfig( 25 | indent=" ", 26 | respectRadix=False, 27 | respectStringType=False, 28 | exponent="E", 29 | sortEntries=True, 30 | ) 31 | parseConfig = kdl.ParseConfig( 32 | nativeUntaggedValues=False, 33 | ) 34 | parser = kdl.Parser(parseConfig, printConfig) 35 | 36 | if options.test: 37 | if options.test.endswith(".kdl"): 38 | singleTestName = options.test 39 | else: 40 | singleTestName = options.test + ".kdl" 41 | inputs = set([singleTestName]) 42 | if options.test.endswith("_fail"): 43 | goldens = set() 44 | else: 45 | goldens = set([singleTestName]) 46 | else: 47 | inputs, goldens = findTestFiles() 48 | 49 | good = [] 50 | bad = [] 51 | for filename in sorted(inputs): 52 | inputPath = os.path.join(TEST_DIR, filename) 53 | inputText: str 54 | with open(inputPath, "r", encoding="utf-8") as fh: 55 | inputText = fh.read() 56 | 57 | goldenText: str | None 58 | if filename in goldens: 59 | goldenPath = os.path.join(GOLDEN_DIR, filename) 60 | with open(goldenPath, "r", encoding="utf-8") as fh: 61 | goldenText = fh.read() 62 | else: 63 | goldenText = None 64 | 65 | try: 66 | outputDoc = parser.parse(inputText) 67 | outputText = outputDoc.print() 68 | except kdl.ParseError as e: 69 | if goldenText is None: 70 | # SUCCESS: expected parse failure 71 | good.append(filename) 72 | else: 73 | # FAILURE: unexpected parse failure 74 | bad.append(filename) 75 | if options.verbose == 2: 76 | print(f"Unexpected parse failure in {filename}") 77 | print(e) 78 | print("Input:") 79 | print(inputText) 80 | print("Expected:") 81 | print(goldenText) 82 | print("================") 83 | continue 84 | except Exception as e: 85 | raise 86 | # FAILURE: unexpected runtime error 87 | bad.append(filename) 88 | if options.verbose == 2: 89 | print(f"BIG BAD: Internal error in {filename}") 90 | print(e) 91 | print("Input:") 92 | print(inputText) 93 | print("================") 94 | continue 95 | # Successful parse! 96 | if goldenText is None: 97 | # FAILURE: successful parse, but should be a parse failure 98 | bad.append(filename) 99 | if options.verbose == 2: 100 | try: 101 | print(f"Unexpected successful parse in {filename}.") 102 | print("Input:") 103 | print(inputText) 104 | print("Unexpected output (should be a parse failure)") 105 | print(outputText) 106 | print("Doc:") 107 | print(pprint.pformat(outputDoc)) 108 | print("================") 109 | except Exception as e: 110 | print(f"While attempting to report an unexpected successful") 111 | print(f"parse in {filename}, encountered a Python error:") 112 | print(e) 113 | continue 114 | if outputText == goldenText: 115 | # SUCCESS: successful parse, matched golden 116 | good.append(filename) 117 | continue 118 | bad.append(filename) 119 | if options.verbose == 2: 120 | # FAILURE: successful parse, but didn't match golden 121 | print(f"Output didn't match golden in {filename}.") 122 | print("Input:") 123 | print(inputText) 124 | print("Expected:") 125 | print(goldenText) 126 | print("Got:") 127 | print(outputText) 128 | print("Doc:") 129 | print(pprint.pformat(outputDoc)) 130 | print("================") 131 | 132 | if not bad: 133 | print(f"Success, {len(good)}/{len(inputs)} tests passed.") 134 | return True 135 | else: 136 | print(f"Failure, {len(good)}/{len(inputs)} tests passed.") 137 | if options.verbose == 1: 138 | for badfilename in bad: 139 | print("* " + badfilename) 140 | return False 141 | 142 | 143 | def findTestFiles() -> Tuple[Set[str], Set[str]]: 144 | inputs = set() 145 | goldens = set() 146 | for root, _, filenames in os.walk(TEST_DIR): 147 | for filename in filenames: 148 | if os.path.splitext(filename)[1] == ".kdl": 149 | inputs.add(filename) 150 | for root, _, filenames in os.walk(GOLDEN_DIR): 151 | for filename in filenames: 152 | if os.path.splitext(filename)[1] == ".kdl": 153 | goldens.add(filename) 154 | return inputs, goldens 155 | 156 | 157 | if __name__ == "__main__": 158 | main() -------------------------------------------------------------------------------- /upstream_tests/README.md: -------------------------------------------------------------------------------- 1 | # Full Document Test Cases 2 | 3 | The `input` folder contains test cases for KDL parsers. The `expected_kdl` 4 | folder contains files with the same name as those in `input` with the expected 5 | output after being run through the parser and printed out again. 6 | 7 | If a testcase is intended to fail parsing, 8 | the `input` file _MUST_ have a `_fail` suffix, 9 | and there must be no corresponding file in `expected_kdl`. 10 | 11 | ## Translation Rules 12 | 13 | By necessity, the files in `expected_kdl` are not identical to their 14 | corresponding inputs. They are instead pretty-printed according to the 15 | following rules: 16 | 17 | * All comments removed 18 | * Extra empty lines removed except for a newline after the last node 19 | * All nodes should be reformatted without escaped newlines 20 | * Node fields should be `identifier ` 21 | * All values and all children must be in the same order as they were defined. 22 | * Properties must be in _alphabetical order_ and separated by a single space. 23 | * All strings must be represented as regular strings, with appropriate escapes 24 | for invalid bare characters. That means that raw strings must be converted 25 | to plain strings, and escaped. 26 | * Any literal newlines or other ascii escape characters in escaped strings 27 | replaced with their escape sequences. 28 | * All identifiers must be unquoted unless they _must_ be quoted. That means 29 | `"foo"` becomes `foo`, and `"foo bar"` stays that way. 30 | * Any duplicate properties must be removed, with only the rightmost one 31 | remaining. This also means duplicate properties must be allowed. 32 | * 4 space indents 33 | * All numbers must be converted to their simplest decimal representation. That 34 | means that hex, octal, and binary must all be converted to decimals. All 35 | floats must be represented using `E` notation, with a single digit left of 36 | the decimal point if the float is less than 1. While parsers are required to 37 | _consume_ different number syntaxes, they are under no obligation to 38 | represent numbers in any particular way. 39 | 40 | Data may be manipulated as you wish in order to output the expected KDL. This 41 | test suite verifies the ability to **parse**, not specific quirks about 42 | internal representations. 43 | 44 | ## What to do if a test fails for you 45 | 46 | This test suite was originally designed for a pre-1.0 version of the KDL 47 | specification. If you encounter a failure, it's likely that the test suite 48 | will need to be updated, rather than your parser itself. This test suite is 49 | NOT AUTHORITATIVE. If this test suite disagrees with the KDL spec in any way, 50 | the most desirable resolution is to send a PR to this repository to fix the 51 | test itself. Likewise, if you think a test succeeded but should not have, 52 | please send a PR. 53 | 54 | If you think the disagreement is due to a genuine error or oversight in the 55 | KDL specification, please open an issue explaining the matter and the change 56 | will be considered for the next version of the KDL spec. 57 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/all_escapes.kdl: -------------------------------------------------------------------------------- 1 | node "\"\\\b\f\n\r\t " 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/all_node_fields.kdl: -------------------------------------------------------------------------------- 1 | node arg prop=val { 2 | inner_node 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_and_prop_same_name.kdl: -------------------------------------------------------------------------------- 1 | node arg arg=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_bare.kdl: -------------------------------------------------------------------------------- 1 | node a 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_false_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_float_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)2.5 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_hex_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)16 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_null_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_raw_string_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_string_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_true_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/arg_zero_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/asterisk_in_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/bare_emoji.kdl: -------------------------------------------------------------------------------- 1 | 😁 happy! 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/bare_ident_dot.kdl: -------------------------------------------------------------------------------- 1 | node . 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/bare_ident_sign.kdl: -------------------------------------------------------------------------------- 1 | node + 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/bare_ident_sign_dot.kdl: -------------------------------------------------------------------------------- 1 | node +. 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/binary.kdl: -------------------------------------------------------------------------------- 1 | node 2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/binary_trailing_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/binary_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/blank_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node ("")10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/blank_node_type.kdl: -------------------------------------------------------------------------------- 1 | ("")node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/blank_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=("")#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/block_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/block_comment_after_node.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/block_comment_before_node.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/block_comment_before_node_no_space.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/block_comment_newline.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/bom_initial.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/boolean_arg.kdl: -------------------------------------------------------------------------------- 1 | node #false #true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/boolean_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop1=#true prop2=#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/chevrons_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123foo weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comma_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123,bar weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_after_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_after_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_after_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_and_newline.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_in_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_in_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/comment_in_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/commented_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/commented_child.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/commented_line.kdl: -------------------------------------------------------------------------------- 1 | node_2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/commented_node.kdl: -------------------------------------------------------------------------------- 1 | node_2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/commented_prop.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/crlf_between_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/dash_dash.kdl: -------------------------------------------------------------------------------- 1 | node -- 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/emoji.kdl: -------------------------------------------------------------------------------- 1 | node 😀 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_child.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_child_different_lines.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_child_same_line.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_child_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_line_comment.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_quoted_node_id.kdl: -------------------------------------------------------------------------------- 1 | "" arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_quoted_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node ""=empty 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/empty_string_arg.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/eof_after_escape.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/esc_multiple_newlines.kdl: -------------------------------------------------------------------------------- 1 | node "12" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/esc_newline_in_string.kdl: -------------------------------------------------------------------------------- 1 | node "hello\nworld" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/esc_unicode_in_string.kdl: -------------------------------------------------------------------------------- 1 | node "hello\nworld" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escaped_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" "Hello\n\tWorld" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_after_semicolon.kdl: -------------------------------------------------------------------------------- 1 | node 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_alone.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_empty_line.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_end_of_node.kdl: -------------------------------------------------------------------------------- 1 | a 2 | b 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_in_child_block.kdl: -------------------------------------------------------------------------------- 1 | parent { 2 | child 3 | child 4 | } 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_line_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_node.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/escline_slashdash.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/false_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | false_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/false_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node false_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/floating_point_keywords.kdl: -------------------------------------------------------------------------------- 1 | floats #inf #-inf #nan 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/hex.kdl: -------------------------------------------------------------------------------- 1 | node 12379813812177893520 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/hex_int.kdl: -------------------------------------------------------------------------------- 1 | node 207698809136909011942886895 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/hex_int_underscores.kdl: -------------------------------------------------------------------------------- 1 | node 737894400291 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/hex_leading_zero.kdl: -------------------------------------------------------------------------------- 1 | node 1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/initial_slashdash.kdl: -------------------------------------------------------------------------------- 1 | another-node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/int_multiple_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 1234 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/just_block_comment.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/just_child.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | inner_node 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/just_newline.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/just_node_id.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/just_space.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/leading_newline.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/leading_zero_binary.kdl: -------------------------------------------------------------------------------- 1 | node 1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/leading_zero_int.kdl: -------------------------------------------------------------------------------- 1 | node 11 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/leading_zero_oct.kdl: -------------------------------------------------------------------------------- 1 | node 1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_nodes.kdl: -------------------------------------------------------------------------------- 1 | node arg1 arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_raw_string.kdl: -------------------------------------------------------------------------------- 1 | node "hey\neveryone\nhow goes?" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_raw_string_containing_quotes.kdl: -------------------------------------------------------------------------------- 1 | node "\"\"\"triple-quote\"\"\"\n##\"too few quotes\"##\n#\"\"\"too few #\"\"\"#" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_raw_string_empty.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_raw_string_empty_indented.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_raw_string_indented.kdl: -------------------------------------------------------------------------------- 1 | node " hey\n everyone\n how goes?" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string.kdl: -------------------------------------------------------------------------------- 1 | node "hey\neveryone\nhow goes?" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_containing_quotes.kdl: -------------------------------------------------------------------------------- 1 | node "this string contains \"quotes\", twice\"\"" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_double_backslash.kdl: -------------------------------------------------------------------------------- 1 | node "a\\ b\na\\b" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_empty.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_empty_indented.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_escape_delimiter.kdl: -------------------------------------------------------------------------------- 1 | node "\"\"\"" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_escape_in_closing_line.kdl: -------------------------------------------------------------------------------- 1 | node "foo bar\nbaz" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_escape_in_closing_line_shallow.kdl: -------------------------------------------------------------------------------- 1 | node " foo bar\n baz" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_escape_newline_at_end.kdl: -------------------------------------------------------------------------------- 1 | node " a" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_indented.kdl: -------------------------------------------------------------------------------- 1 | node " hey\n everyone\n how goes?" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/multiline_string_whitespace_only.kdl: -------------------------------------------------------------------------------- 1 | node "" "" "" "\n\n " "\n" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/negative_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0E-10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/negative_float.kdl: -------------------------------------------------------------------------------- 1 | node -1.0 key=-10.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/negative_int.kdl: -------------------------------------------------------------------------------- 1 | node -10 prop=-15 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/nested_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/nested_children.kdl: -------------------------------------------------------------------------------- 1 | node1 { 2 | node2 { 3 | node 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/nested_comments.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/nested_multiline_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/newline_between_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/newlines_in_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/no_decimal_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1E+10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/node_false.kdl: -------------------------------------------------------------------------------- 1 | node #false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/node_true.kdl: -------------------------------------------------------------------------------- 1 | node #true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/null_arg.kdl: -------------------------------------------------------------------------------- 1 | node #null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/null_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | null_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/null_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node null_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/null_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/numeric_arg.kdl: -------------------------------------------------------------------------------- 1 | node 15.7 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/numeric_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=10.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/octal.kdl: -------------------------------------------------------------------------------- 1 | node 16434824 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/only_cr.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/only_line_comment.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/only_line_comment_crlf.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/only_line_comment_newline.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/optional_child_semicolon.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | foo 3 | bar 4 | baz 5 | } 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/parse_all_arg_types.kdl: -------------------------------------------------------------------------------- 1 | node 1 1.0 1.0E+10 1.0E-10 1 7 2 arg arg "arg\\" #true #false #null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/positive_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0E+10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/positive_int.kdl: -------------------------------------------------------------------------------- 1 | node 10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/preserve_duplicate_nodes.kdl: -------------------------------------------------------------------------------- 1 | node 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/preserve_node_order.kdl: -------------------------------------------------------------------------------- 1 | node2 2 | node5 3 | node1 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_false_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_float_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)2.5E+10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_hex_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)16 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_identifier_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_null_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_raw_string_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_string_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_true_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/prop_zero_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/question_mark_before_number.kdl: -------------------------------------------------------------------------------- 1 | node ?15 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node ("type/")10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_node_name.kdl: -------------------------------------------------------------------------------- 1 | "0node" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_node_type.kdl: -------------------------------------------------------------------------------- 1 | ("type/")node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_numeric.kdl: -------------------------------------------------------------------------------- 1 | node prop="10.0" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_prop_name.kdl: -------------------------------------------------------------------------------- 1 | node "0prop"=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/quoted_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=("type/")#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/r_node.kdl: -------------------------------------------------------------------------------- 1 | r arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_node_name.kdl: -------------------------------------------------------------------------------- 1 | "\\node" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_arg.kdl: -------------------------------------------------------------------------------- 1 | node_1 "\"arg\\n\"and #stuff" 2 | node_2 "#\"arg\\n\"#and #stuff" 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_backslash.kdl: -------------------------------------------------------------------------------- 1 | node "\\n" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_hash_no_esc.kdl: -------------------------------------------------------------------------------- 1 | node "#" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_just_backslash.kdl: -------------------------------------------------------------------------------- 1 | node "\\" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_multiple_hash.kdl: -------------------------------------------------------------------------------- 1 | node "\"#\"##" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_newline.kdl: -------------------------------------------------------------------------------- 1 | node "hello\nworld" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_prop.kdl: -------------------------------------------------------------------------------- 1 | node_1 prop="\"arg#\"\\n" 2 | node_2 prop="#\"arg#\"#\\n" 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/raw_string_quote.kdl: -------------------------------------------------------------------------------- 1 | node "a\"b" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/repeated_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/repeated_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=11 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/same_name_nodes.kdl: -------------------------------------------------------------------------------- 1 | node 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/sci_notation_large.kdl: -------------------------------------------------------------------------------- 1 | node prop=1.23E+1000 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/sci_notation_small.kdl: -------------------------------------------------------------------------------- 1 | node prop=1.23E-1000 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/semicolon_after_child.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | childnode 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/semicolon_in_child.kdl: -------------------------------------------------------------------------------- 1 | node1 { 2 | node2 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/semicolon_separated.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/semicolon_separated_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/semicolon_terminated.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/single_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/single_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_arg_after_newline_esc.kdl: -------------------------------------------------------------------------------- 1 | node arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_arg_before_newline_esc.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_child.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_empty_child.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_escline_before_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_escline_before_children.kdl: -------------------------------------------------------------------------------- 1 | node arg1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_escline_before_node.kdl: -------------------------------------------------------------------------------- 1 | node2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_false_node.kdl: -------------------------------------------------------------------------------- 1 | node foo bar 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_full_node.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_in_slashdash.kdl: -------------------------------------------------------------------------------- 1 | node2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_multi_line_comment_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 3 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_multi_line_comment_inline.kdl: -------------------------------------------------------------------------------- 1 | node 1 3 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_multiple_child_blocks.kdl: -------------------------------------------------------------------------------- 1 | node foo { 2 | three 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_negative_number.kdl: -------------------------------------------------------------------------------- 1 | node 2.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_newline_before_children.kdl: -------------------------------------------------------------------------------- 1 | node 1 2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_newline_before_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 3 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_newline_before_node.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_node_in_child.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_node_with_child.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_only_node.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_only_node_with_space.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_prop.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_raw_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_repeated_prop.kdl: -------------------------------------------------------------------------------- 1 | node arg=correct 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_single_line_comment_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 3 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/slashdash_single_line_comment_node.kdl: -------------------------------------------------------------------------------- 1 | node2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_after_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_after_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_after_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_around_prop_marker.kdl: -------------------------------------------------------------------------------- 1 | node foo=bar 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_in_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_in_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/space_in_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/string_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/string_escaped_literal_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node "Hello World Stuff" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/string_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/tab_space.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/trailing_crlf.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/trailing_underscore_hex.kdl: -------------------------------------------------------------------------------- 1 | node 1194684 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/trailing_underscore_octal.kdl: -------------------------------------------------------------------------------- 1 | node 83 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/true_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | true_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/true_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node true_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/two_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_before_number.kdl: -------------------------------------------------------------------------------- 1 | node _15 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_in_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0E-100 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_in_float.kdl: -------------------------------------------------------------------------------- 1 | node 11.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_in_fraction.kdl: -------------------------------------------------------------------------------- 1 | node 1.02 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_in_int.kdl: -------------------------------------------------------------------------------- 1 | node 10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/underscore_in_octal.kdl: -------------------------------------------------------------------------------- 1 | node 342391 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/unicode_silly.kdl: -------------------------------------------------------------------------------- 1 | ノード お名前=ฅ^•ﻌ•^ฅ 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/unusual_bare_id_chars_in_quoted_id.kdl: -------------------------------------------------------------------------------- 1 | foo123~!@$%^&*.:'|?+<>,`-_ weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/unusual_chars_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123~!@$%^&*.:'|?+<>,`-_ weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/vertical_tab_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | node2 arg2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/zero_float.kdl: -------------------------------------------------------------------------------- 1 | node 0.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/expected_kdl/zero_int.kdl: -------------------------------------------------------------------------------- 1 | node 0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/all_escapes.kdl: -------------------------------------------------------------------------------- 1 | node "\"\\\b\f\n\r\t\s" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/all_node_fields.kdl: -------------------------------------------------------------------------------- 1 | node arg prop=val { 2 | inner_node 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_and_prop_same_name.kdl: -------------------------------------------------------------------------------- 1 | node arg arg=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_bare.kdl: -------------------------------------------------------------------------------- 1 | node a 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_false_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_float_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)2.5 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_hex_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)0x10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_null_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_raw_string_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#"str"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_string_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)"str" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_true_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/arg_zero_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/asterisk_in_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* * */ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_emoji.kdl: -------------------------------------------------------------------------------- 1 | 😁 happy! 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_dot.kdl: -------------------------------------------------------------------------------- 1 | node . -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_numeric_dot_fail.kdl: -------------------------------------------------------------------------------- 1 | node .0n -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_numeric_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0n -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_numeric_sign_fail.kdl: -------------------------------------------------------------------------------- 1 | node +0n -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_sign.kdl: -------------------------------------------------------------------------------- 1 | node + -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bare_ident_sign_dot.kdl: -------------------------------------------------------------------------------- 1 | node +. -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/binary.kdl: -------------------------------------------------------------------------------- 1 | node 0b10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/binary_trailing_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 0b10_ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/binary_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 0b1_0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/blank_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node ("")10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/blank_node_type.kdl: -------------------------------------------------------------------------------- 1 | ("")node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/blank_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=("")#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/block_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* comment */ arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/block_comment_after_node.kdl: -------------------------------------------------------------------------------- 1 | node /* hey */ arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/block_comment_before_node.kdl: -------------------------------------------------------------------------------- 1 | /* hey */ node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/block_comment_before_node_no_space.kdl: -------------------------------------------------------------------------------- 1 | /* hey*/node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/block_comment_newline.kdl: -------------------------------------------------------------------------------- 1 | /* hey */ 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bom_initial.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/bom_later_fail.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/boolean_arg.kdl: -------------------------------------------------------------------------------- 1 | node #false #true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/boolean_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop1=#true prop2=#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/braces_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123{bar} 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/brackets_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123{bar}foo weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/chevrons_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123foo weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comma_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123,bar weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_after_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)/*hey*/10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_after_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)/*hey*/node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_after_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)/*hey*/10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_and_newline.kdl: -------------------------------------------------------------------------------- 1 | node1 // 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_in_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type/*hey*/)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_in_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type/*hey*/)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/comment_in_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type/*hey*/)10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/commented_arg.kdl: -------------------------------------------------------------------------------- 1 | node /- arg1 arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/commented_child.kdl: -------------------------------------------------------------------------------- 1 | node arg /- { 2 | inner_node 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/commented_line.kdl: -------------------------------------------------------------------------------- 1 | // node_1 2 | node_2 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/commented_node.kdl: -------------------------------------------------------------------------------- 1 | /- node_1 2 | node_2 3 | /- node_3 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/commented_prop.kdl: -------------------------------------------------------------------------------- 1 | node /- prop=val arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/crlf_between_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/dash_dash.kdl: -------------------------------------------------------------------------------- 1 | node -- 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/dot_but_no_fraction_before_exponent_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1.e7 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/dot_but_no_fraction_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1. -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/dot_in_exponent_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1.0.0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/dot_zero_fail.kdl: -------------------------------------------------------------------------------- 1 | node .0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/emoji.kdl: -------------------------------------------------------------------------------- 1 | node 😀 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty.kdl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tabatkins/kdlpy/d9a220762fb9f55e4f59296256221084c26f54da/upstream_tests/test_cases/input/empty.kdl -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_arg_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node ()10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_child.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_child_different_lines.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_child_same_line.kdl: -------------------------------------------------------------------------------- 1 | node {} -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_child_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | 3 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_line_comment.kdl: -------------------------------------------------------------------------------- 1 | // 2 | node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_node_type_fail.kdl: -------------------------------------------------------------------------------- 1 | ()node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_prop_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node key=()#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_quoted_node_id.kdl: -------------------------------------------------------------------------------- 1 | "" arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_quoted_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node ""=empty 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/empty_string_arg.kdl: -------------------------------------------------------------------------------- 1 | node "" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/eof_after_escape.kdl: -------------------------------------------------------------------------------- 1 | node \ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/err_backslash_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123\bar weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/esc_multiple_newlines.kdl: -------------------------------------------------------------------------------- 1 | node "1\ 2 | 3 | 4 | 2" 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/esc_newline_in_string.kdl: -------------------------------------------------------------------------------- 1 | node "hello\nworld" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/esc_unicode_in_string.kdl: -------------------------------------------------------------------------------- 1 | node "hello\u{0a}world" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escaped_whitespace.kdl: -------------------------------------------------------------------------------- 1 | // All of these strings are the same 2 | node \ 3 | "Hello\n\tWorld" \ 4 | """ 5 | Hello 6 | World 7 | """ \ 8 | "Hello\n\ \tWorld" \ 9 | "Hello\n\ 10 | \tWorld" \ 11 | "Hello\n\t\ 12 | World" 13 | 14 | // Note that this file deliberately mixes space and newline indentation for 15 | // test purposes 16 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline.kdl: -------------------------------------------------------------------------------- 1 | node \ 2 | arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_after_semicolon.kdl: -------------------------------------------------------------------------------- 1 | node; \ 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_alone.kdl: -------------------------------------------------------------------------------- 1 | \ 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_empty_line.kdl: -------------------------------------------------------------------------------- 1 | \ 2 | 3 | node 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_end_of_node.kdl: -------------------------------------------------------------------------------- 1 | a \ 2 | 3 | b 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_in_child_block.kdl: -------------------------------------------------------------------------------- 1 | parent { 2 | child 3 | \ // comment 4 | child 5 | } 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_line_comment.kdl: -------------------------------------------------------------------------------- 1 | node \ // comment 2 | arg \// comment 3 | arg2 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_node.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | \ 3 | node2 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_node_type.kdl: -------------------------------------------------------------------------------- 1 | \ 2 | (type)node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/escline_slashdash.kdl: -------------------------------------------------------------------------------- 1 | node 2 | \ 3 | /- 4 | node 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/false_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | false_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/false_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node false_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/false_prop_key_fail.kdl: -------------------------------------------------------------------------------- 1 | node false=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/floating_point_keyword_identifier_strings_fail.kdl: -------------------------------------------------------------------------------- 1 | floats inf -inf nan 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/floating_point_keywords.kdl: -------------------------------------------------------------------------------- 1 | floats #inf #-inf #nan 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/hash_in_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo#bar weee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/hex.kdl: -------------------------------------------------------------------------------- 1 | node 0xabcdef1234567890 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/hex_int.kdl: -------------------------------------------------------------------------------- 1 | node 0xABCDEF0123456789abcdef 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/hex_int_underscores.kdl: -------------------------------------------------------------------------------- 1 | node 0xABC_def_0123 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/hex_leading_zero.kdl: -------------------------------------------------------------------------------- 1 | node 0x01 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/illegal_char_in_binary_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0bx01 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/illegal_char_in_hex_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0x10g10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/illegal_char_in_octal_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0o45678 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/initial_slashdash.kdl: -------------------------------------------------------------------------------- 1 | /-node here 2 | another-node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/int_multiple_underscore.kdl: -------------------------------------------------------------------------------- 1 | node 1_2_3_4 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_block_comment.kdl: -------------------------------------------------------------------------------- 1 | /* hey */ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_child.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | inner_node 3 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_newline.kdl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_node_id.kdl: -------------------------------------------------------------------------------- 1 | node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_space.kdl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_space_in_arg_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node ( )false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_space_in_node_type_fail.kdl: -------------------------------------------------------------------------------- 1 | ( )node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_space_in_prop_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node key=( )0x10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_type_no_arg_fail.kdl: -------------------------------------------------------------------------------- 1 | node (type) 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_type_no_node_id_fail.kdl: -------------------------------------------------------------------------------- 1 | (type) 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/just_type_no_prop_fail.kdl: -------------------------------------------------------------------------------- 1 | node key=(type) 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/leading_newline.kdl: -------------------------------------------------------------------------------- 1 | 2 | node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/leading_zero_binary.kdl: -------------------------------------------------------------------------------- 1 | node 0b01 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/leading_zero_int.kdl: -------------------------------------------------------------------------------- 1 | node 011 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/leading_zero_oct.kdl: -------------------------------------------------------------------------------- 1 | node 0o01 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/legacy_raw_string_fail.kdl: -------------------------------------------------------------------------------- 1 | node r"foo" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/legacy_raw_string_hash_fail.kdl: -------------------------------------------------------------------------------- 1 | node r#"foo"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* 2 | some 3 | comments 4 | */ arg 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_nodes.kdl: -------------------------------------------------------------------------------- 1 | node \ 2 | arg1 \// comment 3 | arg2 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | hey 3 | everyone 4 | how goes? 5 | """# 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_containing_quotes.kdl: -------------------------------------------------------------------------------- 1 | node ##""" 2 | """triple-quote""" 3 | ##"too few quotes"## 4 | #"""too few #"""# 5 | """## 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_empty.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | """# -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_empty_indented.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | """# -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_indented.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | hey 3 | everyone 4 | how goes? 5 | """# 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error_fail.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | hey 3 | everyone 4 | how goes? 5 | """# 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error_fail.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | hey 3 | everyone 4 | how goes? 5 | """# 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_single_line_err_fail.kdl: -------------------------------------------------------------------------------- 1 | node #"""one line"""# -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_raw_string_single_quote_err_fail.kdl: -------------------------------------------------------------------------------- 1 | node #" 2 | hey 3 | everyone 4 | how goes? 5 | "# 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | hey 3 | everyone 4 | how goes? 5 | """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_containing_quotes.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | this string contains "quotes", twice"" 3 | """ 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_double_backslash.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | a\\ b 3 | a\\\ b 4 | """ 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_empty.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | """ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_empty_indented.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | """ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_escape_delimiter.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | \""" 3 | """ 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_escape_in_closing_line.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | foo \ 3 | bar 4 | baz 5 | \ """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_escape_in_closing_line_shallow.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | foo \ 3 | bar 4 | baz 5 | \ """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_escape_newline_at_end.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | a 3 | \ 4 | """ 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_escape_newline_at_end_fail.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | a 3 | \ 4 | """ 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_final_whitespace_escape_fail.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | foo 3 | bar\ 4 | """ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_indented.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | hey 3 | everyone 4 | how goes? 5 | """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_non_literal_prefix_fail.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | \s escaped prefix 3 | literal prefix 4 | """ 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_non_matching_prefix_character_error_fail.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | hey 3 | everyone 4 | how goes? 5 | """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_non_matching_prefix_count_error_fail.kdl: -------------------------------------------------------------------------------- 1 | node """ 2 | hey 3 | everyone 4 | how goes? 5 | """ 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_single_line_err_fail.kdl: -------------------------------------------------------------------------------- 1 | node """one line""" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_single_quote_err_fail.kdl: -------------------------------------------------------------------------------- 1 | node " 2 | hey 3 | everyone 4 | how goes? 5 | " 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiline_string_whitespace_only.kdl: -------------------------------------------------------------------------------- 1 | // This file deliberately contains unusual whitespace 2 | // The first two strings are empty 3 | node """ 4 |   """ """ 5 |    \ 6 |    7 |    """ """ 8 |    9 |  """\ 10 | \ // The next two strings contains only whitespace 11 | """ 12 |    13 | 14 |    \s 15 |    """ #""" 16 |      17 | 18 | """# 19 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiple_dots_in_float_before_exponent_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1.0.0e7 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiple_dots_in_float_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1.0.0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiple_es_in_float_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1.0E10e10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/multiple_x_in_hex_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0xx10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/negative_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0e-10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/negative_float.kdl: -------------------------------------------------------------------------------- 1 | node -1.0 key=-10.0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/negative_int.kdl: -------------------------------------------------------------------------------- 1 | node -10 prop=-15 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/nested_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* hi /* there */ everyone */ arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/nested_children.kdl: -------------------------------------------------------------------------------- 1 | node1 { 2 | node2 { 3 | node 4 | } 5 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/nested_comments.kdl: -------------------------------------------------------------------------------- 1 | node /*/* nested */*/ arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/nested_multiline_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* 2 | hey /* 3 | how's 4 | */ 5 | it going 6 | */ arg 7 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/newline_between_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/newlines_in_block_comment.kdl: -------------------------------------------------------------------------------- 1 | node /* hey so 2 | I was thinking 3 | about newts */ arg 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/no_decimal_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1e10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/no_digits_in_hex_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0x -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/no_integer_digit_fail.kdl: -------------------------------------------------------------------------------- 1 | node .1 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/no_solidus_escape_fail.kdl: -------------------------------------------------------------------------------- 1 | node "\/" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/node_false.kdl: -------------------------------------------------------------------------------- 1 | node #false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/node_true.kdl: -------------------------------------------------------------------------------- 1 | node #true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/null_arg.kdl: -------------------------------------------------------------------------------- 1 | node #null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/null_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | null_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/null_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node null_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/null_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/null_prop_key_fail.kdl: -------------------------------------------------------------------------------- 1 | node null=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/numeric_arg.kdl: -------------------------------------------------------------------------------- 1 | node 15.7 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/numeric_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=10.0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/octal.kdl: -------------------------------------------------------------------------------- 1 | node 0o76543210 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/only_cr.kdl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/only_line_comment.kdl: -------------------------------------------------------------------------------- 1 | // hi -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/only_line_comment_crlf.kdl: -------------------------------------------------------------------------------- 1 | // comment 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/only_line_comment_newline.kdl: -------------------------------------------------------------------------------- 1 | // hiiii 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/optional_child_semicolon.kdl: -------------------------------------------------------------------------------- 1 | node {foo;bar;baz} 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/parens_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123(bar)foo weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/parse_all_arg_types.kdl: -------------------------------------------------------------------------------- 1 | node 1 1.0 1.0e10 1.0e-10 0x01 0o07 0b10 arg "arg" #"arg\"# #true #false #null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/positive_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0e+10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/positive_int.kdl: -------------------------------------------------------------------------------- 1 | node +10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/preserve_duplicate_nodes.kdl: -------------------------------------------------------------------------------- 1 | node 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/preserve_node_order.kdl: -------------------------------------------------------------------------------- 1 | node2 2 | node5 3 | node1 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_false_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_float_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)2.5E10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_hex_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)0x10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_identifier_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)str 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_null_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#null 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_raw_string_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#"str"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_string_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)"str" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_true_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/prop_zero_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/question_mark_before_number.kdl: -------------------------------------------------------------------------------- 1 | node ?15 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quote_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123"bar weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node ("type/")10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_node_name.kdl: -------------------------------------------------------------------------------- 1 | "0node" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_node_type.kdl: -------------------------------------------------------------------------------- 1 | ("type/")node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_numeric.kdl: -------------------------------------------------------------------------------- 1 | node prop="10.0" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_prop_name.kdl: -------------------------------------------------------------------------------- 1 | node "0prop"=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/quoted_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=("type/")#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/r_node.kdl: -------------------------------------------------------------------------------- 1 | r "arg" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_node_name.kdl: -------------------------------------------------------------------------------- 1 | #"\node"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type)node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type)#true 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_arg.kdl: -------------------------------------------------------------------------------- 1 | node_1 #""arg\n"and #stuff"# 2 | node_2 ##"#"arg\n"#and #stuff"## 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_backslash.kdl: -------------------------------------------------------------------------------- 1 | node #"\n"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_hash_no_esc.kdl: -------------------------------------------------------------------------------- 1 | node #"#"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_just_backslash.kdl: -------------------------------------------------------------------------------- 1 | node #"\"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_just_quote_fail.kdl: -------------------------------------------------------------------------------- 1 | // This fails because `"""` MUST be followed by a newline. 2 | node #"""# 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_multiple_hash.kdl: -------------------------------------------------------------------------------- 1 | node ###""#"##"### 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_newline.kdl: -------------------------------------------------------------------------------- 1 | node #""" 2 | hello 3 | world 4 | """# 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_prop.kdl: -------------------------------------------------------------------------------- 1 | node_1 prop=#""arg#"\n"# 2 | node_2 prop=##"#"arg#"#\n"## 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/raw_string_quote.kdl: -------------------------------------------------------------------------------- 1 | node #"a"b"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/repeated_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/repeated_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=10 prop=11 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/same_name_nodes.kdl: -------------------------------------------------------------------------------- 1 | node 2 | node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/sci_notation_large.kdl: -------------------------------------------------------------------------------- 1 | node prop=1.23E+1000 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/sci_notation_small.kdl: -------------------------------------------------------------------------------- 1 | node prop=1.23E-1000 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/semicolon_after_child.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | childnode 3 | }; 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/semicolon_in_child.kdl: -------------------------------------------------------------------------------- 1 | node1 { 2 | node2; 3 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/semicolon_separated.kdl: -------------------------------------------------------------------------------- 1 | node1;node2 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/semicolon_separated_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1; node2; -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/semicolon_terminated.kdl: -------------------------------------------------------------------------------- 1 | node1; -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/single_arg.kdl: -------------------------------------------------------------------------------- 1 | node arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/single_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop=val 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slash_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123/bar weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_after_arg_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node (ty)/-arg1 arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_after_node_type_fail.kdl: -------------------------------------------------------------------------------- 1 | (ty)/-node 2 | other-node 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_after_prop_key_fail.kdl: -------------------------------------------------------------------------------- 1 | node key /- = value 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_after_prop_val_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node key=(ty)/-val other-arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_after_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node (type) /- arg1 arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_arg_after_newline_esc.kdl: -------------------------------------------------------------------------------- 1 | node \ 2 | /- arg arg2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_arg_before_newline_esc.kdl: -------------------------------------------------------------------------------- 1 | node /- \ 2 | arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_before_children_end_fail.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | child1 3 | /- 4 | } 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_before_eof_fail.kdl: -------------------------------------------------------------------------------- 1 | node foo /- 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_before_prop_value_fail.kdl: -------------------------------------------------------------------------------- 1 | node key = /-val etc 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_before_semicolon_fail.kdl: -------------------------------------------------------------------------------- 1 | node foo /-; 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_between_child_blocks_fail.kdl: -------------------------------------------------------------------------------- 1 | node { one } /- { two } { three } 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_child.kdl: -------------------------------------------------------------------------------- 1 | node /- { 2 | node2 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_child_block_before_entry_err_fail.kdl: -------------------------------------------------------------------------------- 1 | node /-{ 2 | child 3 | } foo { 4 | bar 5 | } 6 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_empty_child.kdl: -------------------------------------------------------------------------------- 1 | node /- { 2 | } 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_escline_before_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node /-\ 2 | (ty)arg1 arg2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_escline_before_children.kdl: -------------------------------------------------------------------------------- 1 | node arg1 /-\ 2 | { 3 | } 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_escline_before_node.kdl: -------------------------------------------------------------------------------- 1 | /-\ 2 | node1 3 | node2 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_false_node.kdl: -------------------------------------------------------------------------------- 1 | node foo /- 2 | not-a-node bar 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_full_node.kdl: -------------------------------------------------------------------------------- 1 | /- node 1.0 "a" b=""" 2 | b 3 | """ 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_in_slashdash.kdl: -------------------------------------------------------------------------------- 1 | /- node1 /- 1.0 2 | node2 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_inside_arg_type_fail.kdl: -------------------------------------------------------------------------------- 1 | node (/-bad)nope 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_inside_node_type_fail.kdl: -------------------------------------------------------------------------------- 1 | (/-ty)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_multi_line_comment_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 /- /* 2 | multi 3 | line 4 | comment 5 | here 6 | */ 2 3 7 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_multi_line_comment_inline.kdl: -------------------------------------------------------------------------------- 1 | node 1 /-/*two*/2 3 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_multiple_child_blocks.kdl: -------------------------------------------------------------------------------- 1 | node foo /-{ 2 | one 3 | } \ 4 | /-{ 5 | two 6 | } { 7 | three 8 | } /-{ 9 | four 10 | } 11 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_negative_number.kdl: -------------------------------------------------------------------------------- 1 | node /--1.0 2.0 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_newline_before_children.kdl: -------------------------------------------------------------------------------- 1 | node 1 2 /- 2 | { 3 | child 4 | } 5 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_newline_before_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 /- 2 | 2 3 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_newline_before_node.kdl: -------------------------------------------------------------------------------- 1 | /- 2 | node 1 2 3 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_node_in_child.kdl: -------------------------------------------------------------------------------- 1 | node1 { 2 | /- node2 3 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_node_with_child.kdl: -------------------------------------------------------------------------------- 1 | /- node { 2 | node2 3 | } -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_only_node.kdl: -------------------------------------------------------------------------------- 1 | /-node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_only_node_with_space.kdl: -------------------------------------------------------------------------------- 1 | /- node -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_prop.kdl: -------------------------------------------------------------------------------- 1 | node /- key=value arg 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_raw_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node /- key=value 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_repeated_prop.kdl: -------------------------------------------------------------------------------- 1 | node arg=correct /- arg=wrong 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_single_line_comment_entry.kdl: -------------------------------------------------------------------------------- 1 | node 1 /- // stuff 2 | 2 3 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/slashdash_single_line_comment_node.kdl: -------------------------------------------------------------------------------- 1 | /- // this is a comment 2 | node1 3 | node2 4 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_after_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type) 10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_after_node_type.kdl: -------------------------------------------------------------------------------- 1 | (type) node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_after_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type) #false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_around_prop_marker.kdl: -------------------------------------------------------------------------------- 1 | node foo = bar 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_in_arg_type.kdl: -------------------------------------------------------------------------------- 1 | node (type )#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_in_node_type.kdl: -------------------------------------------------------------------------------- 1 | ( type)node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/space_in_prop_type.kdl: -------------------------------------------------------------------------------- 1 | node key=(type )#false 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/square_bracket_in_bare_id_fail.kdl: -------------------------------------------------------------------------------- 1 | foo123[bar]foo weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/string_arg.kdl: -------------------------------------------------------------------------------- 1 | node "arg" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/string_escaped_literal_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node "Hello \ 2 | World \ Stuff" 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/string_prop.kdl: -------------------------------------------------------------------------------- 1 | node prop="val" -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/tab_space.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/trailing_crlf.kdl: -------------------------------------------------------------------------------- 1 | node 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/trailing_underscore_hex.kdl: -------------------------------------------------------------------------------- 1 | node 0x123abc_ -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/trailing_underscore_octal.kdl: -------------------------------------------------------------------------------- 1 | node 0o123_ 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/true_prefix_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | true_id 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/true_prefix_in_prop_key.kdl: -------------------------------------------------------------------------------- 1 | node true_id=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/true_prop_key_fail.kdl: -------------------------------------------------------------------------------- 1 | node true=1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/two_nodes.kdl: -------------------------------------------------------------------------------- 1 | node1 2 | node2 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/type_before_prop_key_fail.kdl: -------------------------------------------------------------------------------- 1 | node (type)key=10 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unbalanced_raw_hashes_fail.kdl: -------------------------------------------------------------------------------- 1 | node ##"foo"# 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_at_start_of_fraction_fail.kdl: -------------------------------------------------------------------------------- 1 | node 1._7 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_at_start_of_hex_fail.kdl: -------------------------------------------------------------------------------- 1 | node 0x_10 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_before_number.kdl: -------------------------------------------------------------------------------- 1 | node _15 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_in_exponent.kdl: -------------------------------------------------------------------------------- 1 | node 1.0e-10_0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_in_float.kdl: -------------------------------------------------------------------------------- 1 | node 1_1.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_in_fraction.kdl: -------------------------------------------------------------------------------- 1 | node 1.0_2 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_in_int.kdl: -------------------------------------------------------------------------------- 1 | node 1_0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/underscore_in_octal.kdl: -------------------------------------------------------------------------------- 1 | node 0o012_3456_7 -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_delete_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x007F (Delete) 2 | node1 arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_h1_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates high\u{D800}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_h2_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates high\u{D911}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_h3_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates high\u{DABB}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_h4_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates high\u{DBFF}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_l1_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates low\u{DC00}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_l2_fail.kdl: -------------------------------------------------------------------------------- 1 | no "Surrogates low\u{DEAD}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_escaped_l3_fail.kdl: -------------------------------------------------------------------------------- 1 | eno "Surrogates low\u{DFFF}" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_fsi_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x2068 2 | node1 ⁨arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_lre_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x202A 2 | node1 ‪arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_lri_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x2066 2 | node1⁦arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_lrm_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x200E 2 | node ‎arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_lro_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x202D 2 | node ‭arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_pdf_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x202C 2 | node ‬arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_pdi_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x2069 2 | node ⁩arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_rle_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x202B 2 | node1 ‫arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_rli_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x2067 2 | node1 ⁧arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_rlm_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x200F 2 | node ‏arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_rlo_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x202E 2 | node ‮arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_silly.kdl: -------------------------------------------------------------------------------- 1 | ノード お名前=ฅ^•ﻌ•^ฅ 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unicode_under_0x20_fail.kdl: -------------------------------------------------------------------------------- 1 | // 0x0019 2 | node1 arg 3 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unterminated_empty_node_fail.kdl: -------------------------------------------------------------------------------- 1 | node { 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unusual_bare_id_chars_in_quoted_id.kdl: -------------------------------------------------------------------------------- 1 | "foo123~!@$%^&*.:'|?+<>,`-_" weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/unusual_chars_in_bare_id.kdl: -------------------------------------------------------------------------------- 1 | foo123~!@$%^&*.:'|?+<>,`-_ weeee 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/vertical_tab_whitespace.kdl: -------------------------------------------------------------------------------- 1 | node arg node2 arg2 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_float.kdl: -------------------------------------------------------------------------------- 1 | node 0.0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_int.kdl: -------------------------------------------------------------------------------- 1 | node 0 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_space_before_first_arg_fail.kdl: -------------------------------------------------------------------------------- 1 | node"string" 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_space_before_prop_fail.kdl: -------------------------------------------------------------------------------- 1 | node foo="value"bar=5 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_space_before_second_arg_fail.kdl: -------------------------------------------------------------------------------- 1 | node "string"1 2 | -------------------------------------------------------------------------------- /upstream_tests/test_cases/input/zero_space_before_slashdash_arg_fail.kdl: -------------------------------------------------------------------------------- 1 | node "string"/-1 2 | --------------------------------------------------------------------------------