From b5de8cf14fc4a6dba69bbffe655831c4fb2c292a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 7 May 2018 22:39:52 -0600 Subject: [PATCH] work on explaining parser combinators --- Chapter07/Cargo.toml | 1 + Chapter07/combinator_pattern.rs | 71 +++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/Chapter07/Cargo.toml b/Chapter07/Cargo.toml index a397d8e..a6efc01 100644 --- a/Chapter07/Cargo.toml +++ b/Chapter07/Cargo.toml @@ -3,6 +3,7 @@ name = "Chapter7" version = "1.0.0" [dependencies] +chomp = "0.3.1" [[bin]] name = "functor_pattern" diff --git a/Chapter07/combinator_pattern.rs b/Chapter07/combinator_pattern.rs index 2a86f1d..66fc828 100644 --- a/Chapter07/combinator_pattern.rs +++ b/Chapter07/combinator_pattern.rs @@ -1,3 +1,69 @@ +#[macro_use] +extern crate chomp; +use chomp::prelude::*; + +#[derive(Debug, Eq, PartialEq)] +struct Name { + first: B, + last: B, +} + +fn name(i: I) -> SimpleResult> { + parse!{i; + let first = take_while1(|c| c != b' '); + token(b' '); // skipping this char + let last = take_while1(|c| c != b'\n'); + + ret Name{ + first: first, + last: last, + } + } +} + + +trait ParseState { + fn next(&self) -> (Box>,Option); +} +struct ParseRCon(A,Result,String>); +enum ParseOutput { + Success(A), + Failure(String) +} + +fn parse_token(t: T) -> impl (Fn(Box>) -> ParseRCon>,A>) + where T: 'static + Fn(char) -> Option { + move |st: Box>| { + let (next_state,next_char) = st.next(); + match next_char { + Some(c) => ParseRCon(next_state,Ok(t(c))), + None => ParseRCon(st,Err("end of input".to_string())) + } + } +} + +fn parse_satisfy(t: T) -> impl (Fn(Box>) -> ParseRCon>,char>) + where T: 'static + Fn(char) -> bool { + parse_token(move |c| if t(c) {Some(c)} else {None}) +} + +/* +TODO + val return : 'a -> ('st, 'a) parser + val (>>=) : ('st, 'a) parser -> ('a -> ('st, 'b) parser) -> + ('st, 'b) parser + val mzero : ('st, 'a) parser + val mplus : ('st, 'a) parser -> ('st, 'a) parser -> + ('st, 'a) parser + val (>>) : ('st, 'a) parser -> ('st, 'b) parser -> + ('st, 'b) parser + + val chars : char list -> ('st,char list) char_parser + many + sepBy + <|> +*/ + fn compose(f: F, g: G) -> impl Fn(A) -> C where F: 'static + Fn(A) -> B, G: 'static + Fn(B) -> C { @@ -14,4 +80,9 @@ fn main() println!("g(1) = {}", g(1)); println!("g(12) = {}", g(12)); println!("g(123) = {}", g(123)); + + let parse_result = parse_only(name, "Martin Wernstål\n".as_bytes()).unwrap(); + println!("first:{} last:{}", + String::from_utf8_lossy(parse_result.first), + String::from_utf8_lossy(parse_result.last)); }