summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall_core/src/parser.rs93
-rw-r--r--dhall_parser/src/dhall.abnf64
-rw-r--r--dhall_parser/src/dhall.pest.visibility22
3 files changed, 84 insertions, 95 deletions
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 68796c4..f888f94 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -116,8 +116,10 @@ fn debug_pair(pair: Pair<Rule>) -> String {
macro_rules! make_parser {
(@pattern, rule, $name:ident) => (Rule::$name);
+ (@pattern, token_rule, $name:ident) => (Rule::$name);
(@pattern, rule_group, $name:ident) => (_);
(@filter, rule) => (true);
+ (@filter, token_rule) => (true);
(@filter, rule_group) => (false);
(@body,
@@ -164,6 +166,13 @@ macro_rules! make_parser {
).ok_or_else(|| -> String { unreachable!() })?;
Ok(ParsedValue::$group(res))
});
+ (@body,
+ $pair:expr,
+ $children:expr,
+ token_rule!($name:ident<$o:ty>)
+ ) => ({
+ Ok(ParsedValue::$name(()))
+ });
(@body, $pair:expr, $children:expr, rule_group!( $name:ident<$o:ty> )) => (
unreachable!()
);
@@ -235,7 +244,8 @@ fn do_parse<'a>(initial_pair: Pair<'a, Rule>) -> ParseResult<ParsedValue<'a>> {
fn can_be_shortcutted(rule: Rule) -> bool {
use Rule::*;
match rule {
- import_alt_expression
+ expression
+ | import_alt_expression
| or_expression
| plus_expression
| text_append_expression
@@ -255,7 +265,7 @@ fn can_be_shortcutted(rule: Rule) -> bool {
}
make_parser! {
- rule!(EOI<()>; captured_str!(_) => ());
+ token_rule!(EOI<()>);
rule!(simple_label<Label>;
captured_str!(s) => Label::from(s.trim().to_owned())
@@ -321,7 +331,7 @@ make_parser! {
captured_str!(s) => s
);
- rule!(end_of_line<()>; captured_str!(_) => ());
+ token_rule!(end_of_line<()>);
rule!(single_quote_literal<ParsedText>; children!(
[end_of_line(eol), single_quote_continue(lines)] => {
@@ -392,9 +402,9 @@ make_parser! {
},
));
- rule!(NaN<()>; captured_str!(_) => ());
- rule!(minus_infinity_literal<()>; captured_str!(_) => ());
- rule!(plus_infinity_literal<()>; captured_str!(_) => ());
+ token_rule!(NaN<()>);
+ token_rule!(minus_infinity_literal<()>);
+ token_rule!(plus_infinity_literal<()>);
rule!(double_literal<core::Double>;
captured_str!(s) => {
@@ -491,7 +501,7 @@ make_parser! {
rule!(bash_environment_variable<String>; captured_str!(s) => s.to_owned());
rule!(posix_environment_variable<String>; captured_str!(s) => s.to_owned());
- rule!(missing<()>; captured_str!(_) => ());
+ token_rule!(missing<()>);
rule!(import_type<ImportLocation>; children!(
[missing(_)] => {
@@ -522,9 +532,7 @@ make_parser! {
ImportHashed { location, hash: Some(h) },
));
- rule_group!(expression<ParsedExpr>);
-
- rule!(Text<()>; captured_str!(_) => ());
+ token_rule!(Text<()>);
rule!(import<ParsedExpr> as expression; children!(
[import_hashed(location_hashed)] => {
@@ -541,25 +549,39 @@ make_parser! {
},
));
- rule!(lambda_expression<ParsedExpr> as expression; children!(
- [nonreserved_label(l), expression(typ), expression(body)] => {
- Expr::Lam(l, rc(typ), rc(body))
- }
- ));
+ token_rule!(lambda<()>);
+ token_rule!(forall<()>);
+ token_rule!(arrow<()>);
+ token_rule!(merge<()>);
+ token_rule!(if_<()>);
+ token_rule!(in_<()>);
- rule!(ifthenelse_expression<ParsedExpr> as expression; children!(
- [expression(cond), expression(left), expression(right)] => {
+ rule!(expression<ParsedExpr> as expression; children!(
+ [lambda(()), nonreserved_label(l), expression(typ), arrow(()), expression(body)] => {
+ Expr::Lam(l, rc(typ), rc(body))
+ },
+ [if_(()), expression(cond), expression(left), expression(right)] => {
Expr::BoolIf(rc(cond), rc(left), rc(right))
- }
- ));
-
- rule!(let_expression<ParsedExpr> as expression; children!(
- [let_binding(bindings).., expression(final_expr)] => {
+ },
+ [let_binding(bindings).., in_(()), expression(final_expr)] => {
bindings.fold(
final_expr,
|acc, x| Expr::Let(x.0, x.1, x.2, rc(acc))
)
- }
+ },
+ [forall(()), nonreserved_label(l), expression(typ), arrow(()), expression(body)] => {
+ Expr::Pi(l, rc(typ), rc(body))
+ },
+ [expression(typ), arrow(()), expression(body)] => {
+ Expr::Pi("_".into(), rc(typ), rc(body))
+ },
+ [merge(()), expression(x), expression(y), expression(z)] => {
+ Expr::Merge(rc(x), rc(y), Some(rc(z)))
+ },
+ [merge(()), expression(x), expression(y)] => {
+ Expr::Merge(rc(x), rc(y), None)
+ },
+ [expression(e)] => e,
));
rule!(let_binding<(Label, Option<ParsedSubExpr>, ParsedSubExpr)>; children!(
@@ -569,27 +591,8 @@ make_parser! {
(name, None, rc(expr)),
));
- rule!(forall_expression<ParsedExpr> as expression; children!(
- [nonreserved_label(l), expression(typ), expression(body)] => {
- Expr::Pi(l, rc(typ), rc(body))
- }
- ));
-
- rule!(arrow_expression<ParsedExpr> as expression; children!(
- [expression(typ), expression(body)] => {
- Expr::Pi("_".into(), rc(typ), rc(body))
- }
- ));
-
- rule!(merge_expression<ParsedExpr> as expression; children!(
- [expression(x), expression(y), expression(z)] =>
- Expr::Merge(rc(x), rc(y), Some(rc(z))),
- [expression(x), expression(y)] =>
- Expr::Merge(rc(x), rc(y), None),
- ));
-
- rule!(List<()>; captured_str!(_) => ());
- rule!(Optional<()>; captured_str!(_) => ());
+ token_rule!(List<()>);
+ token_rule!(Optional<()>);
rule!(empty_collection<ParsedExpr> as expression; children!(
[List(_), expression(t)] => {
@@ -830,7 +833,7 @@ make_parser! {
},
));
- rule!(empty_union_type<()>; captured_str!(_) => ());
+ token_rule!(empty_union_type<()>);
rule!(non_empty_union_type_or_literal
<(Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>)>;
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`
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index e95cd32..ac3ea30 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -34,16 +34,15 @@ single_quote_literal
# in
# as
# using
-# merge
missing
-# if_
+if_
# then
# else_
# let_
-# in_
+in_
# as_
# using
-# merge
+merge
# Infinity
Optional
Text
@@ -78,9 +77,9 @@ List
# combine
# combine_types
# prefer
-# lambda
-# forall
-# arrow
+lambda
+forall
+arrow
# exponent
double_literal
natural_literal
@@ -120,14 +119,7 @@ import_type
hash
import_hashed
import
-# expression
-lambda_expression
-ifthenelse_expression
-let_expression
-forall_expression
-arrow_expression
-merge_expression
-# empty_list_or_optional
+expression
empty_collection
non_empty_optional
annotated_expression