topdown/
try.rs

1use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
2
3pub struct Try<'a, T:'a> {
4    parser: &'a (Parser<T> + 'a)
5}
6
7pub fn try<'a, T>(p: &'a(Parser<T>+'a)) -> Try<'a, T> {
8    return Try{parser:p};
9}
10
11impl<'a, T> Parser<T> for Try<'a, T> {
12    #[allow(unused_variables)]
13    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<T> {
14        let p = cs.pos;
15        match cs.accept(self.parser) {
16            Succ(c) => return Succ(c),
17            Fail(m, l) => {
18                cs.pos = p;
19                return Fail(m, l)
20            },
21            Error(m, l) => return Error(m, l)
22        }
23    }
24}
25
26#[cfg(test)]
27#[allow(unused_variables)]
28#[allow(unused_imports)]
29mod tests {
30    use super::try;
31    use super::super::{CharSeq, wrap, ParserResult, Parser, Succ, Fail, Error};
32
33    fn p(cs : &mut CharSeq) -> ParserResult<String> {
34        cs.accept(&"abc");
35        cs.accept(&"def")
36    }
37
38    #[test]
39    fn test_try() {
40        let mut cs = CharSeq::new("abcxyz", "");
41        let f = wrap(p);
42        let t = try(&f);
43        cs.accept(&t);
44        assert_eq!(0, cs.pos);
45        cs.accept(&f);
46        assert_eq!(3, cs.pos);
47    }
48}
49