choice work
This commit is contained in:
parent
bdaf712a25
commit
6633d10af0
133
src/choice.rs
133
src/choice.rs
@ -31,21 +31,8 @@ where
|
|||||||
I: Clone,
|
I: Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parser1 = &self.0;
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||||
let parser2 = &self.1;
|
choice_loop(input, parsers)
|
||||||
|
|
||||||
//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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,22 +44,8 @@ where
|
|||||||
I: Clone,
|
I: Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parser1 = &self.0;
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||||
let parser2 = &self.1;
|
choice_loop(input, parsers)
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,23 +58,8 @@ where
|
|||||||
I: Clone,
|
I: Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parser1 = &self.0;
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||||
let parser2 = &self.1;
|
choice_loop(input, parsers)
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,32 +73,14 @@ where
|
|||||||
I: Clone,
|
I: Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parser1 = &self.0;
|
let parsers = vec![
|
||||||
let parser2 = &self.1;
|
&self.0 as &dyn Parser<I, O, E>,
|
||||||
let parser3 = &self.2;
|
&self.1,
|
||||||
let parser4 = &self.3;
|
&self.2,
|
||||||
let parser5 = &self.4;
|
&self.3,
|
||||||
|
&self.4,
|
||||||
//TODO need a more principled way to return an error when no choices work
|
];
|
||||||
let mut err = None;
|
choice_loop(input, parsers)
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,26 +95,26 @@ where
|
|||||||
I: Clone,
|
I: Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parser1 = &self.0;
|
let parsers = vec![
|
||||||
let parser2 = &self.1;
|
&self.0 as &dyn Parser<I, O, E>,
|
||||||
let parser3 = &self.2;
|
&self.1,
|
||||||
let parser4 = &self.3;
|
&self.2,
|
||||||
let parser5 = &self.4;
|
&self.3,
|
||||||
let parser6 = &self.5;
|
&self.4,
|
||||||
|
&self.5,
|
||||||
|
];
|
||||||
|
choice_loop(input, parsers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
//TODO need a more principled way to return an error when no choices work
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
|
|
||||||
for parser in [
|
for parser in parsers.iter() {
|
||||||
parser1 as &dyn Parser<I, O, E>,
|
|
||||||
parser2,
|
|
||||||
parser3,
|
|
||||||
parser4,
|
|
||||||
parser5,
|
|
||||||
parser6,
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
{
|
|
||||||
match parser.parse(input.clone()) {
|
match parser.parse(input.clone()) {
|
||||||
Ok(result) => return Ok(result),
|
Ok(result) => return Ok(result),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -183,7 +123,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err.unwrap())
|
Err(err.unwrap())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -200,4 +139,16 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine")));
|
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