summaryrefslogtreecommitdiff
path: root/dhall_core
diff options
context:
space:
mode:
authorNadrieril2019-03-06 23:48:32 +0100
committerNadrieril2019-03-06 23:48:32 +0100
commite3813e7d4e3450704c1213fd6cdff7c801ccbc34 (patch)
tree86b248b5e1c8a0053a1a447b5ff4e38c267fcb3e /dhall_core
parent54382cd107d1befd6015f8232716158a20db44a4 (diff)
Finally get rid of old parser
Diffstat (limited to 'dhall_core')
-rw-r--r--dhall_core/Cargo.toml7
-rw-r--r--dhall_core/build.rs6
-rw-r--r--dhall_core/src/grammar.lalrpop164
-rw-r--r--dhall_core/src/grammar_util.rs5
-rw-r--r--dhall_core/src/lexer.rs394
-rw-r--r--dhall_core/src/lib.rs3
-rw-r--r--dhall_core/src/parser.rs53
7 files changed, 22 insertions, 610 deletions
diff --git a/dhall_core/Cargo.toml b/dhall_core/Cargo.toml
index dcd5c1f..4010f4a 100644
--- a/dhall_core/Cargo.toml
+++ b/dhall_core/Cargo.toml
@@ -3,19 +3,12 @@ name = "dhall_core"
version = "0.1.0"
authors = ["NanoTech <nanotech@nanotechcorp.net>", "Nadrieril <nadrieril@users.noreply.github.com>"]
edition = "2018"
-build = "build.rs"
[lib]
doctest = false
-[build-dependencies]
-lalrpop = "0.16.3"
-
[dependencies]
-bytecount = "0.5.1"
itertools = "0.8.0"
-lalrpop-util = "0.16.3"
-nom = "3.0.0"
term-painter = "0.2.3"
pest = { git = "https://github.com/pest-parser/pest" }
dhall_parser = { path = "../dhall_parser" }
diff --git a/dhall_core/build.rs b/dhall_core/build.rs
deleted file mode 100644
index 946841a..0000000
--- a/dhall_core/build.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use lalrpop;
-
-fn main() {
- lalrpop::process_root().unwrap();
- println!("cargo:rerun-if-changed=src/grammar.lalrpop");
-}
diff --git a/dhall_core/src/grammar.lalrpop b/dhall_core/src/grammar.lalrpop
deleted file mode 100644
index 1ffe2ff..0000000
--- a/dhall_core/src/grammar.lalrpop
+++ /dev/null
@@ -1,164 +0,0 @@
-use std::collections::BTreeMap;
-use std::iter;
-use std::iter::FromIterator;
-
-use crate::core;
-use crate::core::bx;
-use crate::core::Expr::*;
-use crate::core::Builtin;
-use crate::core::Builtin::*;
-use crate::core::BinOp::*;
-use crate::grammar_util::*;
-use crate::lexer::*;
-
-grammar<'input>;
-
-extern {
- type Location = usize;
- type Error = LexicalError;
-
- enum Tok<'input> {
- Pi => Tok::Pi,
- Lambda => Tok::Lambda,
- Combine => Tok::Combine,
- "->" => Tok::Arrow,
-
- Int => Tok::Integer(<isize>),
- Nat => Tok::Natural(<usize>),
- Text => Tok::Text(<String>),
- Bool => Tok::Bool(<bool>),
- Label => Tok::Identifier(<&'input str>),
- Const => Tok::Const(<core::Const>),
- Let => Tok::Keyword(Keyword::Let),
- In => Tok::Keyword(Keyword::In),
- If => Tok::Keyword(Keyword::If),
- Then => Tok::Keyword(Keyword::Then),
- Else => Tok::Keyword(Keyword::Else),
- List => Tok::ListLike(ListLike::List),
- Optional => Tok::ListLike(ListLike::Optional),
- Builtin => Tok::Builtin(<Builtin>),
-
- "{" => Tok::BraceL,
- "}" => Tok::BraceR,
- "[" => Tok::BracketL,
- "]" => Tok::BracketR,
- "(" => Tok::ParenL,
- ")" => Tok::ParenR,
- "&&" => Tok::BoolAnd,
- "||" => Tok::BoolOr,
- "==" => Tok::CompareEQ,
- "!=" => Tok::CompareNE,
- "++" => Tok::Append,
- "*" => Tok::Times,
- "+" => Tok::Plus,
- "," => Tok::Comma,
- "." => Tok::Dot,
- ":" => Tok::Ascription,
- "=" => Tok::Equals,
- }
-}
-
-pub Expr: BoxExpr<'input> = { // exprA
- ExprB,
-};
-
-ExprB: BoxExpr<'input> = {
- Lambda "(" <Label> ":" <Expr> ")" "->" <ExprB> => bx(Lam(<>)),
- Pi "(" <Label> ":" <Expr> ")" "->" <ExprB> => bx(Pi(<>)),
- If <Expr> Then <ExprB> Else <ExprC> => bx(BoolIf(<>)),
- <ExprC> "->" <ExprB> => bx(Pi("_", <>)),
- Let <Label> <(":" <Expr>)?> "=" <Expr> In <ExprB> => bx(Let(<>)),
- "[" <a:Elems> "]" ":" <b:ListLike> <c:ExprE> => bx(b(Some(c), a)),
- <ExprC> ":" <Expr> => bx(Annot(<>)),
- ExprC,
-};
-
-ListLike: ExprListFn<'input> = {
- List => ListLit,
- Optional => OptionalLit,
-};
-
-BoolOr: ExprOpFn<'input> = { "||" => (|x,y| BinOp(BoolOr, x, y)) };
-NaturalPlus: ExprOpFn<'input> = { "+" => (|x,y| BinOp(NaturalPlus, x, y)) };
-TextAppend: ExprOpFn<'input> = { "++" => (|x,y| BinOp(TextAppend, x, y)) };
-BoolAnd: ExprOpFn<'input> = { "&&" => (|x,y| BinOp(BoolAnd, x, y)) };
-CombineOp: ExprOpFn<'input> = { Combine => (|x,y| BinOp(Combine, x, y)) };
-NaturalTimes: ExprOpFn<'input> = { "*" => (|x,y| BinOp(NaturalTimes, x, y)) };
-BoolEQ: ExprOpFn<'input> = { "==" => (|x,y| BinOp(BoolEQ, x, y)) };
-BoolNE: ExprOpFn<'input> = { "!=" => (|x,y| BinOp(BoolNE, x, y)) };
-
-Tier<NextTier, Op>: BoxExpr<'input> = {
- <a:NextTier> <f:Op> <b:Tier<NextTier, Op>> => bx(f(a, b)),
- // <b:Tier<NextTier, Op>> <f:Op> <a:NextTier> => bx(f(a, b)),
- NextTier,
-};
-
-ExprC = Tier<ExprC1, BoolOr>;
-ExprC1 = Tier<ExprC2, NaturalPlus>;
-ExprC2 = Tier<ExprC3, TextAppend>;
-ExprC3 = Tier<ExprC4, BoolAnd>;
-ExprC4 = Tier<ExprC5, CombineOp>;
-ExprC5 = Tier<ExprC6, NaturalTimes>;
-ExprC6 = Tier<ExprC7, BoolEQ>;
-ExprC7 = Tier<ExprD, BoolNE>;
-
-ExprD: BoxExpr<'input> = {
- <v:(ExprE)+> => {
- let mut it = v.into_iter();
- let f = it.next().unwrap();
- it.fold(f, |f, x| bx(App(f, x)))
- }
-};
-
-ExprE: BoxExpr<'input> = {
- <a:ExprF> <fields:("." <Label>)*> => {
- fields.into_iter().fold(a, |x, f| bx(Field(x, f)))
- },
-};
-
-ExprF: BoxExpr<'input> = {
- Nat => bx(NaturalLit(<>)),
- Int => bx(IntegerLit(<>)),
- Text => bx(TextLit(<>)),
- Label => bx(Var(core::V(<>, 0))), // FIXME support var@n syntax
- Const => bx(Const(<>)),
- List => bx(Builtin(List)),
- Optional => bx(Builtin(Optional)),
- Builtin => bx(Builtin(<>)),
- Bool => bx(BoolLit(<>)),
- Record,
- RecordLit,
- "(" <Expr> ")",
-};
-
-SepBy<S, T>: iter::Chain<::std::vec::IntoIter<T>, ::std::option::IntoIter<T>> = {
- <v:(<T> S)*> <last:T?> => v.into_iter().chain(last.into_iter()),
-};
-
-SepBy1<S, T>: iter::Chain<::std::vec::IntoIter<T>, iter::Once<T>> = {
- <v:(<T> S)*> <last:T> => v.into_iter().chain(iter::once(last)),
-};
-
-Elems: Vec<ParsedExpr<'input>> = {
- <v:SepBy<",", Expr>> => {
- v.into_iter()
- .map(|b| *b)
- .collect::<Vec<_>>()
- }
-};
-
-RecordLit: BoxExpr<'input> = {
- "{" "=" "}" => bx(RecordLit(BTreeMap::new())),
- "{" <FieldValues> "}" => bx(RecordLit(BTreeMap::from_iter(<>))),
-};
-
-Record: BoxExpr<'input> = {
- "{" <FieldTypes> "}" => bx(Record(BTreeMap::from_iter(<>))),
-};
-
-FieldValues = SepBy1<",", Field<"=">>;
-FieldTypes = SepBy<",", Field<":">>;
-
-Field<Sep>: (&'input str, ParsedExpr<'input>) = {
- <a:Label> Sep <b:Expr> => (a, *b),
-};
diff --git a/dhall_core/src/grammar_util.rs b/dhall_core/src/grammar_util.rs
index 82528f4..73f935f 100644
--- a/dhall_core/src/grammar_util.rs
+++ b/dhall_core/src/grammar_util.rs
@@ -1,7 +1,4 @@
-use crate::core::{Expr, X, Import};
+use crate::core::{Expr, Import, X};
pub type ParsedExpr<'i> = Expr<'i, X, Import>;
pub type BoxExpr<'i> = Box<ParsedExpr<'i>>;
-pub type ExprOpFn<'i> = fn(BoxExpr<'i>, BoxExpr<'i>) -> ParsedExpr<'i>;
-pub type ExprListFn<'i> =
- fn(Option<BoxExpr<'i>>, Vec<ParsedExpr<'i>>) -> ParsedExpr<'i>;
diff --git a/dhall_core/src/lexer.rs b/dhall_core/src/lexer.rs
deleted file mode 100644
index 5fc0f05..0000000
--- a/dhall_core/src/lexer.rs
+++ /dev/null
@@ -1,394 +0,0 @@
-use nom::*;
-
-use crate::core::Builtin;
-use crate::core::Builtin::*;
-use crate::core::Const;
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum Keyword {
- Let,
- In,
- If,
- Then,
- Else,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ListLike {
- List,
- Optional,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum Tok<'i> {
- Identifier(&'i str),
- Keyword(Keyword),
- Builtin(Builtin),
- ListLike(ListLike),
- Const(Const),
- Bool(bool),
- Integer(isize),
- Natural(usize),
- Text(String),
-
- // Symbols
- BraceL,
- BraceR,
- BracketL,
- BracketR,
- ParenL,
- ParenR,
- Arrow,
- Lambda,
- Pi,
- Combine,
- BoolAnd,
- BoolOr,
- CompareEQ,
- CompareNE,
- Append,
- Times,
- Plus,
- Comma,
- Dot,
- Ascription,
- Equals,
-}
-
-#[derive(Debug)]
-pub enum LexicalError {
- Error(usize, nom::simple_errors::Err<u32>),
- Incomplete(nom::Needed),
-}
-
-pub type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
-
-#[allow(dead_code)]
-fn is_identifier_first_char(c: char) -> bool {
- c.is_alphabetic() || c == '_'
-}
-
-fn is_identifier_rest_char(c: char) -> bool {
- is_identifier_first_char(c) || c.is_digit(10) || c == '/'
-}
-
-macro_rules! digits {
- ($i:expr, $t:tt, $radix:expr) => {{
- let r: nom::IResult<&str, $t> = map_res!(
- $i,
- take_while1_s!(call!(|c: char| c.is_digit($radix))),
- |s| $t::from_str_radix(s, $radix)
- );
- r
- }};
-}
-
-named!(natural<&str, usize>, digits!(usize, 10));
-named!(integral<&str, isize>, digits!(isize, 10));
-named!(integer<&str, isize>, alt!(
- preceded!(tag!("-"), map!(integral, |i: isize| -i)) |
- preceded!(tag!("+"), integral)
-));
-named!(boolean<&str, bool>, alt!(
- value!(true, tag!("True")) |
- value!(false, tag!("False"))
-));
-
-named!(identifier<&str, &str>, recognize!(preceded!(
- take_while1_s!(is_identifier_first_char),
- take_while_s!(is_identifier_rest_char))
-));
-
-/// Parse an identifier, ensuring a whole identifier is parsed and not just a prefix.
-macro_rules! ident_tag {
- ($i:expr, $tag:expr) => {
- match identifier($i) {
- nom::IResult::Done(i, s) => {
- if s == $tag {
- nom::IResult::Done(i, s)
- } else {
- nom::IResult::Error(error_position!(
- nom::ErrorKind::Tag,
- $i
- ))
- }
- }
- r => r,
- }
- };
-}
-
-fn string_escape_single(c: char) -> Option<&'static str> {
- match c {
- 'n' => Some("\n"),
- 'r' => Some("\r"),
- 't' => Some("\t"),
- '"' => Some("\""),
- '\'' => Some("'"),
- '\\' => Some("\\"),
- '0' => Some("\0"),
- 'a' => Some("\x07"),
- 'b' => Some("\x08"),
- 'f' => Some("\x0c"),
- 'v' => Some("\x0b"),
- '&' => Some(""),
- _ => None,
- }
-}
-
-named!(string_escape_numeric<&str, char>, map_opt!(alt!(
- preceded!(tag!("x"), digits!(u32, 16)) |
- preceded!(tag!("o"), digits!(u32, 8)) |
- digits!(u32, 10)
-), ::std::char::from_u32));
-
-fn string_lit_inner(input: &str) -> nom::IResult<&str, String> {
- use nom::ErrorKind;
- use nom::IResult::*; ;
- let mut s = String::new();
- let mut cs = input.char_indices().peekable();
- while let Some((i, c)) = cs.next() {
- match c {
- '"' => return nom::IResult::Done(&input[i..], s),
- '\\' => match cs.next() {
- Some((_, s)) if s.is_whitespace() => {
- while cs.peek().map(|&(_, s)| s.is_whitespace())
- == Some(true)
- {
- let _ = cs.next();
- }
- if cs.next().map(|p| p.1) != Some('\\') {
- return Error(error_position!(
- ErrorKind::Custom(4 /* FIXME */),
- input
- ));
- }
- }
- Some((j, ec)) => {
- if let Some(esc) = string_escape_single(ec) {
- s.push_str(esc);
- // FIXME Named ASCII escapes and control character escapes
- } else {
- match string_escape_numeric(&input[j..]) {
- Done(rest, esc) => {
- let &(k, _) = cs.peek().unwrap();
- // digits are always single byte ASCII characters
- let consumed = input[k..].len() - rest.len();
- for _ in 0..consumed {
- let _ = cs.next();
- }
- s.push(esc);
- }
- Incomplete(s) => return Incomplete(s),
- Error(e) => return Error(e),
- }
- }
- }
- _ => {
- return Error(error_position!(
- ErrorKind::Custom(5 /* FIXME */),
- input
- ));
- }
- },
- _ => s.push(c),
- }
- }
- Error(error_position!(ErrorKind::Custom(3 /* FIXME */), input))
-}
-
-named!(string_lit<&str, String>, delimited!(tag!("\""), string_lit_inner, tag!("\"")));
-
-named!(keyword<&str, Keyword>, alt!(
- value!(Keyword::Let, ident_tag!("let")) |
- value!(Keyword::In, ident_tag!("in")) |
- value!(Keyword::If, ident_tag!("if")) |
- value!(Keyword::Then, ident_tag!("then")) |
- value!(Keyword::Else, ident_tag!("else"))
-));
-
-named!(type_const<&str, Const>, alt!(
- value!(Const::Type, ident_tag!("Type")) |
- value!(Const::Kind, ident_tag!("Kind"))
-));
-
-named!(list_like<&str, ListLike>, alt!(
- value!(ListLike::List, ident_tag!("List")) |
- value!(ListLike::Optional, ident_tag!("Optional"))
-));
-
-named!(builtin<&str, Builtin>, alt!(
- value!(NaturalFold, ident_tag!("Natural/fold")) |
- value!(NaturalBuild, ident_tag!("Natural/build")) |
- value!(NaturalIsZero, ident_tag!("Natural/isZero")) |
- value!(NaturalEven, ident_tag!("Natural/even")) |
- value!(NaturalOdd, ident_tag!("Natural/odd")) |
- value!(NaturalShow, ident_tag!("Natural/show")) |
- value!(Natural, ident_tag!("Natural")) |
- value!(Integer, ident_tag!("Integer")) |
- value!(Double, ident_tag!("Double")) |
- value!(Text, ident_tag!("Text")) |
- value!(ListBuild, ident_tag!("List/build")) |
- value!(ListFold, ident_tag!("List/fold")) |
- value!(ListLength, ident_tag!("List/length")) |
- value!(ListHead, ident_tag!("List/head")) |
- value!(ListLast, ident_tag!("List/last")) |
- value!(ListIndexed, ident_tag!("List/indexed")) |
- value!(ListReverse, ident_tag!("List/reverse")) |
- value!(OptionalFold, ident_tag!("Optional/fold")) |
- value!(Bool, ident_tag!("Bool"))
-));
-
-named!(token<&str, Tok>, alt!(
- value!(Tok::Pi, ident_tag!("forall")) |
- value!(Tok::Pi, tag!("∀")) |
- value!(Tok::Lambda, tag!("\\")) |
- value!(Tok::Lambda, tag!("λ")) |
- value!(Tok::Combine, tag!("/\\")) |
- value!(Tok::Combine, tag!("∧")) |
- value!(Tok::Arrow, tag!("->")) |
- value!(Tok::Arrow, tag!("→")) |
-
- map!(type_const, Tok::Const) |
- map!(boolean, Tok::Bool) |
- map!(keyword, Tok::Keyword) |
- map!(builtin, Tok::Builtin) |
- map!(list_like, Tok::ListLike) |
- map!(natural, Tok::Natural) |
- map!(integer, Tok::Integer) |
- map!(identifier, Tok::Identifier) |
- map!(string_lit, Tok::Text) |
-
- value!(Tok::BraceL, tag!("{")) |
- value!(Tok::BraceR, tag!("}")) |
- value!(Tok::BracketL, tag!("[")) |
- value!(Tok::BracketR, tag!("]")) |
- value!(Tok::ParenL, tag!("(")) |
- value!(Tok::ParenR, tag!(")")) |
- value!(Tok::BoolAnd, tag!("&&")) |
- value!(Tok::BoolOr, tag!("||")) |
- value!(Tok::CompareEQ, tag!("==")) |
- value!(Tok::CompareNE, tag!("!=")) |
- value!(Tok::Append, tag!("++")) |
- value!(Tok::Times, tag!("*")) |
- value!(Tok::Plus, tag!("+")) |
- value!(Tok::Comma, tag!(",")) |
- value!(Tok::Dot, tag!(".")) |
- value!(Tok::Ascription, tag!(":")) |
- value!(Tok::Equals, tag!("="))
-));
-
-fn find_end(input: &str, ending: &str) -> Option<usize> {
- input.find(ending).map(|i| i + ending.len())
-}
-
-pub struct Lexer<'input> {
- input: &'input str,
- offset: usize,
-}
-
-impl<'input> Lexer<'input> {
- pub fn new(input: &'input str) -> Self {
- Lexer {
- input: input,
- offset: 0,
- }
- }
-
- fn current_input(&mut self) -> &'input str {
- &self.input[self.offset..]
- }
-
- fn skip_whitespace(&mut self) -> bool {
- let input = self.current_input();
- let trimmed = input.trim_start();
- let whitespace_len = input.len() - trimmed.len();
- let skipped = whitespace_len > 0;
- if skipped {
- // println!("skipped {} whitespace bytes in {}..{}", whitespace_len, self.offset, self.offset + whitespace_len);
- self.offset += whitespace_len;
- }
- skipped
- }
-
- fn skip_comments(&mut self) -> bool {
- let input = self.current_input();
- if !input.is_char_boundary(0) || !input.is_char_boundary(2) {
- return false;
- }
- let skip = match &input[0..2] {
- "{-" => find_end(input, "-}"),
- "--" => find_end(input, "\n"), // Also skips past \r\n (CRLF)
- _ => None,
- }
- .unwrap_or(0);
- // println!("skipped {} bytes of comment", skip);
- self.offset += skip;
- skip != 0
- }
-
- fn skip_comments_and_whitespace(&mut self) {
- while self.skip_whitespace() || self.skip_comments() {}
- }
-}
-
-impl<'input> Iterator for Lexer<'input> {
- type Item = Spanned<Tok<'input>, usize, LexicalError>;
-
- fn next(&mut self) -> Option<Self::Item> {
- use nom::IResult::*;
- self.skip_comments_and_whitespace();
- let input = self.current_input();
- if input.is_empty() {
- return None;
- }
- match token(input) {
- Done(rest, t) => {
- let parsed_len = input.len() - rest.len();
- //println!("parsed {} bytes => {:?}", parsed_len, t);
- let start = self.offset;
- self.offset += parsed_len;
- Some(Ok((start, t, self.offset)))
- }
- Error(e) => {
- let offset = self.offset;
- self.offset = self.input.len();
- Some(Err(LexicalError::Error(offset, e)))
- }
- Incomplete(needed) => Some(Err(LexicalError::Incomplete(needed))),
- }
- }
-}
-
-#[test]
-fn test_lex() {
- use self::Tok::*;
- let s = "λ(b : Bool) → b == False";
- let expected = [
- Lambda,
- ParenL,
- Identifier("b"),
- Ascription,
- Builtin(crate::core::Builtin::Bool),
- ParenR,
- Arrow,
- Identifier("b"),
- CompareEQ,
- Bool(false),
- ];
- let lexer = Lexer::new(s);
- let tokens = lexer.map(|r| r.unwrap().1).collect::<Vec<_>>();
- assert_eq!(&tokens, &expected);
-
- assert_eq!(string_lit(r#""a\&b""#).to_result(), Ok("ab".to_owned()));
- assert_eq!(
- string_lit(r#""a\ \b""#).to_result(),
- Ok("ab".to_owned())
- );
- assert!(string_lit(r#""a\ b""#).is_err());
- assert_eq!(string_lit(r#""a\nb""#).to_result(), Ok("a\nb".to_owned()));
- assert_eq!(
- string_lit(r#""\o141\x62\99""#).to_result(),
- Ok("abc".to_owned())
- );
-}
diff --git a/dhall_core/src/lib.rs b/dhall_core/src/lib.rs
index 76f436d..bd53603 100644
--- a/dhall_core/src/lib.rs
+++ b/dhall_core/src/lib.rs
@@ -3,9 +3,6 @@
pub mod core;
pub use crate::core::*;
-use lalrpop_util::lalrpop_mod;
-lalrpop_mod!(pub grammar);
pub mod context;
mod grammar_util;
-pub mod lexer;
pub mod parser;
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 09863a2..34327b1 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -1,24 +1,13 @@
-use std::collections::BTreeMap;
-// use itertools::*;
-use lalrpop_util;
use pest::iterators::Pair;
use pest::Parser;
+use std::collections::BTreeMap;
use std::path::PathBuf;
use dhall_parser::{DhallParser, Rule};
use crate::core;
use crate::core::*;
-use crate::grammar;
use crate::grammar_util::{BoxExpr, ParsedExpr};
-use crate::lexer::{Lexer, LexicalError, Tok};
-
-pub fn parse_expr_lalrpop(
- s: &str,
-) -> Result<BoxExpr, lalrpop_util::ParseError<usize, Tok, LexicalError>> {
- grammar::ExprParser::new().parse(Lexer::new(s))
- // Ok(bx(Expr::BoolLit(false)))
-}
pub type ParseError = pest::error::Error<Rule>;
@@ -818,7 +807,7 @@ rule!(final_expression<BoxExpr<'a>>;
children!(e: expression, _eoi: EOI) => e
);
-pub fn parse_expr_pest(s: &str) -> ParseResult<BoxExpr> {
+pub fn parse_expr(s: &str) -> ParseResult<BoxExpr> {
let pairs = DhallParser::parse(Rule::final_expression, s)?;
// Match the only item in the pairs iterator
match_iter!(@panic; pairs; (p) => expression(p))
@@ -832,12 +821,12 @@ 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_lalrpop(expr));
+ println!("{:?}", parse_expr(expr));
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) {
+ .spawn(move || match parse_expr(expr) {
Err(e) => {
println!("{:?}", e);
println!("{}", e);
@@ -847,14 +836,14 @@ fn test_parse() {
.unwrap()
.join()
.unwrap();
- // assert_eq!(parse_expr_pest(expr).unwrap(), parse_expr_lalrpop(expr).unwrap());
+ // assert_eq!(parse_expr(expr).unwrap(), parse_expr(expr).unwrap());
// assert!(false);
- println!("test {:?}", parse_expr_lalrpop("3 + 5 * 10"));
- assert!(parse_expr_lalrpop("22").is_ok());
- assert!(parse_expr_lalrpop("(22)").is_ok());
+ println!("test {:?}", parse_expr("3 + 5 * 10"));
+ assert!(parse_expr("22").is_ok());
+ assert!(parse_expr("(22)").is_ok());
assert_eq!(
- parse_expr_lalrpop("3 + 5 * 10").ok(),
+ parse_expr("3 + 5 * 10").ok(),
Some(Box::new(BinOp(
NaturalPlus,
Box::new(NaturalLit(3)),
@@ -867,7 +856,7 @@ fn test_parse() {
);
// The original parser is apparently right-associative
assert_eq!(
- parse_expr_lalrpop("2 * 3 * 4").ok(),
+ parse_expr("2 * 3 * 4").ok(),
Some(Box::new(BinOp(
NaturalTimes,
Box::new(NaturalLit(2)),
@@ -878,15 +867,15 @@ fn test_parse() {
))
)))
);
- 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());
+ 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());
}