From a366110ab3dcfdd7722555056f17cb75bdbf9c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Sat, 14 Dec 2024 23:50:16 -0800 Subject: [PATCH] Fix parser --- src/v2_parser.rs | 162 +++++++++++++----- .../expected_kdl/raw_string_just_quote.kdl | 1 - tests/test_cases/expected_kdl/zero_arg.kdl | 1 - tests/test_cases/input/bare_ident_numeric.kdl | 1 - .../input/bare_ident_numeric_dot.kdl | 1 - .../input/bare_ident_numeric_sign.kdl | 1 - tests/test_cases/input/bom_later.kdl | 1 - .../test_cases/input/brackets_in_bare_id.kdl | 1 - .../test_cases/input/dot_but_no_fraction.kdl | 1 - .../dot_but_no_fraction_before_exponent.kdl | 1 - tests/test_cases/input/dot_in_exponent.kdl | 1 - tests/test_cases/input/dot_zero.kdl | 1 - tests/test_cases/input/empty_arg_type.kdl | 1 - tests/test_cases/input/empty_node_type.kdl | 1 - tests/test_cases/input/empty_prop_type.kdl | 1 - .../input/err_backslash_in_bare_id.kdl | 1 - tests/test_cases/input/false_prop_key.kdl | 1 - ...t_keyword_identifier_strings_error.kdl.kdl | 1 - tests/test_cases/input/hash_in_id.kdl | 1 - .../input/illegal_char_in_binary.kdl | 1 - .../test_cases/input/illegal_char_in_hex.kdl | 1 - .../input/illegal_char_in_octal.kdl | 1 - .../input/just_space_in_arg_type.kdl | 1 - .../input/just_space_in_node_type.kdl | 1 - .../input/just_space_in_prop_type.kdl | 1 - tests/test_cases/input/just_type_no_arg.kdl | 1 - .../test_cases/input/just_type_no_node_id.kdl | 1 - tests/test_cases/input/just_type_no_prop.kdl | 1 - ...ng_non_matching_prefix_character_error.kdl | 5 - ...string_non_matching_prefix_count_error.kdl | 5 - .../multiline_raw_string_single_line_err.kdl | 1 - .../multiline_raw_string_single_quote_err.kdl | 5 - ...ng_non_matching_prefix_character_error.kdl | 5 - ...string_non_matching_prefix_count_error.kdl | 5 - .../multiline_string_single_line_err.kdl | 1 - .../multiline_string_single_quote_err.kdl | 5 - .../multiline_string_whitespace_only.kdl | 11 +- ...itespace_only_non_matching_prefix_fail.kdl | 19 ++ .../input/multiple_dots_in_float.kdl | 1 - ...multiple_dots_in_float_before_exponent.kdl | 1 - .../test_cases/input/multiple_es_in_float.kdl | 1 - tests/test_cases/input/multiple_x_in_hex.kdl | 1 - tests/test_cases/input/no_digits_in_hex.kdl | 1 - tests/test_cases/input/no_integer_digit.kdl | 1 - tests/test_cases/input/no_solidus_escape.kdl | 1 - tests/test_cases/input/null_prop_key.kdl | 1 - tests/test_cases/input/parens_in_bare_id.kdl | 1 - tests/test_cases/input/quote_in_bare_id.kdl | 1 - .../input/raw_string_just_quote.kdl | 1 - tests/test_cases/input/slash_in_bare_id.kdl | 1 - ...slashdash_child_block_before_entry_err.kdl | 5 - .../input/square_bracket_in_bare_id.kdl | 1 - tests/test_cases/input/true_prop_key.kdl | 1 - .../test_cases/input/type_before_prop_key.kdl | 1 - .../input/unbalanced_raw_hashes.kdl | 1 - .../input/underscore_at_start_of_fraction.kdl | 1 - .../input/underscore_at_start_of_hex.kdl | 1 - tests/test_cases/input/unicode_delete.kdl | 2 - tests/test_cases/input/unicode_fsi.kdl | 2 - tests/test_cases/input/unicode_lre.kdl | 2 - tests/test_cases/input/unicode_lri.kdl | 2 - tests/test_cases/input/unicode_lrm.kdl | 2 - tests/test_cases/input/unicode_lro.kdl | 2 - tests/test_cases/input/unicode_pdf.kdl | 2 - tests/test_cases/input/unicode_pdi.kdl | 2 - tests/test_cases/input/unicode_rle.kdl | 2 - tests/test_cases/input/unicode_rli.kdl | 2 - tests/test_cases/input/unicode_rlm.kdl | 2 - tests/test_cases/input/unicode_rlo.kdl | 2 - tests/test_cases/input/unicode_under_0x20.kdl | 2 - .../input/unterminated_empty_node.kdl | 1 - tests/test_cases/input/zero_arg.kdl | 1 - 72 files changed, 143 insertions(+), 159 deletions(-) delete mode 100644 tests/test_cases/expected_kdl/raw_string_just_quote.kdl delete mode 100644 tests/test_cases/expected_kdl/zero_arg.kdl delete mode 100644 tests/test_cases/input/bare_ident_numeric.kdl delete mode 100644 tests/test_cases/input/bare_ident_numeric_dot.kdl delete mode 100644 tests/test_cases/input/bare_ident_numeric_sign.kdl delete mode 100644 tests/test_cases/input/bom_later.kdl delete mode 100644 tests/test_cases/input/brackets_in_bare_id.kdl delete mode 100644 tests/test_cases/input/dot_but_no_fraction.kdl delete mode 100644 tests/test_cases/input/dot_but_no_fraction_before_exponent.kdl delete mode 100644 tests/test_cases/input/dot_in_exponent.kdl delete mode 100644 tests/test_cases/input/dot_zero.kdl delete mode 100644 tests/test_cases/input/empty_arg_type.kdl delete mode 100644 tests/test_cases/input/empty_node_type.kdl delete mode 100644 tests/test_cases/input/empty_prop_type.kdl delete mode 100644 tests/test_cases/input/err_backslash_in_bare_id.kdl delete mode 100644 tests/test_cases/input/false_prop_key.kdl delete mode 100644 tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl delete mode 100644 tests/test_cases/input/hash_in_id.kdl delete mode 100644 tests/test_cases/input/illegal_char_in_binary.kdl delete mode 100644 tests/test_cases/input/illegal_char_in_hex.kdl delete mode 100644 tests/test_cases/input/illegal_char_in_octal.kdl delete mode 100644 tests/test_cases/input/just_space_in_arg_type.kdl delete mode 100644 tests/test_cases/input/just_space_in_node_type.kdl delete mode 100644 tests/test_cases/input/just_space_in_prop_type.kdl delete mode 100644 tests/test_cases/input/just_type_no_arg.kdl delete mode 100644 tests/test_cases/input/just_type_no_node_id.kdl delete mode 100644 tests/test_cases/input/just_type_no_prop.kdl delete mode 100644 tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl delete mode 100644 tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl delete mode 100644 tests/test_cases/input/multiline_raw_string_single_line_err.kdl delete mode 100644 tests/test_cases/input/multiline_raw_string_single_quote_err.kdl delete mode 100644 tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl delete mode 100644 tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl delete mode 100644 tests/test_cases/input/multiline_string_single_line_err.kdl delete mode 100644 tests/test_cases/input/multiline_string_single_quote_err.kdl create mode 100644 tests/test_cases/input/multiline_string_whitespace_only_non_matching_prefix_fail.kdl delete mode 100644 tests/test_cases/input/multiple_dots_in_float.kdl delete mode 100644 tests/test_cases/input/multiple_dots_in_float_before_exponent.kdl delete mode 100644 tests/test_cases/input/multiple_es_in_float.kdl delete mode 100644 tests/test_cases/input/multiple_x_in_hex.kdl delete mode 100644 tests/test_cases/input/no_digits_in_hex.kdl delete mode 100644 tests/test_cases/input/no_integer_digit.kdl delete mode 100644 tests/test_cases/input/no_solidus_escape.kdl delete mode 100644 tests/test_cases/input/null_prop_key.kdl delete mode 100644 tests/test_cases/input/parens_in_bare_id.kdl delete mode 100644 tests/test_cases/input/quote_in_bare_id.kdl delete mode 100644 tests/test_cases/input/raw_string_just_quote.kdl delete mode 100644 tests/test_cases/input/slash_in_bare_id.kdl delete mode 100644 tests/test_cases/input/slashdash_child_block_before_entry_err.kdl delete mode 100644 tests/test_cases/input/square_bracket_in_bare_id.kdl delete mode 100644 tests/test_cases/input/true_prop_key.kdl delete mode 100644 tests/test_cases/input/type_before_prop_key.kdl delete mode 100644 tests/test_cases/input/unbalanced_raw_hashes.kdl delete mode 100644 tests/test_cases/input/underscore_at_start_of_fraction.kdl delete mode 100644 tests/test_cases/input/underscore_at_start_of_hex.kdl delete mode 100644 tests/test_cases/input/unicode_delete.kdl delete mode 100644 tests/test_cases/input/unicode_fsi.kdl delete mode 100644 tests/test_cases/input/unicode_lre.kdl delete mode 100644 tests/test_cases/input/unicode_lri.kdl delete mode 100644 tests/test_cases/input/unicode_lrm.kdl delete mode 100644 tests/test_cases/input/unicode_lro.kdl delete mode 100644 tests/test_cases/input/unicode_pdf.kdl delete mode 100644 tests/test_cases/input/unicode_pdi.kdl delete mode 100644 tests/test_cases/input/unicode_rle.kdl delete mode 100644 tests/test_cases/input/unicode_rli.kdl delete mode 100644 tests/test_cases/input/unicode_rlm.kdl delete mode 100644 tests/test_cases/input/unicode_rlo.kdl delete mode 100644 tests/test_cases/input/unicode_under_0x20.kdl delete mode 100644 tests/test_cases/input/unterminated_empty_node.kdl delete mode 100644 tests/test_cases/input/zero_arg.kdl diff --git a/src/v2_parser.rs b/src/v2_parser.rs index dfced19..8a3d3cd 100644 --- a/src/v2_parser.rs +++ b/src/v2_parser.rs @@ -882,9 +882,8 @@ fn node_space1(input: &mut Input<'_>) -> PResult<()> { repeat(1.., node_space).parse_next(input) } -/// `string := identifier-string | quoted-string | raw-string` +/// string := identifier-string | quoted-string | raw-string ¶ pub(crate) fn string(input: &mut Input<'_>) -> PResult> { - // TODO: shouldn't put the `resume_after_cut`s here, because they mess with context from higher levels. trace( "string", alt(( @@ -1018,32 +1017,65 @@ fn equals_sign(input: &mut Input<'_>) -> PResult<()> { } /// ```text -/// quoted-string := '"' single-line-string-body '"' | '"""' newline multi-line-string-body newline unicode-space*) '"""' +/// quoted-string := '"' single-line-string-body '"' | '"""' newline multi-line-string-body newline (unicode-space | ('\' (unicode-space | newline)+)*) '"""' /// single-line-string-body := (string-character - newline)* -/// multi-line-string-body := string-character* +/// multi-line-string-body := (('"' | '""')? string-character)* /// ``` -fn quoted_string<'s>(input: &mut Input<'s>) -> PResult { - let quotes = alt((("\"\"\"", newline).take(), "\"")).parse_next(input)?; +fn quoted_string(input: &mut Input<'_>) -> PResult { + let quotes = + alt(( + ( + "\"\"\"", + cut_err(newline).context(cx().lbl("multi-line string newline").msg( + "Multi-line string opening quotes must be immediately followed by a newline", + )), + ) + .take(), + "\"", + )) + .parse_next(input)?; let is_multiline = quotes.len() > 1; let ml_prefix: Option = if is_multiline { Some( - peek(preceded( + cut_err(peek(preceded( repeat_till( 0.., ( - repeat(0.., (not(newline), opt(ws_escape), string_char)).map(|()| ()), + repeat( + 0.., + ( + not(newline), + alt(( + ws_escape.void(), + trace( + "valid string body char(s)", + alt(( + ('\"', not("\"\"")).void(), + ('\"', not("\"")).void(), + string_char.void(), + )), + ) + .void(), + )), + ), + ) + .map(|()| ()), newline, ), peek(terminated( - repeat(0.., unicode_space).map(|()| ()), + repeat(0.., alt((ws_escape, unicode_space))).map(|()| ()), "\"\"\"", )), ) .map(|((), ())| ()), - terminated(repeat(0.., unicode_space).map(|()| ()).take(), "\"\"\""), - )) - .parse_next(input)? - .to_string(), + terminated( + repeat(0.., alt((ws_escape.map(|_| ""), unicode_space.take()))) + .map(|s: String| s), + "\"\"\"", + ), + ))) + .context(cx().lbl("multi-line string")) + .parse_next(input)?, ) } else { None @@ -1052,30 +1084,40 @@ fn quoted_string<'s>(input: &mut Input<'s>) -> PResult { let parser = repeat_till( 0.., ( - cut_err(alt((&prefix[..], peek(newline).take()))) + cut_err(alt(((&prefix[..]).void(), peek(empty_line).void()))) .context(cx().msg("matching multiline string prefix").lbl("bad prefix").hlp("Multi-line string bodies must be prefixed by the exact same whitespace as the leading whitespace before the closing '\"\"\"'")), alt(( - newline.take().map(|_| "\n".to_string()), + empty_line.map(|s| s.to_string()), repeat_till( 0.., - (not(newline), opt(ws_escape), string_char).map(|(_, _, s)| s), + ( + not(newline), + alt(( + ws_escape.map(|_| None), + alt(( + ('\"', not("\"\"")).map(|(c, ())| Some(c)), + ('\"', not("\"")).map(|(c, ())| Some(c)), + string_char.map(Some), + )) + )) + ).map(|(_, c)| c), newline, ) // multiline string literal newlines are normalized to `\n` - .map(|(s, _): (String, _)| format!("{s}\n")), + .map(|(cs, _): (Vec>, _)| cs.into_iter().flatten().chain(vec!['\n']).collect::()), )), ) .map(|(_, s)| s), ( &prefix[..], - repeat(0.., unicode_space).map(|()| ()).take(), + repeat(0.., ws_escape.void()).map(|()| ()), peek("\"\"\""), ), ) .map(|(s, _): (Vec, (_, _, _))| { let mut s = s.join(""); // Slice off the `\n` at the end of the last line. - s.truncate(s.len() - 1); + s.truncate(s.len().saturating_sub(1)); s }) .context(cx().lbl("multi-line quoted string")); @@ -1090,13 +1132,14 @@ fn quoted_string<'s>(input: &mut Input<'s>) -> PResult { .hlp("You can make a string multi-line by wrapping it in '\"\"\"', with a newline immediately after the opening quotes."), ), ), - opt(ws_escape), - string_char, - ) - .map(|(_, _, s)| s), - (repeat(0.., unicode_space).map(|()| ()).take(), peek("\"")), + alt(( + ws_escape.map(|_| None), + string_char.map(Some), + )) + ).map(|(_, c)| c), + peek("\"") ) - .map(|(s, (end, _)): (String, (&'s str, _))| format!("{s}{end}")) + .map(|(cs, _): (Vec>, _)| cs.into_iter().flatten().collect::()) .context(cx().lbl("quoted string")); cut_err(parser).parse_next(input)? }; @@ -1112,8 +1155,19 @@ fn quoted_string<'s>(input: &mut Input<'s>) -> PResult { Ok(KdlValue::String(body)) } +fn empty_line(input: &mut Input<'_>) -> PResult<&'static str> { + repeat(0.., alt((ws_escape.void(), unicode_space.void()))) + .map(|()| ()) + .parse_next(input)?; + newline.parse_next(input)?; + Ok("\n") +} + /// Like badval, but is able to slurp up invalid raw strings, which contain whitespace. fn quoted_string_badval(input: &mut Input<'_>) -> PResult<()> { + // TODO(@zkat): this should have different behavior based on whether we're + // resuming a single or multi-line string. Right now, multi-liners end up + // with silly errors. ( repeat_till( 0.., @@ -1135,19 +1189,25 @@ fn quoted_string_terminator(input: &mut Input<'_>) -> PResult<()> { /// ``` fn string_char(input: &mut Input<'_>) -> PResult { alt(( - escaped_char, - (not(disallowed_unicode), none_of(['\\', '"'])).map(|(_, c)| c), + trace("escaped char", escaped_char), + trace( + "regular string char", + (not(disallowed_unicode), none_of(['\\', '"'])).map(|(_, c)| c), + ), )) .parse_next(input) } fn ws_escape(input: &mut Input<'_>) -> PResult<()> { - ( - "\\", - repeat(1.., alt((unicode_space, newline))).map(|()| ()), + trace( + "ws_escape", + ( + "\\", + repeat(1.., alt((unicode_space, newline))).map(|()| ()), + ), ) - .void() - .parse_next(input) + .void() + .parse_next(input) } /// ```text @@ -1182,10 +1242,13 @@ fn escaped_char(input: &mut Input<'_>) -> PResult { .parse_next(input) } -/// `raw-string := '#' raw-string-quotes '#' | '#' raw-string '#'` -/// `raw-string-quotes := '"' single-line-raw-string-body '"' | '"""' newline multi-line-raw-string-body newline unicode-space*) '"""'` -/// `single-line-raw-string-body := (unicode - newline - disallowed-literal-code-points)*` -/// `multi-line-raw-string-body := (unicode - disallowed-literal-code-points)` +/// ```text +/// raw-string := '#' raw-string-quotes '#' | '#' raw-string '#' +/// raw-string-quotes := '"' single-line-raw-string-body '"' | '"""' newline multi-line-raw-string-body '"""' +/// single-line-raw-string-body := '' | (single-line-raw-string-char - '"') single-line-raw-string-char*? | '"' (single-line-raw-string-char - '"') single-line-raw-string-char*? +/// single-line-raw-string-char := unicode - newline - disallowed-literal-code-points +/// multi-line-raw-string-body := (unicode - disallowed-literal-code-points)*? +/// ``` fn raw_string(input: &mut Input<'_>) -> PResult { let hashes: String = repeat(1.., "#").parse_next(input)?; let quotes = alt((("\"\"\"", newline).take(), "\"")).parse_next(input)?; @@ -1229,10 +1292,10 @@ fn raw_string(input: &mut Input<'_>) -> PResult { repeat_till( 0.., ( - cut_err(alt((&prefix[..], peek(newline).take()))) + cut_err(alt(((&prefix[..]).void(), peek(empty_line).void()))) .context(cx().lbl("matching multiline raw string prefix")), alt(( - newline.take().map(|_| "\n".to_string()), + empty_line.map(|s| s.to_string()), repeat_till( 0.., (not(newline), not(("\"\"\"", &hashes[..])), any) @@ -1254,7 +1317,7 @@ fn raw_string(input: &mut Input<'_>) -> PResult { .map(|(s, _): (Vec, (_, _, _))| { let mut s = s.join(""); // Slice off the `\n` at the end of the last line. - s.truncate(s.len() - 1); + s.truncate(s.len().saturating_sub(1)); s }) .parse_next(input)? @@ -1311,7 +1374,7 @@ mod string_tests { } #[test] - fn quoted_string() { + fn single_line_quoted_string() { assert_eq!( string.parse(new_input("\"foo\"")).unwrap(), Some(KdlValue::String("foo".into())) @@ -1363,6 +1426,14 @@ mod string_tests { Some(KdlValue::String("\nstring\t".into())), "Empty line without any indentation" ); + assert_eq!( + string + .parse(new_input("\"\"\"\n   \\\n   \n   \"\"\"")) + .unwrap(), + Some(KdlValue::String("".into())), + "Escaped whitespace with proper prefix" + ); + assert!(string .parse(new_input("\"\"\"\nfoo\n bar\n baz\n \"\"\"")) .is_err()); @@ -1491,9 +1562,9 @@ fn disallowed_unicode(input: &mut Input<'_>) -> PResult<()> { /// `escline := '\\' ws* (single-line-comment | newline | eof)` fn escline(input: &mut Input<'_>) -> PResult<()> { "\\".parse_next(input)?; - repeat(0.., ws).map(|_: ()| ()).parse_next(input)?; + wss.parse_next(input)?; alt((single_line_comment, newline, eof.void())).parse_next(input)?; - repeat(0.., ws).map(|_: ()| ()).parse_next(input) + wss.parse_next(input) } #[cfg(test)] @@ -1596,9 +1667,12 @@ fn multi_line_comment_test() { .is_ok()); } -/// slashdash := '/-' line-space* +/// slashdash := '/-' (node-space | line-space)* fn slashdash(input: &mut Input<'_>) -> PResult<()> { - ("/-", repeat(0.., line_space).map(|()| ())) + ( + "/-", + repeat(0.., alt((node_space, line_space))).map(|()| ()), + ) .void() .parse_next(input) } diff --git a/tests/test_cases/expected_kdl/raw_string_just_quote.kdl b/tests/test_cases/expected_kdl/raw_string_just_quote.kdl deleted file mode 100644 index 0a76315..0000000 --- a/tests/test_cases/expected_kdl/raw_string_just_quote.kdl +++ /dev/null @@ -1 +0,0 @@ -node "\"" diff --git a/tests/test_cases/expected_kdl/zero_arg.kdl b/tests/test_cases/expected_kdl/zero_arg.kdl deleted file mode 100644 index 74405b6..0000000 --- a/tests/test_cases/expected_kdl/zero_arg.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0 diff --git a/tests/test_cases/input/bare_ident_numeric.kdl b/tests/test_cases/input/bare_ident_numeric.kdl deleted file mode 100644 index 053af21..0000000 --- a/tests/test_cases/input/bare_ident_numeric.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0n \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_numeric_dot.kdl b/tests/test_cases/input/bare_ident_numeric_dot.kdl deleted file mode 100644 index b97afcf..0000000 --- a/tests/test_cases/input/bare_ident_numeric_dot.kdl +++ /dev/null @@ -1 +0,0 @@ -node .0n \ No newline at end of file diff --git a/tests/test_cases/input/bare_ident_numeric_sign.kdl b/tests/test_cases/input/bare_ident_numeric_sign.kdl deleted file mode 100644 index 6cadc35..0000000 --- a/tests/test_cases/input/bare_ident_numeric_sign.kdl +++ /dev/null @@ -1 +0,0 @@ -node +0n \ No newline at end of file diff --git a/tests/test_cases/input/bom_later.kdl b/tests/test_cases/input/bom_later.kdl deleted file mode 100644 index 6aeff8d..0000000 --- a/tests/test_cases/input/bom_later.kdl +++ /dev/null @@ -1 +0,0 @@ -node arg diff --git a/tests/test_cases/input/brackets_in_bare_id.kdl b/tests/test_cases/input/brackets_in_bare_id.kdl deleted file mode 100644 index ebb78d2..0000000 --- a/tests/test_cases/input/brackets_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123{bar}foo weeee diff --git a/tests/test_cases/input/dot_but_no_fraction.kdl b/tests/test_cases/input/dot_but_no_fraction.kdl deleted file mode 100644 index 48553fc..0000000 --- a/tests/test_cases/input/dot_but_no_fraction.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1. \ No newline at end of file diff --git a/tests/test_cases/input/dot_but_no_fraction_before_exponent.kdl b/tests/test_cases/input/dot_but_no_fraction_before_exponent.kdl deleted file mode 100644 index 8fb8fb8..0000000 --- a/tests/test_cases/input/dot_but_no_fraction_before_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1.e7 \ No newline at end of file diff --git a/tests/test_cases/input/dot_in_exponent.kdl b/tests/test_cases/input/dot_in_exponent.kdl deleted file mode 100644 index fab0d78..0000000 --- a/tests/test_cases/input/dot_in_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1.0.0 \ No newline at end of file diff --git a/tests/test_cases/input/dot_zero.kdl b/tests/test_cases/input/dot_zero.kdl deleted file mode 100644 index e8c0592..0000000 --- a/tests/test_cases/input/dot_zero.kdl +++ /dev/null @@ -1 +0,0 @@ -node .0 \ No newline at end of file diff --git a/tests/test_cases/input/empty_arg_type.kdl b/tests/test_cases/input/empty_arg_type.kdl deleted file mode 100644 index bf22b6d..0000000 --- a/tests/test_cases/input/empty_arg_type.kdl +++ /dev/null @@ -1 +0,0 @@ -node ()10 diff --git a/tests/test_cases/input/empty_node_type.kdl b/tests/test_cases/input/empty_node_type.kdl deleted file mode 100644 index e4163c0..0000000 --- a/tests/test_cases/input/empty_node_type.kdl +++ /dev/null @@ -1 +0,0 @@ -()node diff --git a/tests/test_cases/input/empty_prop_type.kdl b/tests/test_cases/input/empty_prop_type.kdl deleted file mode 100644 index 233480b..0000000 --- a/tests/test_cases/input/empty_prop_type.kdl +++ /dev/null @@ -1 +0,0 @@ -node key=()#false diff --git a/tests/test_cases/input/err_backslash_in_bare_id.kdl b/tests/test_cases/input/err_backslash_in_bare_id.kdl deleted file mode 100644 index 2ea1a4b..0000000 --- a/tests/test_cases/input/err_backslash_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123\bar weeee diff --git a/tests/test_cases/input/false_prop_key.kdl b/tests/test_cases/input/false_prop_key.kdl deleted file mode 100644 index a032c0b..0000000 --- a/tests/test_cases/input/false_prop_key.kdl +++ /dev/null @@ -1 +0,0 @@ -node false=1 diff --git a/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl b/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl deleted file mode 100644 index e120167..0000000 --- a/tests/test_cases/input/floating_point_keyword_identifier_strings_error.kdl.kdl +++ /dev/null @@ -1 +0,0 @@ -floats inf -inf nan diff --git a/tests/test_cases/input/hash_in_id.kdl b/tests/test_cases/input/hash_in_id.kdl deleted file mode 100644 index e1119be..0000000 --- a/tests/test_cases/input/hash_in_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo#bar weee diff --git a/tests/test_cases/input/illegal_char_in_binary.kdl b/tests/test_cases/input/illegal_char_in_binary.kdl deleted file mode 100644 index 1f4bd50..0000000 --- a/tests/test_cases/input/illegal_char_in_binary.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0bx01 diff --git a/tests/test_cases/input/illegal_char_in_hex.kdl b/tests/test_cases/input/illegal_char_in_hex.kdl deleted file mode 100644 index b55e1a6..0000000 --- a/tests/test_cases/input/illegal_char_in_hex.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0x10g10 \ No newline at end of file diff --git a/tests/test_cases/input/illegal_char_in_octal.kdl b/tests/test_cases/input/illegal_char_in_octal.kdl deleted file mode 100644 index 4e36196..0000000 --- a/tests/test_cases/input/illegal_char_in_octal.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0o45678 \ No newline at end of file diff --git a/tests/test_cases/input/just_space_in_arg_type.kdl b/tests/test_cases/input/just_space_in_arg_type.kdl deleted file mode 100644 index 38c9217..0000000 --- a/tests/test_cases/input/just_space_in_arg_type.kdl +++ /dev/null @@ -1 +0,0 @@ -node ( )false diff --git a/tests/test_cases/input/just_space_in_node_type.kdl b/tests/test_cases/input/just_space_in_node_type.kdl deleted file mode 100644 index 8fb5d89..0000000 --- a/tests/test_cases/input/just_space_in_node_type.kdl +++ /dev/null @@ -1 +0,0 @@ -( )node diff --git a/tests/test_cases/input/just_space_in_prop_type.kdl b/tests/test_cases/input/just_space_in_prop_type.kdl deleted file mode 100644 index e42645f..0000000 --- a/tests/test_cases/input/just_space_in_prop_type.kdl +++ /dev/null @@ -1 +0,0 @@ -node key=( )0x10 diff --git a/tests/test_cases/input/just_type_no_arg.kdl b/tests/test_cases/input/just_type_no_arg.kdl deleted file mode 100644 index a36c881..0000000 --- a/tests/test_cases/input/just_type_no_arg.kdl +++ /dev/null @@ -1 +0,0 @@ -node (type) diff --git a/tests/test_cases/input/just_type_no_node_id.kdl b/tests/test_cases/input/just_type_no_node_id.kdl deleted file mode 100644 index 9b03c44..0000000 --- a/tests/test_cases/input/just_type_no_node_id.kdl +++ /dev/null @@ -1 +0,0 @@ -(type) diff --git a/tests/test_cases/input/just_type_no_prop.kdl b/tests/test_cases/input/just_type_no_prop.kdl deleted file mode 100644 index eab7fc6..0000000 --- a/tests/test_cases/input/just_type_no_prop.kdl +++ /dev/null @@ -1 +0,0 @@ -node key=(type) diff --git a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl deleted file mode 100644 index bec4d2e..0000000 --- a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_character_error.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node #""" - hey - everyone - how goes? - """# diff --git a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl b/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl deleted file mode 100644 index 06e7a05..0000000 --- a/tests/test_cases/input/multiline_raw_string_non_matching_prefix_count_error.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node #""" - hey - everyone - how goes? - """# diff --git a/tests/test_cases/input/multiline_raw_string_single_line_err.kdl b/tests/test_cases/input/multiline_raw_string_single_line_err.kdl deleted file mode 100644 index e542c02..0000000 --- a/tests/test_cases/input/multiline_raw_string_single_line_err.kdl +++ /dev/null @@ -1 +0,0 @@ -node #"""one line"""# \ No newline at end of file diff --git a/tests/test_cases/input/multiline_raw_string_single_quote_err.kdl b/tests/test_cases/input/multiline_raw_string_single_quote_err.kdl deleted file mode 100644 index eaa212e..0000000 --- a/tests/test_cases/input/multiline_raw_string_single_quote_err.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node #" -hey -everyone -how goes? -"# diff --git a/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl b/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl deleted file mode 100644 index e46e8d1..0000000 --- a/tests/test_cases/input/multiline_string_non_matching_prefix_character_error.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node """ - hey - everyone - how goes? - """ diff --git a/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl b/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl deleted file mode 100644 index 9cc70b1..0000000 --- a/tests/test_cases/input/multiline_string_non_matching_prefix_count_error.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node """ - hey - everyone - how goes? - """ diff --git a/tests/test_cases/input/multiline_string_single_line_err.kdl b/tests/test_cases/input/multiline_string_single_line_err.kdl deleted file mode 100644 index ee36794..0000000 --- a/tests/test_cases/input/multiline_string_single_line_err.kdl +++ /dev/null @@ -1 +0,0 @@ -node """one line""" \ No newline at end of file diff --git a/tests/test_cases/input/multiline_string_single_quote_err.kdl b/tests/test_cases/input/multiline_string_single_quote_err.kdl deleted file mode 100644 index e3a6cc1..0000000 --- a/tests/test_cases/input/multiline_string_single_quote_err.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node " -hey -everyone -how goes? -" diff --git a/tests/test_cases/input/multiline_string_whitespace_only.kdl b/tests/test_cases/input/multiline_string_whitespace_only.kdl index d3bd045..db8fee5 100644 --- a/tests/test_cases/input/multiline_string_whitespace_only.kdl +++ b/tests/test_cases/input/multiline_string_whitespace_only.kdl @@ -1,18 +1,19 @@ // This file deliberately contains unusual whitespace -// The first two strings are empty +// The first three strings are empty, because whitespace-only lines collapse to +// just `\n`. node """   """ """    \ -    +        """ """ -    +      """\ \ // The next two strings contains only whitespace """    - +       \s    """ #""" -     +      """# diff --git a/tests/test_cases/input/multiline_string_whitespace_only_non_matching_prefix_fail.kdl b/tests/test_cases/input/multiline_string_whitespace_only_non_matching_prefix_fail.kdl new file mode 100644 index 0000000..29e36df --- /dev/null +++ b/tests/test_cases/input/multiline_string_whitespace_only_non_matching_prefix_fail.kdl @@ -0,0 +1,19 @@ +// This file deliberately contains unusual whitespace +// Parsing should fail because not all strings have a matching multiline prefix, +// which must be exact, down to the codepoint, _before_ newline normalization. +node """ +  """ """ +   \ +    +   """ """ +    + """\ + \ // The next two strings contains only whitespace + """ +    + +    \s +    """ #""" +     + + """# diff --git a/tests/test_cases/input/multiple_dots_in_float.kdl b/tests/test_cases/input/multiple_dots_in_float.kdl deleted file mode 100644 index fab0d78..0000000 --- a/tests/test_cases/input/multiple_dots_in_float.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1.0.0 \ No newline at end of file diff --git a/tests/test_cases/input/multiple_dots_in_float_before_exponent.kdl b/tests/test_cases/input/multiple_dots_in_float_before_exponent.kdl deleted file mode 100644 index 434af05..0000000 --- a/tests/test_cases/input/multiple_dots_in_float_before_exponent.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1.0.0e7 \ No newline at end of file diff --git a/tests/test_cases/input/multiple_es_in_float.kdl b/tests/test_cases/input/multiple_es_in_float.kdl deleted file mode 100644 index 6506c5c..0000000 --- a/tests/test_cases/input/multiple_es_in_float.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1.0E10e10 diff --git a/tests/test_cases/input/multiple_x_in_hex.kdl b/tests/test_cases/input/multiple_x_in_hex.kdl deleted file mode 100644 index 013d805..0000000 --- a/tests/test_cases/input/multiple_x_in_hex.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0xx10 \ No newline at end of file diff --git a/tests/test_cases/input/no_digits_in_hex.kdl b/tests/test_cases/input/no_digits_in_hex.kdl deleted file mode 100644 index 700e453..0000000 --- a/tests/test_cases/input/no_digits_in_hex.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0x \ No newline at end of file diff --git a/tests/test_cases/input/no_integer_digit.kdl b/tests/test_cases/input/no_integer_digit.kdl deleted file mode 100644 index bac8026..0000000 --- a/tests/test_cases/input/no_integer_digit.kdl +++ /dev/null @@ -1 +0,0 @@ -node .1 \ No newline at end of file diff --git a/tests/test_cases/input/no_solidus_escape.kdl b/tests/test_cases/input/no_solidus_escape.kdl deleted file mode 100644 index 2dbc2d1..0000000 --- a/tests/test_cases/input/no_solidus_escape.kdl +++ /dev/null @@ -1 +0,0 @@ -node "\/" diff --git a/tests/test_cases/input/null_prop_key.kdl b/tests/test_cases/input/null_prop_key.kdl deleted file mode 100644 index 6896d42..0000000 --- a/tests/test_cases/input/null_prop_key.kdl +++ /dev/null @@ -1 +0,0 @@ -node null=1 diff --git a/tests/test_cases/input/parens_in_bare_id.kdl b/tests/test_cases/input/parens_in_bare_id.kdl deleted file mode 100644 index ff9b439..0000000 --- a/tests/test_cases/input/parens_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123(bar)foo weeee diff --git a/tests/test_cases/input/quote_in_bare_id.kdl b/tests/test_cases/input/quote_in_bare_id.kdl deleted file mode 100644 index 0d8a664..0000000 --- a/tests/test_cases/input/quote_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123"bar weeee diff --git a/tests/test_cases/input/raw_string_just_quote.kdl b/tests/test_cases/input/raw_string_just_quote.kdl deleted file mode 100644 index e81bf12..0000000 --- a/tests/test_cases/input/raw_string_just_quote.kdl +++ /dev/null @@ -1 +0,0 @@ -node #"""# diff --git a/tests/test_cases/input/slash_in_bare_id.kdl b/tests/test_cases/input/slash_in_bare_id.kdl deleted file mode 100644 index d26d325..0000000 --- a/tests/test_cases/input/slash_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123/bar weeee diff --git a/tests/test_cases/input/slashdash_child_block_before_entry_err.kdl b/tests/test_cases/input/slashdash_child_block_before_entry_err.kdl deleted file mode 100644 index b9edfc3..0000000 --- a/tests/test_cases/input/slashdash_child_block_before_entry_err.kdl +++ /dev/null @@ -1,5 +0,0 @@ -node /-{ - child -} foo { - bar -} diff --git a/tests/test_cases/input/square_bracket_in_bare_id.kdl b/tests/test_cases/input/square_bracket_in_bare_id.kdl deleted file mode 100644 index 62f34e2..0000000 --- a/tests/test_cases/input/square_bracket_in_bare_id.kdl +++ /dev/null @@ -1 +0,0 @@ -foo123[bar]foo weeee diff --git a/tests/test_cases/input/true_prop_key.kdl b/tests/test_cases/input/true_prop_key.kdl deleted file mode 100644 index e88c36f..0000000 --- a/tests/test_cases/input/true_prop_key.kdl +++ /dev/null @@ -1 +0,0 @@ -node true=1 diff --git a/tests/test_cases/input/type_before_prop_key.kdl b/tests/test_cases/input/type_before_prop_key.kdl deleted file mode 100644 index 1b19b0d..0000000 --- a/tests/test_cases/input/type_before_prop_key.kdl +++ /dev/null @@ -1 +0,0 @@ -node (type)key=10 diff --git a/tests/test_cases/input/unbalanced_raw_hashes.kdl b/tests/test_cases/input/unbalanced_raw_hashes.kdl deleted file mode 100644 index d0213f2..0000000 --- a/tests/test_cases/input/unbalanced_raw_hashes.kdl +++ /dev/null @@ -1 +0,0 @@ -node ##"foo"# diff --git a/tests/test_cases/input/underscore_at_start_of_fraction.kdl b/tests/test_cases/input/underscore_at_start_of_fraction.kdl deleted file mode 100644 index 30fb7cc..0000000 --- a/tests/test_cases/input/underscore_at_start_of_fraction.kdl +++ /dev/null @@ -1 +0,0 @@ -node 1._7 \ No newline at end of file diff --git a/tests/test_cases/input/underscore_at_start_of_hex.kdl b/tests/test_cases/input/underscore_at_start_of_hex.kdl deleted file mode 100644 index 2de0c48..0000000 --- a/tests/test_cases/input/underscore_at_start_of_hex.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0x_10 \ No newline at end of file diff --git a/tests/test_cases/input/unicode_delete.kdl b/tests/test_cases/input/unicode_delete.kdl deleted file mode 100644 index 3fb52ed..0000000 --- a/tests/test_cases/input/unicode_delete.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x007F (Delete) -node1 arg diff --git a/tests/test_cases/input/unicode_fsi.kdl b/tests/test_cases/input/unicode_fsi.kdl deleted file mode 100644 index 7aece14..0000000 --- a/tests/test_cases/input/unicode_fsi.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x2068 -node1 ⁨arg diff --git a/tests/test_cases/input/unicode_lre.kdl b/tests/test_cases/input/unicode_lre.kdl deleted file mode 100644 index 33342ae..0000000 --- a/tests/test_cases/input/unicode_lre.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x202A -node1 ‪arg diff --git a/tests/test_cases/input/unicode_lri.kdl b/tests/test_cases/input/unicode_lri.kdl deleted file mode 100644 index adec826..0000000 --- a/tests/test_cases/input/unicode_lri.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x2066 -node1⁦arg diff --git a/tests/test_cases/input/unicode_lrm.kdl b/tests/test_cases/input/unicode_lrm.kdl deleted file mode 100644 index ff37cad..0000000 --- a/tests/test_cases/input/unicode_lrm.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x200E -node ‎arg diff --git a/tests/test_cases/input/unicode_lro.kdl b/tests/test_cases/input/unicode_lro.kdl deleted file mode 100644 index b084ded..0000000 --- a/tests/test_cases/input/unicode_lro.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x202D -node ‭arg diff --git a/tests/test_cases/input/unicode_pdf.kdl b/tests/test_cases/input/unicode_pdf.kdl deleted file mode 100644 index 9b94fad..0000000 --- a/tests/test_cases/input/unicode_pdf.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x202C -node ‬arg diff --git a/tests/test_cases/input/unicode_pdi.kdl b/tests/test_cases/input/unicode_pdi.kdl deleted file mode 100644 index d92d2d7..0000000 --- a/tests/test_cases/input/unicode_pdi.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x2069 -node ⁩arg diff --git a/tests/test_cases/input/unicode_rle.kdl b/tests/test_cases/input/unicode_rle.kdl deleted file mode 100644 index 3b46610..0000000 --- a/tests/test_cases/input/unicode_rle.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x202B -node1 ‫arg diff --git a/tests/test_cases/input/unicode_rli.kdl b/tests/test_cases/input/unicode_rli.kdl deleted file mode 100644 index 92902ed..0000000 --- a/tests/test_cases/input/unicode_rli.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x2067 -node1 ⁧arg diff --git a/tests/test_cases/input/unicode_rlm.kdl b/tests/test_cases/input/unicode_rlm.kdl deleted file mode 100644 index bfa63c8..0000000 --- a/tests/test_cases/input/unicode_rlm.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x200F -node ‏arg diff --git a/tests/test_cases/input/unicode_rlo.kdl b/tests/test_cases/input/unicode_rlo.kdl deleted file mode 100644 index 98c848b..0000000 --- a/tests/test_cases/input/unicode_rlo.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x202E -node ‮arg diff --git a/tests/test_cases/input/unicode_under_0x20.kdl b/tests/test_cases/input/unicode_under_0x20.kdl deleted file mode 100644 index 967a87a..0000000 --- a/tests/test_cases/input/unicode_under_0x20.kdl +++ /dev/null @@ -1,2 +0,0 @@ -// 0x0019 -node1 arg diff --git a/tests/test_cases/input/unterminated_empty_node.kdl b/tests/test_cases/input/unterminated_empty_node.kdl deleted file mode 100644 index bdc79c5..0000000 --- a/tests/test_cases/input/unterminated_empty_node.kdl +++ /dev/null @@ -1 +0,0 @@ -node { diff --git a/tests/test_cases/input/zero_arg.kdl b/tests/test_cases/input/zero_arg.kdl deleted file mode 100644 index 74405b6..0000000 --- a/tests/test_cases/input/zero_arg.kdl +++ /dev/null @@ -1 +0,0 @@ -node 0