topdown/
many_until.rs

1use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
2
3
4pub struct ManyUntil<'a, S:'a, T:'a> {
5    parser: &'a (Parser<S>+'a),
6    stop: &'a (Parser<T>+'a)
7}
8
9pub fn many_until<'a, S, T>(p: &'a (Parser<S> + 'a), s: &'a (Parser<T> + 'a)) -> ManyUntil<'a, S, T> {
10    return ManyUntil{parser: p, stop: s};
11}
12
13impl<'a, S, T> Parser<Vec<S>> for ManyUntil<'a, S, T> {
14    #[allow(unused_variables)]
15    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<Vec<S>> {
16        let mut r = Vec::new();
17        let mut succ = true;
18        while succ {
19            match self.parser.parse(cs) {
20                Succ(c) => r.push(c),
21                Fail(m, l) => {
22                    match self.stop.lookahead(cs) {
23                        true => succ = false,
24                        false => return Fail(m, l)
25                    }
26                },
27                Error(m, l) => return Error(m, l)
28            }
29        }
30        return Succ(r);
31    }
32}
33
34
35#[cfg(test)]
36#[allow(unused_variables)]
37#[allow(unused_imports)]
38mod tests {
39    use super::many_until;
40    use super::super::{CharSeq, ParserResult, EOF, Parser, Succ, Fail, Error};
41
42    #[test]
43    fn test_many_until1() {
44        let mut cs = CharSeq::new("aaa", "<mem>");
45        assert!(cs.pos == 0);
46        let s = "a";
47        let eof = EOF;
48        let m = many_until(&s, &eof);
49        match cs.accept(&m) {
50            Succ(v) => assert_eq!(v, vec!["a", "a", "a"]),
51            _ => assert!(false, "bug")
52        }
53        assert!(cs.pos == 3);
54    }
55
56    #[test]
57    fn test_many_until2() {
58        let mut cs = CharSeq::new("aaabbbccc", "<mem>");
59        assert!(cs.pos == 0);
60        let s = "a";
61        let eof = EOF;
62        let m = many_until(&s, &eof);
63        match cs.accept(&m) {
64            Fail(m, l) => assert_eq!(cs.pos, 3),
65            _ => assert!(false, "bug")
66        }
67        assert!(cs.pos == 3);
68        assert!(cs.view() == "bbbccc");
69    }
70
71    #[test]
72    fn test_many_until3() {
73        let mut cs = CharSeq::new("aaabbbccc", "<mem>");
74        assert!(cs.pos == 0);
75        let s = "x";
76        let eof = EOF;
77        let m = many_until(&s, &eof);
78        match cs.accept(&m) {
79            Fail(m, l) => {
80                assert_eq!(l.col,1);
81                assert_eq!(l.row,1);
82            },
83            Succ(a) => assert!(false, "bug"),
84            Error(m, l) => assert!(false, "bug: {} {}", m, l)
85        }
86        assert!(cs.pos == 0);
87        assert!(cs.view() == "aaabbbccc");
88    }
89}
90