From 170eebd7001153a849fbf84c52767240a33c4538 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 16:03:10 +0200 Subject: Rename whitespace rules --- dhall_parser/src/dhall.abnf | 96 ++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 02edc84..025f53a 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -130,9 +130,9 @@ whitespace-chunk = / line-comment / block-comment -whitespace = *whitespace-chunk +whsp = *whitespace-chunk -nonempty-whitespace = 1*whitespace-chunk +whsp1 = 1*whitespace-chunk ; Uppercase or lowercase ASCII letter ALPHA = %x41-5A / %x61-7A @@ -318,7 +318,7 @@ integer-literal = ( "+" / "-" ) natural-literal ; The implementation should recognize reserved names for builtins and treat them as special ; values instead of variables. -identifier = any-label [ whitespace "@" whitespace natural-literal ] +identifier = any-label [ whsp "@" whsp natural-literal ] ; Printable characters other than " ()[]{}<>/\," ; @@ -445,7 +445,7 @@ sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" http = http-raw - [ whitespace using nonempty-whitespace (import-hashed / "(" whitespace import-hashed whitespace ")") ] + [ whsp using whsp1 (import-hashed / "(" whsp import-hashed whsp ")") ] ; Dhall supports unquoted environment variables that are Bash-compliant or ; quoted environment variables that are POSIX-compliant @@ -515,12 +515,12 @@ import-type = missing / local / http / env hash = %x73.68.61.32.35.36.3a 64HEXDIG ; "sha256:XXX...XXX" -import-hashed = import-type [ whitespace hash ] +import-hashed = import-type [ whsp hash ] ; "http://example.com" ; "./foo/bar" ; "env:FOO" -import = import-hashed [ whitespace as nonempty-whitespace Text ] +import = import-hashed [ whsp as whsp1 Text ] ; NOTE: Every rule past this point should only reference rules that end with ; whitespace. This ensures consistent handling of whitespace in the absence of @@ -543,58 +543,58 @@ expression = / annotated-expression ; "\(x : a) -> b" -lambda-expression = lambda whitespace "(" whitespace unreserved-label whitespace ":" nonempty-whitespace expression ")" whitespace arrow whitespace expression +lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression ; "if a then b else c" -ifthenelse-expression = if nonempty-whitespace expression then nonempty-whitespace expression else nonempty-whitespace expression +ifthenelse-expression = if whsp1 expression then whsp1 expression else whsp1 expression ; "let x : t = e1 in e2" ; "let x = e1 in e2" ; "let x = e1 let y = e2 in e3" -let-expression = 1*let-binding in nonempty-whitespace expression -let-binding = let nonempty-whitespace unreserved-label whitespace [ ":" nonempty-whitespace expression ] "=" whitespace expression +let-expression = 1*let-binding in whsp1 expression +let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression ] "=" whsp expression ; "forall (x : a) -> b" -forall-expression = forall whitespace "(" whitespace unreserved-label whitespace ":" nonempty-whitespace expression ")" whitespace arrow whitespace expression +forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression ; "a -> b" -arrow-expression = operator-expression arrow whitespace expression +arrow-expression = operator-expression arrow whsp expression ; "merge e1 e2 : t" ; "merge e1 e2" -merge-expression = merge nonempty-whitespace import-expression whitespace import-expression whitespace [ ":" nonempty-whitespace application-expression ] +merge-expression = merge whsp1 import-expression whsp import-expression whsp [ ":" whsp1 application-expression ] ; "[] : List t" ; "[] : Optional t" ; "[x] : Optional t" -empty-list-or-optional = "[" whitespace (empty-collection / non-empty-optional) -empty-collection = "]" whitespace ":" nonempty-whitespace (List whitespace / Optional whitespace) import-expression whitespace -non-empty-optional = expression "]" whitespace ":" nonempty-whitespace Optional whitespace import-expression whitespace +empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional) +empty-collection = "]" whsp ":" whsp1 (List whsp / Optional whsp) import-expression whsp +non-empty-optional = expression "]" whsp ":" whsp1 Optional whsp import-expression whsp ; "x : t" -annotated-expression = operator-expression [ ":" nonempty-whitespace expression ] +annotated-expression = operator-expression [ ":" whsp1 expression ] operator-expression = import-alt-expression -import-alt-expression = or-expression *("?" nonempty-whitespace or-expression) -or-expression = plus-expression *("||" whitespace plus-expression ) -plus-expression = text-append-expression *("+" nonempty-whitespace text-append-expression ) -text-append-expression = list-append-expression *("++" whitespace list-append-expression ) -list-append-expression = and-expression *("#" whitespace and-expression ) -and-expression = combine-expression *("&&" whitespace combine-expression ) -combine-expression = prefer-expression *(combine whitespace prefer-expression ) -prefer-expression = combine-types-expression *(prefer whitespace combine-types-expression) -combine-types-expression = times-expression *(combine-types whitespace times-expression ) -times-expression = equal-expression *("*" whitespace equal-expression ) -equal-expression = not-equal-expression *("==" whitespace not-equal-expression ) -not-equal-expression = application-expression *("!=" whitespace application-expression ) +import-alt-expression = or-expression *("?" whsp1 or-expression) +or-expression = plus-expression *("||" whsp plus-expression ) +plus-expression = text-append-expression *("+" whsp1 text-append-expression ) +text-append-expression = list-append-expression *("++" whsp list-append-expression ) +list-append-expression = and-expression *("#" whsp and-expression ) +and-expression = combine-expression *("&&" whsp combine-expression ) +combine-expression = prefer-expression *(combine whsp prefer-expression ) +prefer-expression = combine-types-expression *(prefer whsp combine-types-expression) +combine-types-expression = times-expression *(combine-types whsp times-expression ) +times-expression = equal-expression *("*" whsp equal-expression ) +equal-expression = not-equal-expression *("==" whsp not-equal-expression ) +not-equal-expression = application-expression *("!=" whsp application-expression ) ; Import expressions need to be separated by some whitespace, otherwise there ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`", ; or "apply the import `./a` to label `b`" application-expression = - import-expression *(nonempty-whitespace import-expression) whitespace + import-expression *(whsp1 import-expression) whsp import-expression = import @@ -607,17 +607,17 @@ import-expression = ; can't tell from parsing just the period whether "foo." will become "foo.bar" ; (i.e. accessing field `bar` of the record `foo`) or `foo./bar` (i.e. applying ; the function `foo` to the relative path `./bar`) -selector-expression = primitive-expression *(whitespace "." whitespace selector) +selector-expression = primitive-expression *(whsp "." whsp selector) selector = any-label / labels -labels = "{" whitespace [ any-label whitespace *("," whitespace any-label whitespace) ] "}" +labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}" primitive-expression = literal-expression - / "{" whitespace record-type-or-literal "}" - / "<" whitespace union-type-or-literal ">" + / "{" whsp record-type-or-literal "}" + / "<" whsp union-type-or-literal ">" / non-empty-list-literal / parenthesized-expression @@ -656,14 +656,14 @@ record-type-or-literal = empty-record-literal / non-empty-record-type-or-literal / empty-record-type -empty-record-literal = "=" whitespace +empty-record-literal = "=" whsp empty-record-type = "" non-empty-record-type-or-literal = - any-label whitespace (non-empty-record-literal / non-empty-record-type) -non-empty-record-type = ":" nonempty-whitespace expression *("," whitespace record-type-entry) -record-type-entry = any-label whitespace ":" nonempty-whitespace expression -non-empty-record-literal = "=" whitespace expression *("," whitespace record-literal-entry) -record-literal-entry = any-label whitespace "=" whitespace expression + any-label whsp (non-empty-record-literal / non-empty-record-type) +non-empty-record-type = ":" whsp1 expression *("," whsp record-type-entry) +record-type-entry = any-label whsp ":" whsp1 expression +non-empty-record-literal = "=" whsp expression *("," whsp record-literal-entry) +record-literal-entry = any-label whsp "=" whsp expression ; "< Foo : Integer | Bar : Bool >" ; "< Foo : Integer | Bar = True >" @@ -672,21 +672,21 @@ union-type-or-literal = / empty-union-type empty-union-type = "" non-empty-union-type-or-literal = - any-label whitespace - ( "=" whitespace expression union-type-entries - / ":" nonempty-whitespace expression [ "|" whitespace non-empty-union-type-or-literal ] + any-label whsp + ( "=" whsp expression union-type-entries + / ":" whsp1 expression [ "|" whsp non-empty-union-type-or-literal ] ) -union-type-entries = *("|" whitespace union-type-entry) -union-type-entry = any-label whitespace ":" nonempty-whitespace expression +union-type-entries = *("|" whsp union-type-entry) +union-type-entry = any-label whsp ":" whsp1 expression ; "[1, 2, 3]" ; `empty-list-or-optional` handles empty lists -non-empty-list-literal = "[" whitespace expression *("," whitespace expression) "]" +non-empty-list-literal = "[" whsp expression *("," whsp expression) "]" ; "( e )" -parenthesized-expression = "(" whitespace expression ")" +parenthesized-expression = "(" whsp expression ")" ; All expressions end with trailing whitespace. This just adds a final ; whitespace prefix for the top-level of the program -complete-expression = whitespace expression +complete-expression = whsp expression -- cgit v1.2.3 From ecc39e26a7cf211a5312da468e11f828917e669d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 16:46:39 +0200 Subject: Remove trailing whitespace from expression rules --- dhall_parser/src/dhall.abnf | 66 +++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 025f53a..640a422 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -543,58 +543,60 @@ expression = / annotated-expression ; "\(x : a) -> b" -lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression +lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression ; "if a then b else c" -ifthenelse-expression = if whsp1 expression then whsp1 expression else whsp1 expression +ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression ; "let x : t = e1 in e2" ; "let x = e1 in e2" ; "let x = e1 let y = e2 in e3" let-expression = 1*let-binding in whsp1 expression -let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression ] "=" whsp expression +let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp ; "forall (x : a) -> b" -forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression +forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression ; "a -> b" -arrow-expression = operator-expression arrow whsp expression +arrow-expression = operator-expression whsp arrow whsp expression ; "merge e1 e2 : t" ; "merge e1 e2" -merge-expression = merge whsp1 import-expression whsp import-expression whsp [ ":" whsp1 application-expression ] +merge-expression = merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ] ; "[] : List t" ; "[] : Optional t" ; "[x] : Optional t" empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional) -empty-collection = "]" whsp ":" whsp1 (List whsp / Optional whsp) import-expression whsp -non-empty-optional = expression "]" whsp ":" whsp1 Optional whsp import-expression whsp +empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression +non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression ; "x : t" -annotated-expression = operator-expression [ ":" whsp1 expression ] +annotated-expression = operator-expression [ whsp ":" whsp1 expression ] operator-expression = import-alt-expression -import-alt-expression = or-expression *("?" whsp1 or-expression) -or-expression = plus-expression *("||" whsp plus-expression ) -plus-expression = text-append-expression *("+" whsp1 text-append-expression ) -text-append-expression = list-append-expression *("++" whsp list-append-expression ) -list-append-expression = and-expression *("#" whsp and-expression ) -and-expression = combine-expression *("&&" whsp combine-expression ) -combine-expression = prefer-expression *(combine whsp prefer-expression ) -prefer-expression = combine-types-expression *(prefer whsp combine-types-expression) -combine-types-expression = times-expression *(combine-types whsp times-expression ) -times-expression = equal-expression *("*" whsp equal-expression ) -equal-expression = not-equal-expression *("==" whsp not-equal-expression ) -not-equal-expression = application-expression *("!=" whsp application-expression ) +; Nonempty-whitespace to disambiguate `http://a/a?a` +import-alt-expression = or-expression *(whsp "?" whsp1 or-expression) +or-expression = plus-expression *(whsp "||" whsp plus-expression) +; Nonempty-whitespace to disambiguate `f +2` +plus-expression = text-append-expression *(whsp "+" whsp1 text-append-expression) +text-append-expression = list-append-expression *(whsp "++" whsp list-append-expression) +list-append-expression = and-expression *(whsp "#" whsp and-expression) +and-expression = combine-expression *(whsp "&&" whsp combine-expression) +combine-expression = prefer-expression *(whsp combine whsp prefer-expression) +prefer-expression = combine-types-expression *(whsp prefer whsp combine-types-expression) +combine-types-expression = times-expression *(whsp combine-types whsp times-expression) +times-expression = equal-expression *(whsp "*" whsp equal-expression) +equal-expression = not-equal-expression *(whsp "==" whsp not-equal-expression) +not-equal-expression = application-expression *(whsp "!=" whsp application-expression) ; Import expressions need to be separated by some whitespace, otherwise there ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`", ; or "apply the import `./a` to label `b`" application-expression = - import-expression *(whsp1 import-expression) whsp + import-expression *(whsp1 import-expression) import-expression = import @@ -660,10 +662,10 @@ empty-record-literal = "=" whsp empty-record-type = "" non-empty-record-type-or-literal = any-label whsp (non-empty-record-literal / non-empty-record-type) -non-empty-record-type = ":" whsp1 expression *("," whsp record-type-entry) -record-type-entry = any-label whsp ":" whsp1 expression -non-empty-record-literal = "=" whsp expression *("," whsp record-literal-entry) -record-literal-entry = any-label whsp "=" whsp expression +non-empty-record-type = ":" whsp1 expression whsp *("," whsp record-type-entry) +record-type-entry = any-label whsp ":" whsp1 expression whsp +non-empty-record-literal = "=" whsp expression whsp *("," whsp record-literal-entry) +record-literal-entry = any-label whsp "=" whsp expression whsp ; "< Foo : Integer | Bar : Bool >" ; "< Foo : Integer | Bar = True >" @@ -673,20 +675,20 @@ union-type-or-literal = empty-union-type = "" non-empty-union-type-or-literal = any-label whsp - ( "=" whsp expression union-type-entries - / ":" whsp1 expression [ "|" whsp non-empty-union-type-or-literal ] + ( "=" whsp expression whsp union-type-entries + / ":" whsp1 expression whsp [ "|" whsp non-empty-union-type-or-literal ] ) union-type-entries = *("|" whsp union-type-entry) -union-type-entry = any-label whsp ":" whsp1 expression +union-type-entry = any-label whsp ":" whsp1 expression whsp ; "[1, 2, 3]" ; `empty-list-or-optional` handles empty lists -non-empty-list-literal = "[" whsp expression *("," whsp expression) "]" +non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]" ; "( e )" -parenthesized-expression = "(" whsp expression ")" +parenthesized-expression = "(" whsp expression whsp ")" ; All expressions end with trailing whitespace. This just adds a final ; whitespace prefix for the top-level of the program -complete-expression = whsp expression +complete-expression = whsp expression whsp -- cgit v1.2.3 From 2930da578e6a7847a33aee0d7145552b299e783d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 17:23:36 +0200 Subject: rename --- dhall_parser/src/dhall.abnf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 640a422..8964f44 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -170,11 +170,11 @@ quoted-label = 1*quoted-label-char ; for code obfuscation label = ("`" quoted-label "`" / simple-label) -; An unreserved-label cannot not be any of the reserved identifiers for builtins (unless quoted). +; A nonreserved-label cannot not be any of the reserved identifiers for builtins (unless quoted). ; Their list can be found in semantics.md. This is not enforced by the grammar but ; should be checked by implementations. The only place where this restriction applies ; is bound variables. -unreserved-label = label +nonreserved-label = label ; An any-label is allowed to be one of the reserved identifiers. any-label = label @@ -543,7 +543,7 @@ expression = / annotated-expression ; "\(x : a) -> b" -lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression +lambda-expression = lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression ; "if a then b else c" ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression @@ -552,10 +552,10 @@ ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else ; "let x = e1 in e2" ; "let x = e1 let y = e2 in e3" let-expression = 1*let-binding in whsp1 expression -let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp +let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp ; "forall (x : a) -> b" -forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression +forall-expression = forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression ; "a -> b" arrow-expression = operator-expression whsp arrow whsp expression -- cgit v1.2.3 From a342f45f820e28638e4a73a7b3a577ebf2396b0d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 18:48:42 +0200 Subject: Factor back in some rule branches --- dhall_parser/src/dhall.abnf | 64 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 8964f44..2fad4d4 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -529,52 +529,46 @@ import = import-hashed [ whsp as whsp1 Text ] ; This is important to avoid the need for sequential backtracking in application-expression. expression = - lambda-expression - / ifthenelse-expression - / let-expression - / forall-expression + ; "\(x : a) -> b" + lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression + + ; "if a then b else c" + / if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression + + ; "let x : t = e1 in e2" + ; "let x = e1 in e2" + ; "let x = e1 let y = e2 in e3" + / 1*let-binding in whsp1 expression + + ; "forall (x : a) -> b" + / forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression + + ; "a -> b" ; NOTE: Backtrack if parsing this alternative fails - / arrow-expression - / merge-expression + / operator-expression whsp arrow whsp expression + + ; "merge e1 e2 : t" + ; "merge e1 e2" + / merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ] + + ; "[] : List t" + ; "[] : Optional t" + ; "[x] : Optional t" ; NOTE: Backtrack if parsing this alternative fails since we can't tell ; from the opening bracket whether or not this will be an empty list or ; a non-empty list - / empty-list-or-optional + / "[" whsp (empty-collection / non-empty-optional) + + ; "x : t" / annotated-expression -; "\(x : a) -> b" -lambda-expression = lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression - -; "if a then b else c" -ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression +; "x : t" +annotated-expression = operator-expression [ whsp ":" whsp1 expression ] -; "let x : t = e1 in e2" -; "let x = e1 in e2" -; "let x = e1 let y = e2 in e3" -let-expression = 1*let-binding in whsp1 expression let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp - -; "forall (x : a) -> b" -forall-expression = forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression - -; "a -> b" -arrow-expression = operator-expression whsp arrow whsp expression - -; "merge e1 e2 : t" -; "merge e1 e2" -merge-expression = merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ] - -; "[] : List t" -; "[] : Optional t" -; "[x] : Optional t" -empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional) empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression -; "x : t" -annotated-expression = operator-expression [ whsp ":" whsp1 expression ] - - operator-expression = import-alt-expression ; Nonempty-whitespace to disambiguate `http://a/a?a` -- cgit v1.2.3 From f385e9dabfe3d923a841dc6d99542683cbbbb77a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 19:46:17 +0200 Subject: Import many trivial changes from upstream --- dhall_parser/src/dhall.abnf | 90 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 46 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 2fad4d4..ca54215 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -132,6 +132,7 @@ whitespace-chunk = whsp = *whitespace-chunk +; nonempty whitespace whsp1 = 1*whitespace-chunk ; Uppercase or lowercase ASCII letter @@ -142,19 +143,13 @@ DIGIT = %x30-39 ; 0-9 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" -; A simple label cannot be one of the following reserved keywords: -; -; * if -; * then -; * else -; * let -; * in -; * as -; * using -; * merge -; * missing -; * Infinity -; * Some +; A simple label cannot be one of the reserved keywords +; listed in the `keyword` rule. +; A PEG parser could use negative lookahead to +; enforce this, e.g. as follows: +; simple-label = +; keyword 1*simple-label-next-char +; / !keyword (simple-label-first-char *simple-label-next-char) simple-label-first-char = ALPHA / "_" simple-label-next-char = ALPHA / DIGIT / "-" / "/" / "_" simple-label = simple-label-first-char *simple-label-next-char @@ -174,6 +169,7 @@ label = ("`" quoted-label "`" / simple-label) ; Their list can be found in semantics.md. This is not enforced by the grammar but ; should be checked by implementations. The only place where this restriction applies ; is bound variables. +; A PEG parser could use negative lookahead to avoid parsing those identifiers. nonreserved-label = label ; An any-label is allowed to be one of the reserved identifiers. @@ -216,8 +212,8 @@ any-label = label ; > "\uD834\uDD1E". double-quote-chunk = interpolation - ; '\' - / %x5C double-quote-escaped + ; '\' Beginning of escape sequence + / %x5C double-quote-escaped / double-quote-char double-quote-escaped = @@ -273,7 +269,6 @@ single-quote-char = single-quote-literal = "''" end-of-line single-quote-continue -; Interpolation interpolation = "${" complete-expression "}" text-literal = (double-quote-literal / single-quote-literal) @@ -281,25 +276,25 @@ text-literal = (double-quote-literal / single-quote-literal) ; RFC 5234 interprets string literals as case-insensitive and recommends using ; hex instead for case-sensitive strings ; -; If you don't feel like reading hex, these are all the same as the rule name, -; except without the '' ending. +; If you don't feel like reading hex, these are all the same as the rule name. ; Keywords that should never be parsed as identifiers -if = %x69.66 -then = %x74.68.65.6e -else = %x65.6c.73.65 -let = %x6c.65.74 -in = %x69.6e -as = %x61.73 -using = %x75.73.69.6e.67 -merge = %x6d.65.72.67.65 -missing = %x6d.69.73.73.69.6e.67 -Infinity = %x49.6e.66.69.6e.69.74.79 +if = %x69.66 +then = %x74.68.65.6e +else = %x65.6c.73.65 +let = %x6c.65.74 +in = %x69.6e +as = %x61.73 +using = %x75.73.69.6e.67 +merge = %x6d.65.72.67.65 +missing = %x6d.69.73.73.69.6e.67 +Infinity = %x49.6e.66.69.6e.69.74.79 +NaN = %x4e.61.4e +Some = %x53.6f.6d.65 + ; Reserved identifiers, only needed for some special cases of parsing Optional = %x4f.70.74.69.6f.6e.61.6c Text = %x54.65.78.74 List = %x4c.69.73.74 -NaN = %x4e.61.4e -Some = %x53.6f.6d.65 combine = %x2227 / "/\" combine-types = %x2A53 / "//\\" @@ -363,6 +358,8 @@ quoted-path-component = 1*quoted-path-character path-component = "/" ( unquoted-path-component / %x22 quoted-path-component %x22 ) +; The last path-component matched by this rule is referred to as "file" in the semantics, +; and the other path-components as "directory". path = 1*path-component local = @@ -513,7 +510,7 @@ posix-environment-variable-character = import-type = missing / local / http / env -hash = %x73.68.61.32.35.36.3a 64HEXDIG ; "sha256:XXX...XXX" +hash = %x73.68.61.32.35.36.3a 64HEXDIG ; "sha256:XXX...XXX" import-hashed = import-type [ whsp hash ] @@ -522,12 +519,6 @@ import-hashed = import-type [ whsp hash ] ; "env:FOO" import = import-hashed [ whsp as whsp1 Text ] -; NOTE: Every rule past this point should only reference rules that end with -; whitespace. This ensures consistent handling of whitespace in the absence of -; a separate lexing step. -; The exception is the rules ending in , which should _not_ end in whitespace. -; This is important to avoid the need for sequential backtracking in application-expression. - expression = ; "\(x : a) -> b" lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression @@ -544,6 +535,7 @@ expression = / forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression ; "a -> b" + ; ; NOTE: Backtrack if parsing this alternative fails / operator-expression whsp arrow whsp expression @@ -554,6 +546,7 @@ expression = ; "[] : List t" ; "[] : Optional t" ; "[x] : Optional t" + ; ; NOTE: Backtrack if parsing this alternative fails since we can't tell ; from the opening bracket whether or not this will be an empty list or ; a non-empty list @@ -562,11 +555,17 @@ expression = ; "x : t" / annotated-expression -; "x : t" +; Nonempty-whitespace to disambiguate `env:VARIABLE` from type annotations annotated-expression = operator-expression [ whsp ":" whsp1 expression ] +; "let x = e1" let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp + +; "] : List t" +; "] : Optional t" empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression + +; "x] : Optional t" non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression operator-expression = import-alt-expression @@ -592,14 +591,13 @@ not-equal-expression = application-expression *(whsp "!=" whsp application application-expression = import-expression *(whsp1 import-expression) -import-expression = - import - / selector-expression +import-expression = import / selector-expression ; `record.field` extracts one field of a record +; ; `record.{ field0, field1, field2 }` projects out several fields of a record ; -; NOTE: Backtrack when parsing the `*(dot ...)`. The reason why is that you +; NOTE: Backtrack when parsing the `*("." ...)`. The reason why is that you ; can't tell from parsing just the period whether "foo." will become "foo.bar" ; (i.e. accessing field `bar` of the record `foo`) or `foo./bar` (i.e. applying ; the function `foo` to the relative path `./bar`) @@ -646,14 +644,13 @@ literal-expression = minus-infinity-literal = "-" Infinity plus-infinity-literal = Infinity -; "{ foo = 1 , bar = True }" -; "{ foo : Integer, bar : Bool }" record-type-or-literal = empty-record-literal / non-empty-record-type-or-literal / empty-record-type empty-record-literal = "=" whsp empty-record-type = "" + non-empty-record-type-or-literal = any-label whsp (non-empty-record-literal / non-empty-record-type) non-empty-record-type = ":" whsp1 expression whsp *("," whsp record-type-entry) @@ -666,7 +663,9 @@ record-literal-entry = any-label whsp "=" whsp expression whsp union-type-or-literal = non-empty-union-type-or-literal / empty-union-type + empty-union-type = "" + non-empty-union-type-or-literal = any-label whsp ( "=" whsp expression whsp union-type-entries @@ -683,6 +682,5 @@ non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "] parenthesized-expression = "(" whsp expression whsp ")" -; All expressions end with trailing whitespace. This just adds a final -; whitespace prefix for the top-level of the program +; This just adds surrounding whitespace for the top-level of the program complete-expression = whsp expression whsp -- cgit v1.2.3 From 2ef0951c45e3c9c87990ab7e334059aa9b21f540 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 19:51:12 +0200 Subject: Tweak double literals --- dhall_parser/src/dhall.abnf | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index ca54215..15fd898 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -305,7 +305,20 @@ arrow = %x2192 / "->" exponent = "e" [ "+" / "-" ] 1*DIGIT -double-literal = [ "+" / "-" ] 1*DIGIT ( "." 1*DIGIT [ exponent ] / exponent) +numeric-double-literal = [ "+" / "-" ] 1*DIGIT ( "." 1*DIGIT [ exponent ] / exponent) + +minus-infinity-literal = "-" Infinity +plus-infinity-literal = Infinity + +double-literal = + ; "2.0" + numeric-double-literal + ; "-Infinity" + / minus-infinity-literal + ; "Infinity" + / plus-infinity-literal + ; "NaN" + / NaN natural-literal = 1*DIGIT @@ -627,13 +640,6 @@ literal-expression = ; "+2" / integer-literal - ; "-Infinity" - / minus-infinity-literal - ; "Infinity" - / plus-infinity-literal - ; "NaN" - / NaN - ; '"ABC"' / text-literal -- cgit v1.2.3 From e05299d3d84dcbba79887f1dc5b42d689b714edc Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 20:07:51 +0200 Subject: Factor literal-expression back in --- dhall_parser/src/dhall.abnf | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 15fd898..52d5b91 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -622,15 +622,6 @@ labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}" primitive-expression = - literal-expression - / "{" whsp record-type-or-literal "}" - / "<" whsp union-type-or-literal ">" - / non-empty-list-literal - / parenthesized-expression - -; NOTE: Backtrack when parsing the first three alternatives (i.e. the numeric -; literals). This is because they share leading characters in common -literal-expression = ; "2.0" double-literal @@ -646,9 +637,10 @@ literal-expression = ; "x" ; "x@2" / identifier - -minus-infinity-literal = "-" Infinity -plus-infinity-literal = Infinity + / "{" whsp record-type-or-literal "}" + / "<" whsp union-type-or-literal ">" + / non-empty-list-literal + / parenthesized-expression record-type-or-literal = empty-record-literal -- cgit v1.2.3 From 7b8c64a754bbd2f9c55cf8992d5bcc8c7a460327 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 20:18:19 +0200 Subject: Whitespace --- dhall_parser/src/dhall.abnf | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 52d5b91..9456036 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -620,7 +620,8 @@ selector = any-label / labels labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}" - +; NOTE: Backtrack when parsing the first three alternatives (i.e. the numeric +; literals). This is because they share leading characters in common primitive-expression = ; "2.0" double-literal @@ -634,27 +635,27 @@ primitive-expression = ; '"ABC"' / text-literal + / "{" whsp record-type-or-literal whsp "}" + / "<" whsp union-type-or-literal whsp ">" + / non-empty-list-literal ; "x" ; "x@2" / identifier - / "{" whsp record-type-or-literal "}" - / "<" whsp union-type-or-literal ">" - / non-empty-list-literal - / parenthesized-expression + / "(" whsp expression whsp ")" record-type-or-literal = empty-record-literal / non-empty-record-type-or-literal / empty-record-type -empty-record-literal = "=" whsp +empty-record-literal = "=" empty-record-type = "" non-empty-record-type-or-literal = any-label whsp (non-empty-record-literal / non-empty-record-type) -non-empty-record-type = ":" whsp1 expression whsp *("," whsp record-type-entry) -record-type-entry = any-label whsp ":" whsp1 expression whsp -non-empty-record-literal = "=" whsp expression whsp *("," whsp record-literal-entry) -record-literal-entry = any-label whsp "=" whsp expression whsp +non-empty-record-type = ":" whsp1 expression *(whsp "," whsp record-type-entry) +record-type-entry = any-label whsp ":" whsp1 expression +non-empty-record-literal = "=" whsp expression *(whsp "," whsp record-literal-entry) +record-literal-entry = any-label whsp "=" whsp expression ; "< Foo : Integer | Bar : Bool >" ; "< Foo : Integer | Bar = True >" @@ -666,19 +667,16 @@ empty-union-type = "" non-empty-union-type-or-literal = any-label whsp - ( "=" whsp expression whsp union-type-entries - / ":" whsp1 expression whsp [ "|" whsp non-empty-union-type-or-literal ] + ( "=" whsp expression union-type-entries + / ":" whsp1 expression [ whsp "|" whsp non-empty-union-type-or-literal ] ) -union-type-entries = *("|" whsp union-type-entry) -union-type-entry = any-label whsp ":" whsp1 expression whsp +union-type-entries = *(whsp "|" whsp union-type-entry) +union-type-entry = any-label whsp ":" whsp1 expression ; "[1, 2, 3]" ; `empty-list-or-optional` handles empty lists non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]" -; "( e )" -parenthesized-expression = "(" whsp expression whsp ")" - ; This just adds surrounding whitespace for the top-level of the program complete-expression = whsp expression whsp -- cgit v1.2.3 From ebbd660008dc783ae6c8bc57ca764309ea463a5e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 20:20:43 +0200 Subject: Import more trivial changes from upstream --- dhall_parser/src/dhall.abnf | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 9456036..0f07a20 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -635,30 +635,43 @@ primitive-expression = ; '"ABC"' / text-literal + ; "{ foo = 1 , bar = True }" + ; "{ foo : Integer, bar : Bool }" / "{" whsp record-type-or-literal whsp "}" + + ; "< Foo : Integer | Bar : Bool >" + ; "< Foo : Integer | Bar = True | Baz : Bool >" + ; "< Foo | Bar : Bool >" / "<" whsp union-type-or-literal whsp ">" + + ; "[1, 2, 3]" + ; `empty-collection` handles empty lists / non-empty-list-literal + ; "x" ; "x@2" / identifier - / "(" whsp expression whsp ")" + + ; "( e )" + / "(" complete-expression ")" record-type-or-literal = empty-record-literal / non-empty-record-type-or-literal / empty-record-type + empty-record-literal = "=" empty-record-type = "" non-empty-record-type-or-literal = any-label whsp (non-empty-record-literal / non-empty-record-type) -non-empty-record-type = ":" whsp1 expression *(whsp "," whsp record-type-entry) + +non-empty-record-type = ":" whsp1 expression *(whsp "," whsp record-type-entry) record-type-entry = any-label whsp ":" whsp1 expression + non-empty-record-literal = "=" whsp expression *(whsp "," whsp record-literal-entry) record-literal-entry = any-label whsp "=" whsp expression -; "< Foo : Integer | Bar : Bool >" -; "< Foo : Integer | Bar = True >" union-type-or-literal = non-empty-union-type-or-literal / empty-union-type -- cgit v1.2.3 From 08596e55a3e71f2fd636494aaa232e1cf476e4ac Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 21:35:11 +0200 Subject: Handle Some as in upstream grammar --- dhall_parser/src/dhall.abnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 0f07a20..4aa3fec 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -602,7 +602,7 @@ not-equal-expression = application-expression *(whsp "!=" whsp application ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`", ; or "apply the import `./a` to label `b`" application-expression = - import-expression *(whsp1 import-expression) + [ Some whsp1 ] import-expression *(whsp1 import-expression) import-expression = import / selector-expression -- cgit v1.2.3 From 3e4b2dcb8c371045737901c0d49f9d9403109ea0 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 21:43:41 +0200 Subject: Get keyword rule from upstream --- dhall_parser/src/dhall.abnf | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 4aa3fec..01ec6d8 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -291,6 +291,15 @@ Infinity = %x49.6e.66.69.6e.69.74.79 NaN = %x4e.61.4e Some = %x53.6f.6d.65 +; Unused rule that could be used as negative lookahead in the +; `simple-label` rule for parsers that support this. +keyword = + if / then / else + / let / in + / using / missing / as + / Infinity / NaN + / merge / Some + ; Reserved identifiers, only needed for some special cases of parsing Optional = %x4f.70.74.69.6f.6e.61.6c Text = %x54.65.78.74 -- cgit v1.2.3 From e7a58d09748bd333f755a06090f378e31dc6617a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 22:28:00 +0200 Subject: Import union rules from upstream grammar --- dhall_parser/src/dhall.abnf | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 01ec6d8..7ad0b24 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -688,17 +688,18 @@ union-type-or-literal = empty-union-type = "" non-empty-union-type-or-literal = - any-label whsp - ( "=" whsp expression union-type-entries - / ":" whsp1 expression [ whsp "|" whsp non-empty-union-type-or-literal ] - ) -union-type-entries = *(whsp "|" whsp union-type-entry) + any-label [ whsp ( union-literal-variant-value / union-type-or-literal-variant-type) ] + +; = True | ... +union-literal-variant-value = "=" whsp expression *(whsp "|" whsp union-type-entry) union-type-entry = any-label whsp ":" whsp1 expression -; "[1, 2, 3]" -; `empty-list-or-optional` handles empty lists -non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]" +; : Integer | ... +; | ... +union-type-or-literal-variant-type = [ ":" whsp1 expression ] [ whsp "|" whsp non-empty-union-type-or-literal ] +non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]" + ; This just adds surrounding whitespace for the top-level of the program complete-expression = whsp expression whsp -- cgit v1.2.3 From af968c9e72ef5c2ea1ee965776879d9c903bd1aa Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Apr 2019 22:32:04 +0200 Subject: Revert end_of_line handling to upstream --- dhall_parser/src/dhall.abnf | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'dhall_parser/src/dhall.abnf') diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf index 7ad0b24..847da02 100644 --- a/dhall_parser/src/dhall.abnf +++ b/dhall_parser/src/dhall.abnf @@ -100,10 +100,9 @@ ; ; For simplicity this supports Unix and Windows line-endings, which are the most ; common -end-of-line-silent = +end-of-line = %x0A ; "\n" / %x0D.0A ; "\r\n" -end-of-line = end-of-line-silent tab = %x09 ; "\t" @@ -113,7 +112,7 @@ block-comment-chunk = block-comment / %x20-10FFFF / tab - / end-of-line-silent + / end-of-line block-comment-continue = "-}" / block-comment-chunk block-comment-continue @@ -121,12 +120,12 @@ not-end-of-line = %x20-10FFFF / tab ; NOTE: Slightly different from Haskell-style single-line comments because this ; does not require a space after the dashes -line-comment = "--" *not-end-of-line end-of-line-silent +line-comment = "--" *not-end-of-line end-of-line whitespace-chunk = " " / tab - / end-of-line-silent + / end-of-line / line-comment / block-comment -- cgit v1.2.3