summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-03-05 16:36:12 +0100
committerNadrieril2019-03-05 16:36:12 +0100
commit2cd161a43f0e3a25b9613663b6979ea514447a14 (patch)
tree23fade1d4d074bd40ba36af1a8631ddefe857198
parent050bba1a4cb5a15ef52e014879bab87855e8299a (diff)
Parse single quote literals
-rw-r--r--dhall/src/parser.rs71
-rw-r--r--dhall_parser/src/dhall.abnf9
-rw-r--r--dhall_parser/src/dhall.pest.visibility5
3 files changed, 62 insertions, 23 deletions
diff --git a/dhall/src/parser.rs b/dhall/src/parser.rs
index 5075a24..ee93a7d 100644
--- a/dhall/src/parser.rs
+++ b/dhall/src/parser.rs
@@ -399,6 +399,29 @@ named!(str<&'a str>; with_captured_str!(s; { s.trim() }));
named!(raw_str<&'a str>; with_captured_str!(s; s));
+named_rule!(escaped_quote_pair<&'a str>; plain_value!("''"));
+named_rule!(escaped_interpolation<&'a str>; plain_value!("${"));
+
+named_rule!(single_quote_continue<Vec<&'a str>>; match_children!(
+ // TODO: handle interpolation
+ // (c: expression, rest: single_quote_continue) => {
+ // rest.push(c); rest
+ // },
+ (c: escaped_quote_pair, rest: single_quote_continue) => {
+ rest.push(c); rest
+ },
+ (c: escaped_interpolation, rest: single_quote_continue) => {
+ rest.push(c); rest
+ },
+ // capture interpolation as string
+ (c: raw_str, rest: single_quote_continue) => {
+ rest.push(c); rest
+ },
+ () => {
+ vec![]
+ },
+));
+
named!(natural<usize>; with_raw_pair!(pair; {
pair.as_str().trim()
.parse()
@@ -411,7 +434,7 @@ named!(integer<isize>; with_raw_pair!(pair; {
.map_err(|e: std::num::ParseIntError| custom_parse_error(&pair, format!("{}", e)))?
}));
-named!(letbinding<(&'a str, Option<BoxExpr<'a>>, BoxExpr<'a>)>;
+named_rule!(let_binding<(&'a str, Option<BoxExpr<'a>>, BoxExpr<'a>)>;
match_children!((name: str, annot?: expression, expr: expression) => (name, annot, expr))
);
@@ -445,7 +468,8 @@ named_rule!(union_type_entries<BTreeMap<&'a str, ParsedExpr<'a>>>;
})
);
-named_rule!(non_empty_union_type_or_literal<(Option<(&'a str, BoxExpr<'a>)>, BTreeMap<&'a str, ParsedExpr<'a>>)>;
+named_rule!(non_empty_union_type_or_literal
+ <(Option<(&'a str, BoxExpr<'a>)>, BTreeMap<&'a str, ParsedExpr<'a>>)>;
match_children!(
(label: str, e: expression, entries: union_type_entries) => {
(Some((label, e)), entries)
@@ -466,10 +490,16 @@ named_rule!(non_empty_union_type_or_literal<(Option<(&'a str, BoxExpr<'a>)>, BTr
named_rule!(empty_union_type<()>; plain_value!(()));
named!(expression<BoxExpr<'a>>; match_rule!(
+ // TODO: parse escapes and interpolation
Rule::double_quote_literal =>
match_children!((strs*: raw_str) => {
bx(Expr::TextLit(strs.collect()))
}),
+ Rule::single_quote_literal =>
+ match_children!((eol: raw_str, contents: single_quote_continue) => {
+ contents.push(eol);
+ bx(Expr::TextLit(contents.into_iter().rev().collect()))
+ }),
Rule::natural_literal_raw => map!(natural; |n| bx(Expr::NaturalLit(n))),
Rule::integer_literal_raw => map!(integer; |n| bx(Expr::IntegerLit(n))),
@@ -499,7 +529,7 @@ named!(expression<BoxExpr<'a>>; match_rule!(
}),
Rule::let_expression =>
- match_children!((bindings*: letbinding, final_expr: expression) => {
+ match_children!((bindings*: let_binding, final_expr: expression) => {
bindings.fold(final_expr, |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc)))
}),
@@ -583,13 +613,13 @@ named!(expression<BoxExpr<'a>>; match_rule!(
}),
- _ => with_rule!(rule;
- match_children!((exprs*: expression) => {
- let rulename = format!("{:?}", rule);
- // panic!(rulename);
- bx(Expr::FailedParse(rulename, exprs.map(|x| *x).collect()))
- })
- ),
+ // _ => with_rule!(rule;
+ // match_children!((exprs*: expression) => {
+ // let rulename = format!("{:?}", rule);
+ // // panic!(rulename);
+ // bx(Expr::FailedParse(rulename, exprs.map(|x| *x).collect()))
+ // })
+ // ),
));
named!(final_expression<BoxExpr<'a>>;
@@ -608,13 +638,20 @@ fn test_parse() {
// let expr = r#"(1 + 2) * 3"#;
let expr = r#"if True then 1 + 3 * 5 else 2"#;
println!("{:?}", parse_expr_lalrpop(expr));
- match parse_expr_pest(expr) {
- Err(e) => {
- println!("{:?}", e);
- println!("{}", e);
- }
- ok => println!("{:?}", ok),
- }
+ use std::thread;
+ // I don't understand why it stack overflows even on tiny expressions...
+ thread::Builder::new()
+ .stack_size(3 * 1024 * 1024)
+ .spawn(move || match parse_expr_pest(expr) {
+ Err(e) => {
+ println!("{:?}", e);
+ println!("{}", e);
+ }
+ ok => println!("{:?}", ok),
+ })
+ .unwrap()
+ .join()
+ .unwrap();
// assert_eq!(parse_expr_pest(expr).unwrap(), parse_expr_lalrpop(expr).unwrap());
// assert!(false);
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 391741f..e311aa6 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -100,9 +100,10 @@
;
; For simplicity this supports Unix and Windows line-endings, which are the most
; common
-end-of-line =
+end-of-line-silent =
%x0A ; "\n"
/ %x0D.0A ; "\r\n"
+end-of-line = end-of-line-silent
tab = %x09 ; "\t"
@@ -112,7 +113,7 @@ block-comment-chunk =
block-comment
/ %x20-10FFFF
/ tab
- / end-of-line
+ / end-of-line-silent
block-comment-continue = "-}" / block-comment-chunk block-comment-continue
@@ -120,12 +121,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
+line-comment = "--" *not-end-of-line end-of-line-silent
whitespace-chunk =
" "
/ tab
- / end-of-line
+ / end-of-line-silent
/ line-comment
/ block-comment
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index a2dedde..e9bf241 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -1,4 +1,5 @@
-# end_of_line
+end_of_line
+# end_of_line_silent
# tab
# block_comment
# block_comment_chunk
@@ -21,7 +22,7 @@ label_raw
label
# double_quote_chunk
double_quote_literal
-# single_quote_continue
+single_quote_continue
single_quote_literal
# text_literal_raw
# if_raw