choice work

This commit is contained in:
Greg Shuflin 2022-10-20 23:47:06 -07:00
parent bdaf712a25
commit 6633d10af0
1 changed files with 49 additions and 98 deletions

View File

@ -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"));
}
}