diff --git a/src/combinators.rs b/src/combinators.rs index 30a145d..1b6aaf3 100644 --- a/src/combinators.rs +++ b/src/combinators.rs @@ -9,7 +9,9 @@ use crate::combinators::left_right_parsers::{LeftParser, RightParser}; use crate::combinators::many_parsers::{ Many1Parser, Many1TillParser, ManyParser, ManyTillParser, Skip1Parser, SkipParser, }; -use crate::combinators::separated_parsers::{SeparateBy1Parser, SeparateOrEndBy1Parser}; +use crate::combinators::separated_parsers::{ + QuoteParser, SeparateBy1Parser, SeparateOrEndBy1Parser, +}; use crate::combinators::tuple_parser::{ParserTuple, TupleParser}; use crate::parser::{any, Parser}; use std::fmt::Debug; @@ -190,7 +192,13 @@ where PLeft: Parser<'a, TToken, TLeft, TContext>, PRight: Parser<'a, TToken, TRight, TContext>, { - left.right(parser.many_till(right)) + QuoteParser { + left, + parser, + right, + left_data: PhantomData, + right_data: PhantomData, + } } pub fn separate_by1<'a, TToken, T: 'a, TSeparator: 'a, TContext, P, PSeparator>( diff --git a/src/combinators/many_parsers.rs b/src/combinators/many_parsers.rs index 6b3e35d..0b5bd65 100644 --- a/src/combinators/many_parsers.rs +++ b/src/combinators/many_parsers.rs @@ -270,6 +270,18 @@ mod test { char_parser('a').many_till(char_parser('b')).parse(c, i) }); + parser_test_helper( + ParserContext::new_with_str("aaabc", ()), + &vec!['a', 'a', 'a'], + |c, i| { + char_parser('a') + .many_till(char_parser('b')) + .left(char_parser('b')) + .left(char_parser('c')) + .parse(c, i) + }, + ); + failed_parser_test_helper(ParserContext::new_with_str("aaacb", ()), |c, i| { char_parser('a').many_till(char_parser('b')).parse(c, i) }); diff --git a/src/combinators/separated_parsers.rs b/src/combinators/separated_parsers.rs index 2722cf5..e6b66d9 100644 --- a/src/combinators/separated_parsers.rs +++ b/src/combinators/separated_parsers.rs @@ -1,9 +1,60 @@ -use crate::parser::{Parser, ParserContext, ParserResult}; +use crate::parser::{FailedParserResult, Parser, ParserContext, ParserResult}; use std::cell::RefCell; use std::fmt::Debug; use std::marker::PhantomData; use std::rc::Rc; +pub struct QuoteParser
{
+ pub(crate) parser: P,
+ pub(crate) left: PLeft,
+ pub(crate) right: PRight,
+ pub(crate) left_data: PhantomData
+where
+ TToken: Debug + Clone,
+ P: Parser<'a, TToken, T, TContext>,
+ PLeft: Parser<'a, TToken, TLeft, TContext>,
+ PRight: Parser<'a, TToken, TRight, TContext>,
+{
+ fn parse(
+ &self,
+ context: Rc {
pub(crate) parser: P,
pub(crate) separator: PSeparator,
@@ -82,6 +133,7 @@ mod test {
use super::*;
use crate::combinators::{
end_by, end_by1, quote, separate_by, separate_by1, separate_or_end_by, separate_or_end_by1,
+ ParserExt,
};
use crate::parser::{failed_parser_test_helper, parser_test_helper, satisfy};
use crate::text::char_parser;
@@ -106,7 +158,17 @@ mod test {
parser,
);
parser_test_helper(ParserContext::new_with_str("''", ()), &vec![], parser);
- failed_parser_test_helper(ParserContext::new_with_str("asd", ()), parser)
+ failed_parser_test_helper(ParserContext::new_with_str("asd", ()), parser);
+
+ parser_test_helper(
+ ParserContext::new_with_str("'a'b", ()),
+ &vec!['a'],
+ |c, i| {
+ quote(char_parser('\''), char_parser('a'), char_parser('\''))
+ .left(char_parser('b'))
+ .parse(c, i)
+ },
+ )
}
#[test]