From 159b2ccede0d5559fe3ff9681ccfff314e608b35 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 20 Mar 2020 11:09:51 +0000 Subject: Parse RFC3986 URLs --- dhall/build.rs | 23 +--------------------- dhall/src/syntax/text/dhall.pest.visibility | 2 ++ dhall/src/syntax/text/parser.rs | 22 +++++++++++++++++++-- .../tests/parser/failure/spacing/MergeNoSpace2.txt | 2 +- dhall/tests/parser/failure/unit/UsingToMap.txt | 6 +++--- 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/dhall/build.rs b/dhall/build.rs index e6ed0da..c81b302 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -163,11 +163,6 @@ fn generate_tests() -> std::io::Result<()> { false // Pretty sure the test is incorrect || path == "unit/import/urls/quotedPathFakeUrlEncode" - // TODO: RFC3986 URLs - || path == "unit/import/urls/emptyPath0" - || path == "unit/import/urls/emptyPath1" - || path == "unit/import/urls/emptyPathSegment" - || path == "usingToMap" }), input_type: FileType::Text, output_type: Some(FileType::Binary), @@ -186,14 +181,7 @@ fn generate_tests() -> std::io::Result<()> { directory: "parser/success/", variant: "Printer", too_slow_path: Box::new(|path: &str| path == "largeExpression"), - exclude_path: Box::new(|path: &str| { - false - // TODO: RFC3986 URLs - || path == "unit/import/urls/emptyPath0" - || path == "unit/import/urls/emptyPath1" - || path == "unit/import/urls/emptyPathSegment" - || path == "usingToMap" - }), + exclude_path: Box::new(|_path: &str| false), input_type: FileType::Text, output_type: Some(FileType::Binary), }, @@ -210,11 +198,6 @@ fn generate_tests() -> std::io::Result<()> { || path == "double" || path == "unit/DoubleLitExponentNoDot" || path == "unit/DoubleLitSecretelyInt" - // TODO: RFC3986 URLs - || path == "unit/import/urls/emptyPath0" - || path == "unit/import/urls/emptyPath1" - || path == "unit/import/urls/emptyPathSegment" - || path == "usingToMap" }), input_type: FileType::Text, output_type: Some(FileType::Binary), @@ -373,10 +356,6 @@ fn convert_abnf_to_pest() -> std::io::Result<()> { let mut file = File::create(grammar_path)?; writeln!(&mut file, "// AUTO-GENERATED FILE. See build.rs.")?; - // TODO: this is a cheat; properly support RFC3986 URLs instead - rules.remove("url_path"); - writeln!(&mut file, "url_path = _{{ path }}")?; - // Work around some greediness issue in the grammar. rules.remove("missing"); writeln!( diff --git a/dhall/src/syntax/text/dhall.pest.visibility b/dhall/src/syntax/text/dhall.pest.visibility index 2a89076..b2114ce 100644 --- a/dhall/src/syntax/text/dhall.pest.visibility +++ b/dhall/src/syntax/text/dhall.pest.visibility @@ -120,6 +120,7 @@ home_path absolute_path scheme http_raw +url_path authority # userinfo # host @@ -133,6 +134,7 @@ authority # dec_octet # domain # domainlabel +segment # pchar query # pct_encoded diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs index 5686300..03211c7 100644 --- a/dhall/src/syntax/text/parser.rs +++ b/dhall/src/syntax/text/parser.rs @@ -551,14 +551,14 @@ impl DhallParser { fn http_raw(input: ParseInput) -> ParseResult> { Ok(match_nodes!(input.into_children(); - [scheme(sch), authority(auth), path(p)] => URL { + [scheme(sch), authority(auth), url_path(p)] => URL { scheme: sch, authority: auth, path: p, query: None, headers: None, }, - [scheme(sch), authority(auth), path(p), query(q)] => URL { + [scheme(sch), authority(auth), url_path(p), query(q)] => URL { scheme: sch, authority: auth, path: p, @@ -568,10 +568,28 @@ impl DhallParser { )) } + fn url_path(input: ParseInput) -> ParseResult { + Ok(match_nodes!(input.into_children(); + [path_component(components)..] => { + let mut file_path: Vec<_> = components.collect(); + // An empty path normalizes to "/" + if file_path.is_empty() { + file_path = vec!["".to_owned()]; + } + FilePath { file_path } + } + )) + } + fn authority(input: ParseInput) -> ParseResult { Ok(input.as_str().to_owned()) } + #[alias(path_component)] + fn segment(input: ParseInput) -> ParseResult { + Ok(input.as_str().to_string()) + } + fn query(input: ParseInput) -> ParseResult { Ok(input.as_str().to_owned()) } diff --git a/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt b/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt index 96d937b..77314e0 100644 --- a/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt +++ b/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt @@ -3,4 +3,4 @@ 1 | merge x(y)␊ | ^--- | - = expected missing, double_quote_literal, single_quote_literal, if_, merge, non_empty_list_literal, NaN, Some_, toMap, assert, forall, numeric_double_literal, minus_infinity_literal, plus_infinity_literal, natural_literal, integer_literal, or import_hashed + = expected missing, non_empty_list_literal, double_quote_literal, single_quote_literal, if_, merge, NaN, Some_, toMap, assert, forall, numeric_double_literal, minus_infinity_literal, plus_infinity_literal, natural_literal, integer_literal, or import_hashed diff --git a/dhall/tests/parser/failure/unit/UsingToMap.txt b/dhall/tests/parser/failure/unit/UsingToMap.txt index f6ab2a5..8b1a8aa 100644 --- a/dhall/tests/parser/failure/unit/UsingToMap.txt +++ b/dhall/tests/parser/failure/unit/UsingToMap.txt @@ -1,6 +1,6 @@ - --> 8:20 + --> 8:27 | 8 | https://example.com using toMap { Foo = "Bar" }␊ - | ^--- + | ^--- | - = expected path + = expected import_hashed or primitive_expression -- cgit v1.2.3