summaryrefslogtreecommitdiff
path: root/dhall/src/parser.rs
diff options
context:
space:
mode:
authorNadrieril2019-03-02 22:21:43 +0100
committerNadrieril2019-03-02 22:25:38 +0100
commit54d3f23e68bf6e769d8a96e40a2b0c4426e38507 (patch)
tree60024b9d191aff4dd21d5f3489c786088a07f52c /dhall/src/parser.rs
parent48d89a280838919c1fba9e0acf1e090d3286c470 (diff)
Add parser/failure tests from spec
Diffstat (limited to '')
-rw-r--r--dhall/src/parser.rs163
1 files changed, 82 insertions, 81 deletions
diff --git a/dhall/src/parser.rs b/dhall/src/parser.rs
index 0acfe39..9259dfd 100644
--- a/dhall/src/parser.rs
+++ b/dhall/src/parser.rs
@@ -7,7 +7,7 @@ use crate::core::{bx, Expr, V};
pub type ParseError<'i> = lalrpop_util::ParseError<usize, Tok<'i>, LexicalError>;
-pub fn parse_expr(s: &str) -> Result<BoxExpr, ParseError> {
+pub fn parse_expr_lalrpop(s: &str) -> Result<BoxExpr, ParseError> {
grammar::ExprParser::new().parse(Lexer::new(s))
}
@@ -48,80 +48,81 @@ fn debug_pair(pair: Pair<Rule>) {
aux(0, "".into(), pair)
}
-pub fn parse_expr_pest(s: &str) -> Result<BoxExpr, Error<Rule>> {
- let parsed_expr = DhallParser::parse(Rule::final_expression, s)?.next().unwrap();
- debug_pair(parsed_expr.clone());
- // println!("{}", parsed_expr.clone());
-
- fn parse_binop<'a, F>(pair: Pair<'a, Rule>, mut f: F) -> BoxExpr<'a>
- where F: FnMut(BoxExpr<'a>, BoxExpr<'a>) -> ParsedExpr<'a> {
- let mut inner = pair.into_inner().map(parse_expression);
- let first_expr = inner.next().unwrap();
- inner.fold(first_expr, |acc, e| bx(f(acc, e)))
- }
+fn parse_binop<'a, F>(pair: Pair<'a, Rule>, mut f: F) -> BoxExpr<'a>
+where F: FnMut(BoxExpr<'a>, BoxExpr<'a>) -> ParsedExpr<'a> {
+ let mut inner = pair.into_inner().map(parse_expression);
+ let first_expr = inner.next().unwrap();
+ inner.fold(first_expr, |acc, e| bx(f(acc, e)))
+}
- fn skip_expr(pair: Pair<Rule>) -> BoxExpr {
- let mut inner = pair.into_inner().map(parse_expression);
- inner.next().unwrap()
- }
+fn skip_expr(pair: Pair<Rule>) -> BoxExpr {
+ let mut inner = pair.into_inner().map(parse_expression);
+ inner.next().unwrap()
+}
- fn parse_str(pair: Pair<Rule>) -> &str {
- pair.as_str().trim()
- }
+fn parse_str(pair: Pair<Rule>) -> &str {
+ pair.as_str().trim()
+}
- fn parse_natural(pair: Pair<Rule>) -> Result<usize, std::num::ParseIntError> {
- parse_str(pair).parse()
- }
+fn parse_natural(pair: Pair<Rule>) -> Result<usize, std::num::ParseIntError> {
+ parse_str(pair).parse()
+}
- fn parse_expression(pair: Pair<Rule>) -> BoxExpr {
- match pair.as_rule() {
- Rule::natural_literal_raw => bx(Expr::NaturalLit(parse_natural(pair).unwrap())),
-
- Rule::annotated_expression => { parse_binop(pair, Expr::Annot) }
- Rule::import_alt_expression => { skip_expr(pair) }
- Rule::or_expression => { parse_binop(pair, Expr::BoolOr) }
- Rule::plus_expression => { parse_binop(pair, Expr::NaturalPlus) }
- Rule::text_append_expression => { parse_binop(pair, Expr::TextAppend) }
- Rule::list_append_expression => { skip_expr(pair) }
- Rule::and_expression => { parse_binop(pair, Expr::BoolAnd) }
- Rule::combine_expression => { skip_expr(pair) }
- Rule::prefer_expression => { skip_expr(pair) }
- Rule::combine_types_expression => { skip_expr(pair) }
- Rule::times_expression => { parse_binop(pair, Expr::NaturalTimes) }
- Rule::equal_expression => { parse_binop(pair, Expr::BoolEQ) }
- Rule::not_equal_expression => { parse_binop(pair, Expr::BoolNE) }
- Rule::application_expression => { parse_binop(pair, Expr::App) }
-
- Rule::selector_expression_raw => {
- let mut inner = pair.into_inner();
- let first_expr = parse_expression(inner.next().unwrap());
- inner.fold(first_expr, |acc, e| bx(Expr::Field(acc, e.as_str())))
- }
+fn parse_expression(pair: Pair<Rule>) -> BoxExpr {
+ match pair.as_rule() {
+ Rule::natural_literal_raw => bx(Expr::NaturalLit(parse_natural(pair).unwrap())),
+
+ Rule::annotated_expression => { parse_binop(pair, Expr::Annot) }
+ Rule::import_alt_expression => { skip_expr(pair) }
+ Rule::or_expression => { parse_binop(pair, Expr::BoolOr) }
+ Rule::plus_expression => { parse_binop(pair, Expr::NaturalPlus) }
+ Rule::text_append_expression => { parse_binop(pair, Expr::TextAppend) }
+ Rule::list_append_expression => { skip_expr(pair) }
+ Rule::and_expression => { parse_binop(pair, Expr::BoolAnd) }
+ Rule::combine_expression => { skip_expr(pair) }
+ Rule::prefer_expression => { skip_expr(pair) }
+ Rule::combine_types_expression => { skip_expr(pair) }
+ Rule::times_expression => { parse_binop(pair, Expr::NaturalTimes) }
+ Rule::equal_expression => { parse_binop(pair, Expr::BoolEQ) }
+ Rule::not_equal_expression => { parse_binop(pair, Expr::BoolNE) }
+ Rule::application_expression => { parse_binop(pair, Expr::App) }
+
+ Rule::selector_expression_raw => {
+ let mut inner = pair.into_inner();
+ let first_expr = parse_expression(inner.next().unwrap());
+ inner.fold(first_expr, |acc, e| bx(Expr::Field(acc, e.as_str())))
+ }
- Rule::identifier_raw => {
- let mut inner = pair.into_inner();
- let name = parse_str(inner.next().unwrap());
- let idx = inner.next().map(parse_natural).unwrap_or(Ok(0)).unwrap();
- bx(Expr::Var(V(name, idx)))
- }
+ Rule::identifier_raw => {
+ let mut inner = pair.into_inner();
+ let name = parse_str(inner.next().unwrap());
+ let idx = inner.next().map(parse_natural).unwrap_or(Ok(0)).unwrap();
+ bx(Expr::Var(V(name, idx)))
+ }
- // Rule::record_type_or_literal => {
- // let mut inner = pair.into_inner();
- // let first_expr = parse_expression(inner.next().unwrap());
- // inner.fold(first_expr, |acc, e| bx(Expr::Field(acc, e.as_str())))
- // }
+ // Rule::record_type_or_literal => {
+ // let mut inner = pair.into_inner();
+ // let first_expr = parse_expression(inner.next().unwrap());
+ // inner.fold(first_expr, |acc, e| bx(Expr::Field(acc, e.as_str())))
+ // }
- // r => panic!("{:?}", r),
- // _ => bx(Expr::BoolLit(false)),
+ // r => panic!("{:?}", r),
+ // _ => bx(Expr::BoolLit(false)),
- _ => {
- let rulename = format!("{:?}", pair.as_rule());
- let mut inner = pair.into_inner().map(parse_expression).map(|x| *x);
- bx(Expr::FailedParse(rulename, inner.collect()))
- }
+ _ => {
+ let rulename = format!("{:?}", pair.as_rule());
+ let mut inner = pair.into_inner().map(parse_expression).map(|x| *x);
+ bx(Expr::FailedParse(rulename, inner.collect()))
}
}
+}
+
+pub fn parse_expr_pest(s: &str) -> Result<BoxExpr, Error<Rule>> {
+ let parsed_expr = DhallParser::parse(Rule::final_expression, s)?.next().unwrap();
+ debug_pair(parsed_expr.clone());
+ // println!("{}", parsed_expr.clone());
+
Ok(parse_expression(parsed_expr))
}
@@ -133,7 +134,7 @@ fn test_parse() {
// let expr = r#"{ x = "foo", y = 4 }.x"#;
// let expr = r#"(1 + 2) * 3"#;
let expr = r#"if True then 1 + 3 * 5 else 2"#;
- println!("{:?}", parse_expr(expr));
+ println!("{:?}", parse_expr_lalrpop(expr));
match parse_expr_pest(expr) {
Err(e) => {
println!("{:?}", e);
@@ -144,27 +145,27 @@ fn test_parse() {
// assert_eq!(parse_expr_pest(expr).unwrap(), parse_expr(expr).unwrap());
assert!(false);
- println!("test {:?}", parse_expr("3 + 5 * 10"));
- assert!(parse_expr("22").is_ok());
- assert!(parse_expr("(22)").is_ok());
- assert_eq!(parse_expr("3 + 5 * 10").ok(),
+ println!("test {:?}", parse_expr_lalrpop("3 + 5 * 10"));
+ assert!(parse_expr_lalrpop("22").is_ok());
+ assert!(parse_expr_lalrpop("(22)").is_ok());
+ assert_eq!(parse_expr_lalrpop("3 + 5 * 10").ok(),
Some(Box::new(NaturalPlus(Box::new(NaturalLit(3)),
Box::new(NaturalTimes(Box::new(NaturalLit(5)),
Box::new(NaturalLit(10))))))));
// The original parser is apparently right-associative
- assert_eq!(parse_expr("2 * 3 * 4").ok(),
+ assert_eq!(parse_expr_lalrpop("2 * 3 * 4").ok(),
Some(Box::new(NaturalTimes(Box::new(NaturalLit(2)),
Box::new(NaturalTimes(Box::new(NaturalLit(3)),
Box::new(NaturalLit(4))))))));
- assert!(parse_expr("((((22))))").is_ok());
- assert!(parse_expr("((22)").is_err());
- println!("{:?}", parse_expr("\\(b : Bool) -> b == False"));
- assert!(parse_expr("\\(b : Bool) -> b == False").is_ok());
- println!("{:?}", parse_expr("foo.bar"));
- assert!(parse_expr("foo.bar").is_ok());
- assert!(parse_expr("[] : List Bool").is_ok());
-
- // println!("{:?}", parse_expr("< Left = True | Right : Natural >"));
- // println!("{:?}", parse_expr(r#""bl${42}ah""#));
- // assert!(parse_expr("< Left = True | Right : Natural >").is_ok());
+ assert!(parse_expr_lalrpop("((((22))))").is_ok());
+ assert!(parse_expr_lalrpop("((22)").is_err());
+ println!("{:?}", parse_expr_lalrpop("\\(b : Bool) -> b == False"));
+ assert!(parse_expr_lalrpop("\\(b : Bool) -> b == False").is_ok());
+ println!("{:?}", parse_expr_lalrpop("foo.bar"));
+ assert!(parse_expr_lalrpop("foo.bar").is_ok());
+ assert!(parse_expr_lalrpop("[] : List Bool").is_ok());
+
+ // println!("{:?}", parse_expr_lalrpop("< Left = True | Right : Natural >"));
+ // println!("{:?}", parse_expr_lalrpop(r#""bl${42}ah""#));
+ // assert!(parse_expr_lalrpop("< Left = True | Right : Natural >").is_ok());
}