@@ -895,13 +895,96 @@ where
895
895
#[ derive( Copy , Clone ) ]
896
896
pub struct Loop < F , S > ( F , S ) ;
897
897
898
- impl < Input , F , P , G , S > Parser < Input > for Loop < F , S >
898
+ impl < Input , F , S , P , G > Parser < Input > for Loop < F , S >
899
+ where
900
+ Input : Stream ,
901
+ F : FnMut ( & mut S ) -> P ,
902
+ S : Clone ,
903
+ P : Parser < Input , Output = G > ,
904
+ G : FnOnce ( & mut S )
905
+ {
906
+ type Output = S ;
907
+ type PartialState = ( Option < S > , Option < P > , bool , P :: PartialState ) ;
908
+
909
+ parse_mode ! ( Input ) ;
910
+ #[ inline]
911
+ fn parse_mode_impl < M > (
912
+ & mut self ,
913
+ mode : M ,
914
+ input : & mut Input ,
915
+ state : & mut Self :: PartialState ,
916
+ ) -> ParseResult < Self :: Output , <Input as StreamOnce >:: Error >
917
+ where
918
+ M : ParseMode ,
919
+ {
920
+ let Self ( ref mut next_func, ref init_state) = * self ;
921
+ LoopGen ( next_func, || init_state. clone ( ) ) . parse_mode_impl ( mode, input, state)
922
+ }
923
+ }
924
+
925
+ // Takes a function `func` and initial `state`. Function is applied to current
926
+ // state and generates a parser outputting function to update the state. This
927
+ // is repeated until the generated parser fails.
928
+ //
929
+ /// ```
930
+ /// # extern crate combine;
931
+ /// # use std::collections::HashMap;
932
+ /// # use combine::{Parser, Stream, many1, token, value, unexpected_any, optional, choice};
933
+ /// # use combine::parser::char::digit;
934
+ /// # use combine::parser::sequence::loop_parser;
935
+ /// # fn main() {
936
+ /// // Parses 'a', 'b' and 'c' such that there is no consecutive letters returning their count
937
+ /// #[derive(PartialEq, Eq, Clone, Hash)]
938
+ /// enum Token { A, B, C }
939
+ /// fn token_parser<Input>(last_token: &Option<Token>) -> impl Parser<Input, Output = Token>
940
+ /// where
941
+ /// Input: Stream<Token = char>
942
+ /// {
943
+ /// let mut choices = vec![];
944
+ /// if *last_token != Some(Token::A) {
945
+ /// choices.push(token('a').map(|_| Token::A).left());
946
+ /// }
947
+ /// if *last_token != Some(Token::B) {
948
+ /// choices.push(token('b').map(|_| Token::B).left().right());
949
+ /// }
950
+ /// if *last_token != Some(Token::C) {
951
+ /// choices.push(token('c').map(|_| Token::C).right().right());
952
+ /// }
953
+ /// choice(choices)
954
+ /// }
955
+ /// let result = loop_parser((HashMap::<Token, usize>::new(), None), |(_, last_token)| {
956
+ /// token_parser(last_token).map(|current_token| move |(ref mut acc, ref mut last_token): &mut (HashMap::<Token, usize>, Option<Token>)| {
957
+ /// *acc.entry(current_token.clone()).or_insert(0) += 1;
958
+ /// *last_token = Some(current_token);
959
+ /// })
960
+ /// }).map(|x| x.0).parse("ababacbcbcaa");
961
+ /// assert_eq!(result.as_ref().map(|x| x.0.get(&Token::A)), Ok(Some(&4)));
962
+ /// assert_eq!(result.as_ref().map(|x| x.0.get(&Token::B)), Ok(Some(&4)));
963
+ /// assert_eq!(result.as_ref().map(|x| x.0.get(&Token::C)), Ok(Some(&3)));
964
+ /// assert_eq!(result.as_ref().map(|x| x.1), Ok("a"));
965
+ /// # }
966
+ /// ```
967
+ pub fn loop_parser < Input , F , P , G , S > ( state : S , func : F ) -> Loop < F , S >
899
968
where
900
969
Input : Stream ,
901
970
F : FnMut ( & mut S ) -> P ,
902
971
P : Parser < Input , Output = G > ,
903
972
G : FnOnce ( & mut S ) ,
904
973
S : Clone
974
+ {
975
+ Loop ( func, state)
976
+ }
977
+
978
+ #[ derive( Copy , Clone ) ]
979
+ pub struct LoopGen < F , G > ( F , G ) ;
980
+
981
+ impl < Input , F , G , S , P , H > Parser < Input > for LoopGen < F , G >
982
+ where
983
+ Input : Stream ,
984
+ F : FnMut ( & mut S ) -> P ,
985
+ G : FnMut ( ) -> S ,
986
+ P : Parser < Input , Output = H > ,
987
+ H : FnOnce ( & mut S )
905
988
{
906
989
type Output = S ;
907
990
type PartialState = ( Option < S > , Option < P > , bool , P :: PartialState ) ;
@@ -917,13 +1000,13 @@ where
917
1000
where
918
1001
M : ParseMode ,
919
1002
{
920
- let Self ( ref mut next_func, ref init_state ) = * self ;
1003
+ let Self ( ref mut next_func, ref mut state_gen ) = * self ;
921
1004
let ( ref mut state, ref mut parser, ref mut committed, ref mut partial_state) = * state;
922
1005
if mode. is_first ( ) {
923
1006
debug_assert ! ( state. is_none( ) ) ;
924
1007
debug_assert ! ( parser. is_none( ) ) ;
925
1008
debug_assert ! ( !* committed) ;
926
- * state = Some ( init_state . clone ( ) ) ;
1009
+ * state = Some ( state_gen ( ) ) ;
927
1010
* parser = Some ( next_func ( state. as_mut ( ) . unwrap ( ) ) ) ;
928
1011
}
929
1012
let parser = parser. as_mut ( ) . unwrap ( ) ;
@@ -957,20 +1040,16 @@ where
957
1040
}
958
1041
}
959
1042
960
-
961
- // If `init` is not `None` it parses using it first. Than subsequently
962
- // applies `func` to result until `None` is returned. The result is
963
- // the last state.
964
- //
965
- // Otherwise, if `init` is `None`, it returns the `state` without
966
- // consuming any input.
1043
+ // Takes a function `func` and initial `state`. Function is applied to current
1044
+ // state and generates a parser outputting function to update the state. This
1045
+ // is repeated until the generated parser fails.
967
1046
//
968
1047
/// ```
969
1048
/// # extern crate combine;
970
1049
/// # use std::collections::HashMap;
971
1050
/// # use combine::{Parser, Stream, many1, token, value, unexpected_any, optional, choice};
972
1051
/// # use combine::parser::char::digit;
973
- /// # use combine::parser::sequence::loop_parser ;
1052
+ /// # use combine::parser::sequence::loop_gen ;
974
1053
/// # fn main() {
975
1054
/// // Parses 'a', 'b' and 'c' such that there is no consecutive letters returning their count
976
1055
/// #[derive(PartialEq, Eq, Clone, Hash)]
@@ -991,7 +1070,7 @@ where
991
1070
/// }
992
1071
/// choice(choices)
993
1072
/// }
994
- /// let result = loop_parser( (HashMap::<Token, usize>::new(), None), |(_, last_token)| {
1073
+ /// let result = loop_gen(|| (HashMap::<Token, usize>::new(), None), |(_, last_token)| {
995
1074
/// token_parser(last_token).map(|current_token| move |(ref mut acc, ref mut last_token): &mut (HashMap::<Token, usize>, Option<Token>)| {
996
1075
/// *acc.entry(current_token.clone()).or_insert(0) += 1;
997
1076
/// *last_token = Some(current_token);
@@ -1003,13 +1082,13 @@ where
1003
1082
/// assert_eq!(result.as_ref().map(|x| x.1), Ok("a"));
1004
1083
/// # }
1005
1084
/// ```
1006
- pub fn loop_parser < Input , F , P , G , S > ( state : S , func : F ) -> Loop < F , S >
1085
+ pub fn loop_gen < Input , F , G , S , P , H > ( state_gen : G , func : F ) -> LoopGen < F , G >
1007
1086
where
1008
1087
Input : Stream ,
1009
1088
F : FnMut ( & mut S ) -> P ,
1010
- P : Parser < Input , Output = G > ,
1011
- G : FnOnce ( & mut S ) ,
1012
- S : Clone
1089
+ G : FnMut ( ) -> S ,
1090
+ P : Parser < Input , Output = H > ,
1091
+ H : FnOnce ( & mut S )
1013
1092
{
1014
- Loop ( func, state )
1093
+ LoopGen ( func, state_gen )
1015
1094
}
0 commit comments