topdown/
many1.rs

1use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
2
3pub struct Many1<'a, T:'a> {
4    parser: &'a (Parser<T>+'a)
5}
6
7pub fn many1<'a, T>(p: &'a (Parser<T> + 'a)) -> Many1<'a, T> {
8    return Many1{parser: p};
9}
10
11impl<'a, T> Parser<Vec<T>> for Many1<'a, T> {
12    #[allow(unused_variables)]
13    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<Vec<T>> {
14        let mut succ = true;
15        let mut r = Vec::new();
16        while succ {
17            match self.parser.parse(cs) {
18                Succ(c) => r.push(c),
19                Fail(m, l) => succ = false,
20                Error(m, l) => return Error(m, l)
21            }
22        }
23        if r.len() == 0 {
24            return cs.fail("nothing");
25        }
26        return Succ(r);
27    }
28
29}
30
31#[cfg(test)]
32#[allow(unused_variables)]
33#[allow(unused_imports)]
34mod tests {
35    use super::many1;
36    use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
37
38    #[test]
39    fn test_many1_1() {
40        let mut cs = CharSeq::new("aaabbbccc", "<mem>");
41        assert!(cs.pos == 0);
42        let s = "a";
43        let m = many1(&s);
44        match cs.accept(&m) {
45            Succ(a) => assert!(a == vec!["a", "a", "a"]),
46            _ => assert!(false, "bug")
47        }
48        assert!(cs.pos == 3);
49        assert!(cs.view() == "bbbccc");
50    }
51
52    #[test]
53    fn test_many1_2() {
54        let mut cs = CharSeq::new("aaabbbccc", "<mem>");
55        assert!(cs.pos == 0);
56        let s = "x";
57        let m = many1(&s);
58        match cs.accept(&m) {
59            Fail(m, l) => (),
60            Succ(a) => {
61                let mut x = String::new();
62                for i in a.iter() {
63                    x.push_str(i.as_slice());
64                    x.push(',');
65                }
66                assert!(false, format!("bug: succeded: {}", x))
67            },
68            Error(m, l) => assert!(false, "bug")
69        }
70        assert!(cs.pos == 0);
71        assert!(cs.view() == "aaabbbccc");
72    }
73}
74