Compare commits
2 Commits
814ab29cb6
...
3e6c2c9bde
Author | SHA1 | Date | |
---|---|---|---|
3e6c2c9bde | |||
f69406bc02 |
|
@ -9,7 +9,9 @@ use crate::combinators::left_right_parsers::{LeftParser, RightParser};
|
||||||
use crate::combinators::many_parsers::{
|
use crate::combinators::many_parsers::{
|
||||||
Many1Parser, Many1TillParser, ManyParser, ManyTillParser, Skip1Parser, SkipParser,
|
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::combinators::tuple_parser::{ParserTuple, TupleParser};
|
||||||
use crate::parser::{any, Parser};
|
use crate::parser::{any, Parser};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -190,7 +192,13 @@ where
|
||||||
PLeft: Parser<'a, TToken, TLeft, TContext>,
|
PLeft: Parser<'a, TToken, TLeft, TContext>,
|
||||||
PRight: Parser<'a, TToken, TRight, 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>(
|
pub fn separate_by1<'a, TToken, T: 'a, TSeparator: 'a, TContext, P, PSeparator>(
|
||||||
|
|
|
@ -270,6 +270,18 @@ mod test {
|
||||||
char_parser('a').many_till(char_parser('b')).parse(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| {
|
||||||
|
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(ParserContext::new_with_str("aaacb", ()), |c, i| {
|
||||||
char_parser('a').many_till(char_parser('b')).parse(c, i)
|
char_parser('a').many_till(char_parser('b')).parse(c, i)
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,60 @@
|
||||||
use crate::parser::{Parser, ParserContext, ParserResult};
|
use crate::parser::{FailedParserResult, Parser, ParserContext, ParserResult};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub struct QuoteParser<P, PLeft, PRight, TLeft, TRight> {
|
||||||
|
pub(crate) parser: P,
|
||||||
|
pub(crate) left: PLeft,
|
||||||
|
pub(crate) right: PRight,
|
||||||
|
pub(crate) left_data: PhantomData<TLeft>,
|
||||||
|
pub(crate) right_data: PhantomData<TRight>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, TToken, T: 'a, TLeft: 'a, TRight: 'a, TContext, P, PLeft, PRight>
|
||||||
|
Parser<'a, TToken, Vec<T>, TContext> for QuoteParser<P, PLeft, PRight, TLeft, TRight>
|
||||||
|
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<RefCell<ParserContext<TToken, TContext>>>,
|
||||||
|
input: &'a [TToken],
|
||||||
|
) -> ParserResult<'a, TToken, Vec<T>> {
|
||||||
|
let (mut input, _) = match self.left.parse(context.clone(), input) {
|
||||||
|
Err(r) => Err(FailedParserResult::new(
|
||||||
|
r.input(),
|
||||||
|
format!("Failed to parse left quote: {}", r.message()),
|
||||||
|
)),
|
||||||
|
r => r,
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Ok((i, _)) = self.right.parse(context.clone(), input) {
|
||||||
|
input = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok((i, r)) = self.parser.parse(context.clone(), input) {
|
||||||
|
input = i;
|
||||||
|
result.push(r);
|
||||||
|
} else {
|
||||||
|
return Err(FailedParserResult::new_with_str(
|
||||||
|
input,
|
||||||
|
"Quote without the right quote.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok((input, result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SeparateBy1Parser<P, PSeparator, TSeparator> {
|
pub struct SeparateBy1Parser<P, PSeparator, TSeparator> {
|
||||||
pub(crate) parser: P,
|
pub(crate) parser: P,
|
||||||
pub(crate) separator: PSeparator,
|
pub(crate) separator: PSeparator,
|
||||||
|
@ -82,6 +133,7 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::combinators::{
|
use crate::combinators::{
|
||||||
end_by, end_by1, quote, separate_by, separate_by1, separate_or_end_by, separate_or_end_by1,
|
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::parser::{failed_parser_test_helper, parser_test_helper, satisfy};
|
||||||
use crate::text::char_parser;
|
use crate::text::char_parser;
|
||||||
|
@ -106,7 +158,17 @@ mod test {
|
||||||
parser,
|
parser,
|
||||||
);
|
);
|
||||||
parser_test_helper(ParserContext::new_with_str("''", ()), &vec![], 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]
|
#[test]
|
||||||
|
|
|
@ -211,7 +211,7 @@ pub fn literal_string_parser(
|
||||||
let length = x.len();
|
let length = x.len();
|
||||||
NewLexicalToken {
|
NewLexicalToken {
|
||||||
token_type: LexicalTokenType::LiteralString,
|
token_type: LexicalTokenType::LiteralString,
|
||||||
literal_value: &x[1..length],
|
literal_value: &x[1..length - 1],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.parse(context, input)
|
.parse(context, input)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user