0

I'm trying to create a parser combinator. I defined a trait and an Or parser:

trait Parser<'a> {
    fn run(&self, input: &'a str) -> (Option<&'a str>, &'a str);
}

trait Parser<'a> {
    fn run(&self, input: &'a str) -> (Option<&'a str>, &'a str);
}

pub struct Or<'a> {
    p1: &'a Parser<'a>,
    p2: &'a Parser<'a>,
}

impl<'a> Parser<'a> for Or<'a> {
    fn run(&self, input: &'a str) -> (Option<&'a str>, &'a str) {
        let (result, remainder) = self.p1.run(input);
        match result {
            Some(r) => (result, remainder),
            None => self.p2.run(input),
        }
    }
}

impl<'a> Or<'a> {
    fn new(p1: &'a Parser<'a>, p2: &'a Parser<'a>) -> Or<'a> {
        Or { p1, p2 }
    }
}

Now I want to define a Choice parser which should iterate through a vector of parsers and return a result if any of them are successful:

pub struct Choice<'a> {
    parsers: &'a Vec<&'a Parser<'a>>,
}

impl<'a> Choice<'a> {
    fn new(parsers: &'a Vec<&'a Parser<'a>>) -> Choice<'a> {
        Choice { parsers }
    }
}

impl<'a> Parser<'a> for Choice<'a> {
    fn run(&self, input: &'a str) -> (Option<&'a str>, &'a str) {
        let parser: &Parser = self.parsers
            .iter()
            .fold(&AlwaysFails::new(), |sum, p2| &Or::new(sum, p2));
        parser.run(input)
    }
}

AlwaysFails is a parser which always returns a tuple of (None, input):

pub struct AlwaysFails;

impl AlwaysFails {
    fn new() -> Self {
        AlwaysFails
    }
}

impl<'a> Parser<'a> for AlwaysFails {
    fn run(&self, input: &'a str) -> (Option<&'a str>, &'a str) {
        (None, input)
    }
}

I am getting the error

error[E0277]: the trait bound `&Parser<'a>: Parser<'_>` is not satisfied
  --> src/main.rs:40:64
   |
40 |             .fold(&AlwaysFails::new(), |sum, p2| &Or::new(sum, p2));
   |                                                                ^^ the trait `Parser<'_>` is not implemented for `&Parser<'a>`
   |
   = note: required for the cast to the object type `Parser<'_>`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Anthony
  • 11
  • 1
  • 4
  • [The duplicate applied to your question](https://play.integer32.com/?gist=fc701f49172707948c5c8d118fc2f1c9&version=stable). – Shepmaster Dec 10 '17 at 22:13
  • The code you just linked doesn't compile. It's clearer why I guess. – Anthony Dec 10 '17 at 22:53
  • That's correct, you still have other issues that prevent your code from compiling, but the duplicate solves the problem you asked about. Notably, see [Is there any way to return a reference to a variable created in a function?](https://stackoverflow.com/q/32682876/155423) – Shepmaster Dec 10 '17 at 22:56

0 Answers0