choice work
This commit is contained in:
parent
bdaf712a25
commit
6633d10af0
147
src/choice.rs
147
src/choice.rs
@ -31,21 +31,8 @@ where
|
||||
I: Clone,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
let parser1 = &self.0;
|
||||
let parser2 = &self.1;
|
||||
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
|
||||
for parser in [parser1 as &dyn Parser<I, O, E>, parser2].iter() {
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err.unwrap())
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,22 +44,8 @@ where
|
||||
I: Clone,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
let parser1 = &self.0;
|
||||
let parser2 = &self.1;
|
||||
let parser3 = &self.2;
|
||||
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
|
||||
for parser in [parser1 as &dyn Parser<I, O, E>, parser2, parser3].iter() {
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err.unwrap())
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,23 +58,8 @@ where
|
||||
I: Clone,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
let parser1 = &self.0;
|
||||
let parser2 = &self.1;
|
||||
let parser3 = &self.2;
|
||||
let parser4 = &self.3;
|
||||
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
|
||||
for parser in [parser1 as &dyn Parser<I, O, E>, parser2, parser3, parser4].iter() {
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err.unwrap())
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,32 +73,14 @@ where
|
||||
I: Clone,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
let parser1 = &self.0;
|
||||
let parser2 = &self.1;
|
||||
let parser3 = &self.2;
|
||||
let parser4 = &self.3;
|
||||
let parser5 = &self.4;
|
||||
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
|
||||
for parser in [
|
||||
parser1 as &dyn Parser<I, O, E>,
|
||||
parser2,
|
||||
parser3,
|
||||
parser4,
|
||||
parser5,
|
||||
]
|
||||
.iter()
|
||||
{
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err.unwrap())
|
||||
let parsers = vec![
|
||||
&self.0 as &dyn Parser<I, O, E>,
|
||||
&self.1,
|
||||
&self.2,
|
||||
&self.3,
|
||||
&self.4,
|
||||
];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,35 +95,34 @@ where
|
||||
I: Clone,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
let parser1 = &self.0;
|
||||
let parser2 = &self.1;
|
||||
let parser3 = &self.2;
|
||||
let parser4 = &self.3;
|
||||
let parser5 = &self.4;
|
||||
let parser6 = &self.5;
|
||||
let parsers = vec![
|
||||
&self.0 as &dyn Parser<I, O, E>,
|
||||
&self.1,
|
||||
&self.2,
|
||||
&self.3,
|
||||
&self.4,
|
||||
&self.5,
|
||||
];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
fn choice_loop<I, O, E>(input: I, parsers: Vec<&dyn Parser<I, O, E>>) -> ParseResult<I, O, E>
|
||||
where
|
||||
I: Clone,
|
||||
{
|
||||
//TODO need a more principled way to return an error when no choices work
|
||||
let mut err = None;
|
||||
|
||||
for parser in [
|
||||
parser1 as &dyn Parser<I, O, E>,
|
||||
parser2,
|
||||
parser3,
|
||||
parser4,
|
||||
parser5,
|
||||
parser6,
|
||||
]
|
||||
.iter()
|
||||
{
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
for parser in parsers.iter() {
|
||||
match parser.parse(input.clone()) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
err = Some(e);
|
||||
}
|
||||
}
|
||||
Err(err.unwrap())
|
||||
}
|
||||
Err(err.unwrap())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -200,4 +139,16 @@ mod tests {
|
||||
);
|
||||
assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_several_choices() {
|
||||
let p = choice((
|
||||
literal("a").to(1),
|
||||
literal("q").to(10),
|
||||
repeated(literal("chutney")).to(200),
|
||||
literal("banana").to(10000),
|
||||
));
|
||||
|
||||
assert_eq!(p.parse("q drugs").unwrap(), (10, " drugs"));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user