Compare commits

...

2 Commits

15 changed files with 301 additions and 489 deletions

View File

@ -17,7 +17,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
match self.first.parse(context.clone(), input) {
@ -38,7 +38,7 @@ mod test {
#[test]
fn alternate_test() {
fn parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, char> {
char_parser('a')
@ -47,35 +47,35 @@ mod test {
.parse(context, input)
}
parser_test_helper(ParserContext::new_with_str("a", ()), &'a', parser);
parser_test_helper(ParserContext::new_with_str("b", ()), &'b', parser);
parser_test_helper(ParserContext::new_with_str("c", ()), &'c', parser);
parser_test_helper("a", &'a', parser);
parser_test_helper("b", &'b', parser);
parser_test_helper("c", &'c', parser);
}
#[test]
fn alternate_macro_test() {
fn parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, char> {
alternate!(char_parser('a'), char_parser('b'), char_parser('c')).parse(context, input)
}
parser_test_helper(ParserContext::new_with_str("a", ()), &'a', parser);
parser_test_helper(ParserContext::new_with_str("b", ()), &'b', parser);
parser_test_helper(ParserContext::new_with_str("c", ()), &'c', parser);
parser_test_helper("a", &'a', parser);
parser_test_helper("b", &'b', parser);
parser_test_helper("c", &'c', parser);
}
#[test]
fn alternate_function_test() {
fn parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, char> {
alternate!(char_parser('a'), char_parser('b')).parse(context, input)
}
parser_test_helper(ParserContext::new_with_str("a", ()), &'a', |c, i| {
parser_test_helper("a", &'a', |c, i| {
let parser = alternate!(parser, char_parser('c'));
let parser = alternate!(parser, char_parser('d'));
parser.parse(c, i)
@ -85,27 +85,23 @@ mod test {
#[test]
fn alternate_pure_function_test() {
fn parser1(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, &[char]> {
alternate!(char_parser('a').literal(), char_parser('b').literal()).parse(context, input)
}
fn parser2(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, &[char]> {
alternate!(char_parser('c').literal(), char_parser('d').literal()).parse(context, input)
}
parser_test_helper(
ParserContext::new_with_str("a", ()),
&"a".to_owned(),
|c, i| {
parser_test_helper("a", &"a".to_owned(), |c, i| {
alternate!(parser1, parser2)
.map(|x| x.iter().map(|x| x.clone()).collect())
.parse(c, i)
},
);
});
}
}

View File

@ -19,7 +19,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
let (input, r) = self.left_parser.parse(context.clone(), input)?;
@ -46,7 +46,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TRight> {
let (input, _) = self.left_parser.parse(context.clone(), input)?;
@ -58,19 +58,19 @@ where
#[cfg(test)]
mod test {
use crate::combinators::ParserExt;
use crate::parser::{parser_test_helper, Parser, ParserContext};
use crate::parser::{parser_test_helper, Parser};
use crate::text::char_parser;
#[test]
fn left_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
parser_test_helper("abc", &'a', |c, i| {
char_parser('a').left(char_parser('b')).parse(c, i)
});
}
#[test]
fn right_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'b', |c, i| {
parser_test_helper("abc", &'b', |c, i| {
char_parser('a').right(char_parser('b')).parse(c, i)
})
}

View File

@ -15,7 +15,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let mut result = vec![];
@ -41,7 +41,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let (mut input, first_result) = self.parser.parse(context.clone(), input)?;
@ -68,7 +68,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, ()> {
let mut input = input;
@ -93,7 +93,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, ()> {
let (mut input, _) = self.parser.parse(context.clone(), input)?;
@ -121,7 +121,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let mut input = input;
@ -159,7 +159,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let (mut input, r) = self.parser.parse(context.clone(), input)?;
@ -192,142 +192,112 @@ mod test {
#[test]
fn many_test() {
parser_test_helper(
ParserContext::new_with_str("aaa", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many().parse(c, i),
);
parser_test_helper(
ParserContext::new_with_str("aaabbaa", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many().parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("bbaa", ()), &vec![], |c, i| {
parser_test_helper("aaa", &vec!['a', 'a', 'a'], |c, i| {
char_parser('a').many().parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("", ()), &vec![], |c, i| {
parser_test_helper("aaabbaa", &vec!['a', 'a', 'a'], |c, i| {
char_parser('a').many().parse(c, i)
});
parser_test_helper("bbaa", &vec![], |c, i| char_parser('a').many().parse(c, i));
parser_test_helper("", &vec![], |c, i| char_parser('a').many().parse(c, i));
}
#[test]
fn many1_test() {
parser_test_helper(
ParserContext::new_with_str("aaa", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many1().parse(c, i),
);
parser_test_helper(
ParserContext::new_with_str("aaabbaa", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many1().parse(c, i),
);
failed_parser_test_helper(ParserContext::new_with_str("bbaa", ()), |c, i| {
parser_test_helper("aaa", &vec!['a', 'a', 'a'], |c, i| {
char_parser('a').many1().parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("", ()), |c, i| {
parser_test_helper("aaabbaa", &vec!['a', 'a', 'a'], |c, i| {
char_parser('a').many1().parse(c, i)
});
failed_parser_test_helper("bbaa", |c, i| char_parser('a').many1().parse(c, i));
failed_parser_test_helper("baa", |c, i| char_parser('a').many1().parse(c, i));
}
#[test]
fn skip_test() {
parser_test_helper(ParserContext::new_with_str("aaab", ()), &'b', |c, i| {
parser_test_helper("aaab", &'b', |c, i| {
char_parser('a').skip().right(char_parser('b')).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("b", ()), &'b', |c, i| {
parser_test_helper("b", &'b', |c, i| {
char_parser('a').skip().right(char_parser('b')).parse(c, i)
});
}
#[test]
fn skip1_test() {
parser_test_helper(ParserContext::new_with_str("aaab", ()), &'b', |c, i| {
parser_test_helper("aaab", &'b', |c, i| {
char_parser('a').skip1().right(char_parser('b')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("b", ()), |c, i| {
failed_parser_test_helper("b", |c, i| {
char_parser('a').skip1().right(char_parser('b')).parse(c, i)
});
}
#[test]
fn many_till_test() {
parser_test_helper(
ParserContext::new_with_str("aaab", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many_till(char_parser('b')).parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("b", ()), &vec![], |c, i| {
parser_test_helper("aaab", &vec!['a', 'a', 'a'], |c, i| {
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| {
parser_test_helper("b", &vec![], |c, i| {
char_parser('a').many_till(char_parser('b')).parse(c, i)
});
parser_test_helper("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| {
failed_parser_test_helper("aaacb", |c, i| {
char_parser('a').many_till(char_parser('b')).parse(c, i)
});
}
#[test]
fn many1_till_test() {
parser_test_helper(
ParserContext::new_with_str("aaab", ()),
&vec!['a', 'a', 'a'],
|c, i| char_parser('a').many1_till(char_parser('b')).parse(c, i),
);
failed_parser_test_helper(ParserContext::new_with_str("b", ()), |c, i| {
parser_test_helper("aaab", &vec!['a', 'a', 'a'], |c, i| {
char_parser('a').many1_till(char_parser('b')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("aaacb", ()), |c, i| {
failed_parser_test_helper("b", |c, i| {
char_parser('a').many1_till(char_parser('b')).parse(c, i)
});
failed_parser_test_helper("aaacb", |c, i| {
char_parser('a').many1_till(char_parser('b')).parse(c, i)
});
}
#[test]
fn take_till_test() {
parser_test_helper(
ParserContext::new_with_str("aaab", ()),
&(vec!['a', 'a', 'a'], 'b'),
|c, i| tuple((take_till(char_parser('b')), char_parser('b'))).parse(c, i),
);
parser_test_helper("aaab", &(vec!['a', 'a', 'a'], 'b'), |c, i| {
tuple((take_till(char_parser('b')), char_parser('b'))).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("b", ()),
&(vec![], 'b'),
|c, i| tuple((take_till(char_parser('b')), char_parser('b'))).parse(c, i),
);
parser_test_helper("b", &(vec![], 'b'), |c, i| {
tuple((take_till(char_parser('b')), char_parser('b'))).parse(c, i)
});
}
#[test]
fn take1_till_test() {
parser_test_helper(
ParserContext::new_with_str("aaab", ()),
&(vec!['a', 'a', 'a'], 'b'),
|c, i| tuple((take1_till(char_parser('b')), char_parser('b'))).parse(c, i),
);
parser_test_helper("aaab", &(vec!['a', 'a', 'a'], 'b'), |c, i| {
tuple((take1_till(char_parser('b')), char_parser('b'))).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("b", ()), |c, i| {
failed_parser_test_helper("b", |c, i| {
tuple((take1_till(char_parser('b')), char_parser('b'))).parse(c, i)
});
}

View File

@ -22,7 +22,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let (mut input, _) = match self.left.parse(context.clone(), input) {
@ -70,7 +70,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let (mut input, first) = self.parser.parse(context.clone(), input)?;
@ -105,7 +105,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<T>> {
let (mut input, first) = self.parser.parse(context.clone(), input)?;
@ -141,7 +141,7 @@ mod test {
#[test]
fn quote_test() {
fn parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, Vec<char>> {
quote(
@ -152,150 +152,112 @@ mod test {
.parse(context, input)
}
parser_test_helper(
ParserContext::new_with_str("'abc'", ()),
&vec!['a', 'b', 'c'],
parser,
);
parser_test_helper(ParserContext::new_with_str("''", ()), &vec![], parser);
failed_parser_test_helper(ParserContext::new_with_str("asd", ()), parser);
parser_test_helper("'abc'", &vec!['a', 'b', 'c'], parser);
parser_test_helper("''", &vec![], parser);
failed_parser_test_helper("asd", parser);
parser_test_helper(
ParserContext::new_with_str("'a'b", ()),
&vec!['a'],
|c, i| {
parser_test_helper("'a'b", &vec!['a'], |c, i| {
quote(char_parser('\''), char_parser('a'), char_parser('\''))
.left(char_parser('b'))
.parse(c, i)
},
)
})
}
#[test]
fn separate_by1_test() {
parser_test_helper(
ParserContext::new_with_str("a,b,c", ()),
&vec!['a', 'b', 'c'],
|c, i| separate_by1(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("a", ()), &vec!['a'], |c, i| {
parser_test_helper("a,b,c", &vec!['a', 'b', 'c'], |c, i| {
separate_by1(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper("a", &vec!['a'], |c, i| {
separate_by1(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper("bbc", &vec!['b'], |c, i| {
separate_by1(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("bbc", ()),
&vec!['b'],
|c, i| separate_by1(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i),
);
}
#[test]
fn separate_by_test() {
parser_test_helper(
ParserContext::new_with_str("1,2,3", ()),
&vec!['1', '2', '3'],
|c, i| separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("1", ()), &vec!['1'], |c, i| {
parser_test_helper("1,2,3", &vec!['1', '2', '3'], |c, i| {
separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("", ()), &vec![], |c, i| {
parser_test_helper("1", &vec!['1'], |c, i| {
separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper("", &vec![], |c, i| {
separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper("abc", &vec!['a'], |c, i| {
separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&vec!['a'],
|c, i| separate_by(satisfy(|c: &char| c.is_ascii()), char_parser(',')).parse(c, i),
);
}
#[test]
fn end_by1_test() {
parser_test_helper(
ParserContext::new_with_str("aab", ()),
&vec!['a', 'a'],
|c, i| end_by1(char_parser('a'), char_parser('b')).parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("ab", ()), &vec!['a'], |c, i| {
parser_test_helper("aab", &vec!['a', 'a'], |c, i| {
end_by1(char_parser('a'), char_parser('b')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("b", ()), |c, i| {
parser_test_helper("ab", &vec!['a'], |c, i| {
end_by1(char_parser('a'), char_parser('b')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("cd", ()), |c, i| {
failed_parser_test_helper("b", |c, i| {
end_by1(char_parser('a'), char_parser('b')).parse(c, i)
});
failed_parser_test_helper("cd", |c, i| {
end_by1(char_parser('a'), char_parser('b')).parse(c, i)
});
}
#[test]
fn end_by_test() {
parser_test_helper(
ParserContext::new_with_str("aab", ()),
&vec!['a', 'a'],
|c, i| end_by(char_parser('a'), char_parser('b')).parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("ab", ()), &vec!['a'], |c, i| {
parser_test_helper("aab", &vec!['a', 'a'], |c, i| {
end_by(char_parser('a'), char_parser('b')).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("b", ()), &vec![], |c, i| {
parser_test_helper("ab", &vec!['a'], |c, i| {
end_by(char_parser('a'), char_parser('b')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("cd", ()), |c, i| {
parser_test_helper("b", &vec![], |c, i| {
end_by(char_parser('a'), char_parser('b')).parse(c, i)
});
failed_parser_test_helper("cd", |c, i| {
end_by(char_parser('a'), char_parser('b')).parse(c, i)
});
}
#[test]
fn separate_or_end_by1_test() {
parser_test_helper(
ParserContext::new_with_str("1,2,3,", ()),
&vec!['1', '2', '3'],
|c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(','))
.parse(c, i)
},
);
parser_test_helper(ParserContext::new_with_str("1,", ()), &vec!['1'], |c, i| {
parser_test_helper("1,2,3,", &vec!['1', '2', '3'], |c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("1,2,3", ()),
&vec!['1', '2', '3'],
|c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(','))
.parse(c, i)
},
);
parser_test_helper(ParserContext::new_with_str("1", ()), &vec!['1'], |c, i| {
parser_test_helper("1,", &vec!['1'], |c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
parser_test_helper("1,2,3", &vec!['1', '2', '3'], |c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper("1", &vec!['1'], |c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
failed_parser_test_helper("abc", |c, i| {
separate_or_end_by1(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
}
#[test]
fn separate_or_end_by_test() {
parser_test_helper(
ParserContext::new_with_str("1,2,3,", ()),
&vec!['1', '2', '3'],
|c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
},
);
parser_test_helper(ParserContext::new_with_str("1,", ()), &vec!['1'], |c, i| {
parser_test_helper("1,2,3,", &vec!['1', '2', '3'], |c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("1,2,3", ()),
&vec!['1', '2', '3'],
|c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
},
);
parser_test_helper(ParserContext::new_with_str("1", ()), &vec!['1'], |c, i| {
parser_test_helper("1", &vec!['1'], |c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("abc", ()), &vec![], |c, i| {
parser_test_helper("1,2,3", &vec!['1', '2', '3'], |c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper("1,", &vec!['1'], |c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
parser_test_helper("abc", &vec![], |c, i| {
separate_or_end_by(satisfy(|c: &char| c.is_numeric()), char_parser(',')).parse(c, i)
});
}

View File

@ -9,7 +9,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T>;
}
@ -25,7 +25,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
self.parser.parse(context, input)
@ -41,7 +41,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -61,7 +61,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -83,7 +83,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3, T4)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -107,7 +107,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3, T4, T5)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -148,7 +148,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3, T4, T5, T6)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -194,7 +194,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3, T4, T5, T6, T7)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -244,7 +244,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, (T1, T2, T3, T4, T5, T6, T7, T8)> {
let (input, r1) = self.0.parse(context.clone(), input)?;
@ -269,22 +269,15 @@ mod test {
#[test]
fn tuple_test() {
parser_test_helper(
ParserContext::new_with_str("ab", ()),
&('a', 'b'),
|c, i| tuple((char_parser('a'), char_parser('b'))).parse(c, i),
);
parser_test_helper("ab", &('a', 'b'), |c, i| {
tuple((char_parser('a'), char_parser('b'))).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&('a', 'b', 'c'),
|c, i| tuple((char_parser('a'), char_parser('b'), char_parser('c'))).parse(c, i),
);
parser_test_helper("abc", &('a', 'b', 'c'), |c, i| {
tuple((char_parser('a'), char_parser('b'), char_parser('c'))).parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("abcd", ()),
&('a', 'b', 'c', 'd'),
|c, i| {
parser_test_helper("abcd", &('a', 'b', 'c', 'd'), |c, i| {
tuple((
char_parser('a'),
char_parser('b'),
@ -292,7 +285,6 @@ mod test {
char_parser('d'),
))
.parse(c, i)
},
);
});
}
}

View File

@ -63,36 +63,13 @@ impl<'a, TToken: Debug> Display for FailedParserResult<'a, TToken> {
pub type ParserResult<'a, TToken, T> = Result<(&'a [TToken], T), FailedParserResult<'a, TToken>>;
pub struct ParserContext<TToken, TContext>
where
TToken: Debug + Clone,
{
pub struct ParserContext<TContext> {
pub context: TContext,
input_array: Vec<TToken>,
}
impl<TToken, TContext> ParserContext<TToken, TContext>
where
TToken: Debug + Clone,
{
pub fn new(input: &[TToken], context: TContext) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self {
input_array: input.iter().map(|x| x.clone()).collect(),
context,
}))
}
pub fn input_slice(&self) -> &[TToken] {
self.input_array.as_slice()
}
}
impl<TContext> ParserContext<char, TContext> {
pub fn new_with_str(input: &str, context: TContext) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self {
input_array: input.chars().collect(),
context,
}))
impl<TContext> ParserContext<TContext> {
pub fn new(context: TContext) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self { context }))
}
}
@ -103,7 +80,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T>;
@ -242,14 +219,11 @@ where
impl<'a, TToken, T: 'a, TContext, F> Parser<'a, TToken, T, TContext> for F
where
TToken: Debug + Clone + 'a,
F: Fn(
Rc<RefCell<ParserContext<TToken, TContext>>>,
&'a [TToken],
) -> ParserResult<'a, TToken, T>,
F: Fn(Rc<RefCell<ParserContext<TContext>>>, &'a [TToken]) -> ParserResult<'a, TToken, T>,
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
(*self)(context, input)
@ -263,7 +237,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
(**self).parse(context, input)
@ -339,32 +313,27 @@ where
}
#[cfg(test)]
pub fn parser_test_helper<T, P>(
context: Rc<RefCell<ParserContext<char, ()>>>,
excepted_node: &T,
test_parser: P,
) where
pub fn parser_test_helper<T, P>(input: &str, excepted_node: &T, test_parser: P)
where
T: PartialEq + Debug,
P: for<'a> Fn(Rc<RefCell<ParserContext<char, ()>>>, &'a [char]) -> ParserResult<'a, char, T>,
P: for<'a> Fn(Rc<RefCell<ParserContext<()>>>, &'a [char]) -> ParserResult<'a, char, T>,
{
let borrowed_context = context.borrow();
let input = borrowed_context.input_slice();
let (_, actual_result) = test_parser.parse(context.clone(), input).unwrap();
let word: Vec<char> = input.chars().collect();
let (_, actual_result) = test_parser
.parse(ParserContext::new(()), word.as_slice())
.unwrap();
assert_eq!(excepted_node, &actual_result);
}
#[cfg(test)]
pub fn failed_parser_test_helper<T, P>(
context: Rc<RefCell<ParserContext<char, ()>>>,
test_parser: P,
) where
pub fn failed_parser_test_helper<T, P>(input: &str, test_parser: P)
where
T: Debug,
P: for<'a> Fn(Rc<RefCell<ParserContext<char, ()>>>, &'a [char]) -> ParserResult<'a, char, T>,
P: for<'a> Fn(Rc<RefCell<ParserContext<()>>>, &'a [char]) -> ParserResult<'a, char, T>,
{
let borrowed_context = context.borrow();
let input = borrowed_context.input_slice();
let result = test_parser.parse(context.clone(), input);
let word: Vec<char> = input.chars().collect();
let result = test_parser.parse(ParserContext::new(()), word.as_slice());
assert!(result.is_err());
}

View File

@ -19,7 +19,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T2> {
self.parser
@ -44,7 +44,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T2> {
let (input, middle) = self.parser.parse(context.clone(), input)?;
@ -68,7 +68,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T2> {
self.parser
@ -92,7 +92,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TResult> {
let result = self.parser.parse(context, input);
@ -114,7 +114,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, &'a [TToken]> {
let origin_input = input;
@ -147,7 +147,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, usize> {
let origin_input = input;
@ -179,7 +179,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
let original_input = input;
@ -202,7 +202,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
match self.parser.parse(context, input) {
@ -227,7 +227,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TResult> {
match self.parser.parse(context, input) {
@ -251,7 +251,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Option<T>> {
match self.parser.parse(context, input) {
@ -274,7 +274,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
match self.parser.parse(context, input) {
@ -303,7 +303,7 @@ where
{
fn parse(
&self,
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
context: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TResult> {
match self.parser.parse(context, input) {
@ -326,20 +326,16 @@ mod test {
#[test]
fn map_test() {
parser_test_helper(
ParserContext::new_with_str("hello, world!", ()),
&(),
|c, i| take(5).map(|_| ()).parse(c, i),
)
parser_test_helper("hello, world!", &(), |c, i| take(5).map(|_| ()).parse(c, i))
}
#[test]
fn bind_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'b', |c, i| {
parser_test_helper("abc", &'b', |c, i| {
char_parser('a').bind(|_| char_parser('b')).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("abc", ()), &'c', |c, i| {
parser_test_helper("abc", &'c', |c, i| {
char_parser('a')
.bind(|_| char_parser('b'))
.bind(|_| char_parser('c'))
@ -358,7 +354,7 @@ mod test {
#[test]
fn convert_test() {
fn single_numer_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, Number> {
let (input, result) = satisfy(|c: &char| c.is_numeric()).parse(context, input)?;
@ -369,19 +365,15 @@ mod test {
}
}
parser_test_helper(
ParserContext::new_with_str("9", ()),
&"9".to_owned(),
|c, i| single_numer_parser.convert().parse(c, i),
);
parser_test_helper("9", &"9".to_owned(), |c, i| {
single_numer_parser.convert().parse(c, i)
});
parser_test_helper(
ParserContext::new_with_str("1", ()),
&"1".to_owned(),
|c, i| single_numer_parser.convert().parse(c, i),
);
parser_test_helper("1", &"1".to_owned(), |c, i| {
single_numer_parser.convert().parse(c, i)
});
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
failed_parser_test_helper("abc", |c, i| {
single_numer_parser.convert::<String>().parse(c, i)
});
}
@ -389,7 +381,7 @@ mod test {
#[test]
fn next_test() {
fn parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, Number> {
satisfy(|c: &char| c.is_numeric())
@ -403,65 +395,43 @@ mod test {
.parse(context, input)
}
parser_test_helper(
ParserContext::new_with_str("9", ()),
&"9".to_owned(),
|c, i| parser.convert().parse(c, i),
);
parser_test_helper("9", &"9".to_owned(), |c, i| parser.convert().parse(c, i));
parser_test_helper(
ParserContext::new_with_str("1", ()),
&"1".to_owned(),
|c, i| parser.convert().parse(c, i),
);
parser_test_helper("1", &"1".to_owned(), |c, i| parser.convert().parse(c, i));
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
parser.convert::<String>().parse(c, i)
});
failed_parser_test_helper("abc", |c, i| parser.convert::<String>().parse(c, i));
}
#[test]
fn literal_test() {
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&vec!['a'],
|c, i| {
parser_test_helper("abc", &vec!['a'], |c, i| {
char_parser('a')
.literal()
.map(|x| x.iter().map(|x| x.clone()).collect())
.parse(c, i)
},
);
});
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&vec!['a', 'b'],
|c, i| {
parser_test_helper("abc", &vec!['a', 'b'], |c, i| {
char_parser('a')
.bind(|_| char_parser('b'))
.literal()
.map(|x| x.iter().map(|x| x.clone()).collect())
.parse(c, i)
},
);
});
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&vec!['a', 'b', 'c'],
|c, i| {
parser_test_helper("abc", &vec!['a', 'b', 'c'], |c, i| {
char_parser('a')
.bind(|_| char_parser('b'))
.bind(|_| char_parser('c'))
.literal()
.map(|x| x.iter().map(|x| x.clone()).collect())
.parse(c, i)
},
);
});
}
#[test]
fn look_ahead_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
parser_test_helper("abc", &'a', |c, i| {
char_parser('a')
.look_ahead()
.bind(|_| char_parser('a'))
@ -471,48 +441,40 @@ mod test {
#[test]
fn try_parse_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
parser_test_helper("abc", &'a', |c, i| {
char_parser('a').try_parse('a').parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("bc", ()), &'a', |c, i| {
parser_test_helper("bc", &'a', |c, i| {
char_parser('a').try_parse('a').parse(c, i)
});
}
#[test]
fn reverse_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &(), |c, i| {
char_parser('b').reverse(()).parse(c, i)
});
parser_test_helper("abc", &(), |c, i| char_parser('b').reverse(()).parse(c, i));
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
char_parser('a').reverse(()).parse(c, i)
});
failed_parser_test_helper("abc", |c, i| char_parser('a').reverse(()).parse(c, i));
}
#[test]
fn optional_test() {
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&Some('a'),
|c, i| char_parser('a').optional().parse(c, i),
);
parser_test_helper(ParserContext::new_with_str("bc", ()), &None, |c, i| {
parser_test_helper("abc", &Some('a'), |c, i| {
char_parser('a').optional().parse(c, i)
});
parser_test_helper("bc", &None, |c, i| char_parser('a').optional().parse(c, i));
}
#[test]
fn run_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
parser_test_helper("abc", &'a', |c, i| {
char_parser('a').run(|c| assert_eq!(c, &'a')).parse(c, i)
})
}
#[test]
fn and_then_test() {
parser_test_helper(ParserContext::new_with_str("123", ()), &1, |c, i| {
parser_test_helper("123", &1, |c, i| {
char_satisfy(char::is_ascii_digit)
.and_then(|c| {
let word = c.to_string();

View File

@ -15,7 +15,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
Ok((input, self.value.clone()))
@ -32,7 +32,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
Err(FailedParserResult::new_with_str(
@ -53,7 +53,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
Err(FailedParserResult::new(input, self.message.clone()))
@ -71,7 +71,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TToken> {
if input.is_empty() {
@ -97,7 +97,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, T> {
if input.is_empty() {
@ -120,7 +120,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, TToken> {
if input.is_empty() {
@ -141,7 +141,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, Vec<TToken>> {
if input.len() < self.count {
@ -171,7 +171,7 @@ where
{
fn parse(
&self,
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [TToken],
) -> ParserResult<'a, TToken, ()> {
if input.len() < self.count {
@ -198,85 +198,63 @@ mod test {
#[test]
fn succeed_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &(), |c, i| {
succeed(()).parse(c, i)
});
parser_test_helper("abc", &(), |c, i| succeed(()).parse(c, i));
}
#[test]
fn fail_test() {
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
fail::<char, (), ()>().parse(c, i)
});
failed_parser_test_helper("abc", |c, i| fail::<char, (), ()>().parse(c, i));
}
#[test]
fn fail_with_message_test() {
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
failed_parser_test_helper("abc", |c, i| {
fail_with_message::<char, (), ()>("Failed!").parse(c, i)
});
}
#[test]
fn satisfy_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
satisfy(|x| x == &'a').parse(c, i)
});
parser_test_helper("abc", &'a', |c, i| satisfy(|x| x == &'a').parse(c, i));
failed_parser_test_helper(ParserContext::new_with_str("abc", ()), |c, i| {
satisfy(|x| x == &'b').parse(c, i)
});
failed_parser_test_helper("abc", |c, i| satisfy(|x| x == &'b').parse(c, i));
}
#[test]
fn satified_map_test() {
parser_test_helper(ParserContext::new_with_str("123", ()), &1, |c, i| {
parser_test_helper("123", &1, |c, i| {
satified_map(|x: &char| x.to_digit(10)).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("23", ()), &2, |c, i| {
parser_test_helper("23", &2, |c, i| {
satified_map(|x: &char| x.to_digit(10)).parse(c, i)
});
parser_test_helper(ParserContext::new_with_str("3", ()), &3, |c, i| {
parser_test_helper("3", &3, |c, i| {
satified_map(|x: &char| x.to_digit(10)).parse(c, i)
});
}
#[test]
fn any_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
any().parse(c, i)
});
parser_test_helper("abc", &'a', |c, i| any().parse(c, i));
parser_test_helper(ParserContext::new_with_str("cde", ()), &'c', |c, i| {
any().parse(c, i)
});
parser_test_helper("cde", &'c', |c, i| any().parse(c, i));
}
#[test]
fn take_test() {
parser_test_helper(
ParserContext::new_with_str("hello, world!", ()),
&("hello".chars().collect()),
|c, i| take(5).parse(c, i),
);
failed_parser_test_helper(ParserContext::new_with_str("abcd", ()), |c, i| {
parser_test_helper("hello, world!", &("hello".chars().collect()), |c, i| {
take(5).parse(c, i)
});
failed_parser_test_helper("abcd", |c, i| take(5).parse(c, i));
}
#[test]
fn skip_test() {
parser_test_helper(
ParserContext::new_with_str("hello, world!", ()),
&(),
|c, i| skip(5).parse(c, i),
);
parser_test_helper("hello, world!", &(), |c, i| skip(5).parse(c, i));
failed_parser_test_helper(ParserContext::new_with_str("abcd", ()), |c, i| {
skip(5).parse(c, i)
});
failed_parser_test_helper("abcd", |c, i| skip(5).parse(c, i));
}
}

View File

@ -36,31 +36,25 @@ mod test {
#[test]
fn char_parser_test() {
parser_test_helper(
ParserContext::new_with_str("abc", ()),
&'a',
|context, input| char_parser('a').parse(context, input),
);
parser_test_helper("abc", &'a', |context, input| {
char_parser('a').parse(context, input)
});
failed_parser_test_helper(ParserContext::new_with_str("bc", ()), |context, input| {
failed_parser_test_helper("bc", |context, input| {
char_parser('a').parse(context, input)
});
}
#[test]
fn string_parser_test() {
parser_test_helper(
ParserContext::new_with_str("Hello, world!", ()),
&"Hello".to_owned(),
|context, input| {
parser_test_helper("Hello, world!", &"Hello".to_owned(), |context, input| {
string_parser("Hello")
.map(|x| x.iter().collect())
.parse(context, input)
},
);
});
fn test_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, String> {
let (input, first) = string_parser("hello, ").parse(context.clone(), input)?;
@ -72,22 +66,14 @@ mod test {
))
}
parser_test_helper(
ParserContext::new_with_str("hello, world!", ()),
&"hello, world!".to_owned(),
test_parser,
);
parser_test_helper(
ParserContext::new_with_str("hello, world!", ()),
&(),
|context, input| test_parser.map(|_| ()).parse(context, input),
)
parser_test_helper("hello, world!", &"hello, world!".to_owned(), test_parser);
parser_test_helper("hello, world!", &(), |context, input| {
test_parser.map(|_| ()).parse(context, input)
})
}
#[test]
fn char_satsify_test() {
parser_test_helper(ParserContext::new_with_str("abc", ()), &'a', |c, i| {
char_satisfy(char::is_ascii).parse(c, i)
});
parser_test_helper("abc", &'a', |c, i| char_satisfy(char::is_ascii).parse(c, i));
}
}

View File

@ -9,7 +9,7 @@ pub struct StringParser {
impl<'a, TContext> Parser<'a, char, &'a [char], TContext> for StringParser {
fn parse(
&self,
_: Rc<RefCell<ParserContext<char, TContext>>>,
_: Rc<RefCell<ParserContext<TContext>>>,
input: &'a [char],
) -> ParserResult<'a, char, &'a [char]> {
let length = self.str.chars().count();

View File

@ -75,9 +75,9 @@ fn file_lexical_parser_test() -> anyhow::Result<()> {
let (_, nom_tokens) =
nom_lexical_parser(source_file.content.as_str()).or_else(|e| Err(e.to_owned()))?;
let context = ParserContext::new_with_str(source_file.content.as_str(), ());
let borrowed_context = context.borrow();
let (_, zero_tokens) = zero_lexical_parser(context.clone(), borrowed_context.input_slice())
let context = ParserContext::new(());
let word: Vec<char> = source_file.content.chars().collect();
let (_, zero_tokens) = zero_lexical_parser(context.clone(), word.as_slice())
.or_else(|e| Err(anyhow!("{}", e)))?;
assert_eq!(nom_tokens.len(), zero_tokens.len());

View File

@ -5,11 +5,10 @@ use zero_parser::parser::ParserContext;
mod tokenizer;
fn validate_tokens(input: &'static str, tokens: Vec<LexicalTokenType>) {
let context = ParserContext::new_with_str(input, ());
let borrowed_context = context.borrow();
let context = ParserContext::new(());
let word: Vec<char> = input.chars().collect();
let (_, actual_tokens) =
zero_lexical_parser(context.clone(), borrowed_context.input_slice()).unwrap();
let (_, actual_tokens) = zero_lexical_parser(context.clone(), word.as_slice()).unwrap();
dbg!(&tokens, &actual_tokens);
assert_eq!(tokens.len(), actual_tokens.len());

View File

@ -109,7 +109,7 @@ pub fn nom_lexical_parser(mut input: &str) -> IResult<&str, Vec<LexicalToken>> {
}
pub fn zero_lexical_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
mut input: &[char],
) -> ParserResult<char, Vec<NewLexicalToken>> {
let mut array = vec![];

View File

@ -9,7 +9,7 @@ use zero_parser::text::{char_parser, one_of, string_parser};
use zero_parser::{alternate, parser::satisfy};
pub fn keyword_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -38,7 +38,7 @@ pub fn keyword_parser(
}
pub fn delimiter_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
alternate!(
@ -60,7 +60,7 @@ pub fn delimiter_parser(
}
pub fn operator_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
alternate!(
@ -89,7 +89,7 @@ pub fn operator_parser(
}
pub fn identifier_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -105,7 +105,7 @@ pub fn identifier_parser(
}
pub fn decimal_integer_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -126,7 +126,7 @@ pub fn decimal_integer_parser(
}
pub fn octal_integer_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -147,7 +147,7 @@ pub fn octal_integer_parser(
}
pub fn hexadecimal_integer_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -168,7 +168,7 @@ pub fn hexadecimal_integer_parser(
}
pub fn integer_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
alternate!(
@ -180,7 +180,7 @@ pub fn integer_parser(
}
pub fn float_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
tuple((
@ -202,7 +202,7 @@ pub fn float_parser(
}
pub fn literal_string_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
quote(char_parser('"'), any(), char_parser('"'))
@ -218,7 +218,7 @@ pub fn literal_string_parser(
}
pub fn comments_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, ()> {
alternate!(
@ -239,7 +239,7 @@ pub fn comments_parser(
}
pub fn junk_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, ()> {
alternate!(
@ -250,7 +250,7 @@ pub fn junk_parser(
}
pub fn combine_parser(
context: Rc<RefCell<ParserContext<char, ()>>>,
context: Rc<RefCell<ParserContext<()>>>,
input: &[char],
) -> ParserResult<char, NewLexicalToken> {
alternate!(

View File

@ -1,3 +1,5 @@
extern crate core;
use crate::tokenizer::zero_parsers::{
combine_parser, comments_parser, decimal_integer_parser, delimiter_parser, float_parser,
hexadecimal_integer_parser, identifier_parser, integer_parser, keyword_parser,
@ -13,16 +15,12 @@ mod tokenizer;
fn assert_lexical_parser(
except: LexicalToken,
parser: fn(
Rc<RefCell<ParserContext<char, ()>>>,
&[char],
) -> ParserResult<char, NewLexicalToken>,
parser: fn(Rc<RefCell<ParserContext<()>>>, &[char]) -> ParserResult<char, NewLexicalToken>,
input: &str,
) {
let context = ParserContext::new_with_str(input, ());
let borrowed_context = context.borrow();
let input = borrowed_context.input_slice();
let (_, token) = parser(context.clone(), input).unwrap();
let context = ParserContext::new(());
let word: Vec<char> = input.chars().collect();
let (_, token) = parser(context.clone(), word.as_slice()).unwrap();
assert_eq!(except, token);
}
@ -30,11 +28,11 @@ fn assert_lexical_parser(
fn assert_parser<T, F>(except: T, parser: F, input: &str)
where
T: PartialEq + Debug,
F: Fn(Rc<RefCell<ParserContext<char, ()>>>, &[char]) -> ParserResult<char, T>,
F: Fn(Rc<RefCell<ParserContext<()>>>, &[char]) -> ParserResult<char, T>,
{
let context = ParserContext::new_with_str(input, ());
let borrowed_context = context.borrow();
let (_, token) = parser(context.clone(), borrowed_context.input_slice()).unwrap();
let context = ParserContext::new(());
let word: Vec<char> = input.chars().collect();
let (_, token) = parser(context.clone(), word.as_slice()).unwrap();
assert_eq!(except, token);
}