topdown/
choice.rs

1use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
2
3pub struct Choice<'a, T: 'a> {
4    parsers: &'a [&'a(Parser<T>+'a)]
5}
6
7pub fn choice<'a, T>(p: &'a [&'a (Parser<T> + 'a)]) -> Choice<'a, T> {
8    return Choice{parsers: p};
9}
10
11impl<'a, T> Parser<T> for Choice<'a, T> {
12    #[allow(unused_variables)]
13    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<T> {
14        let pos = cs.pos;
15        let mut vec = Vec::new();
16        for p in self.parsers.iter() {
17            match p.parse(cs) {
18                Succ(r) => return Succ(r),
19                Fail(m, l) => {
20                    vec.push((m, l));
21                    cs.pos = pos;
22                },
23                Error(m, l) => return Error(m, l)
24            }
25        }
26        vec.sort_by(|a, b| a.1.cmp(&b.1));
27        match vec.pop() {
28            Some(p) => {
29                cs.pos = pos;
30                let (m, l) = p;
31                return Fail(m, l);
32            },
33            None => ()
34        }
35        let r = cs.fail("");
36        cs.pos = pos;
37        return r;
38    }
39}
40
41#[cfg(test)]
42#[allow(unused_variables)]
43#[allow(unused_imports)]
44mod tests {
45    use super::choice;
46    use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
47
48    #[test]
49    fn test_choice1() {
50        let mut cs = CharSeq::new("abcdefghi", "<mem>");
51        let l: &[&Parser<String>] = &[&("abc"), &("def")];
52        let choice = choice(l);
53        match cs.accept(&choice) {
54            Succ(c) => assert!(c.as_slice() == "abc"),
55            Fail(a, b) => assert!(false, "failed"),
56            Error(a, b) => assert!(false, "error")
57        }
58    }
59
60    #[test]
61    fn test_choice2() {
62        let mut cs = CharSeq::new("abcdefghi", "<mem>");
63        let l: &[&Parser<String>] = &[&("ghi"), &("def")];
64        let choice = choice(l);
65        match cs.accept(&choice) {
66            Succ(c) => assert!(false, c),
67            Fail(a, b) => (),
68            Error(a, b) => assert!(false, "error")
69        }
70    }
71
72    #[test]
73    fn test_choice3() {
74        let mut cs = CharSeq::new("abcdefghi", "<mem>");
75        let a = S{fst: "abc", snd:"ghi"};
76        let b = S{fst: "abc", snd:"jkl"};
77        let l: &[&Parser<String>] = &[&a, &b];
78        let choice = choice(l);
79        match cs.accept(&choice) {
80            Succ(c) => assert!(false, c),
81            Fail(a, b) => {
82                assert_eq!(0, cs.pos);
83                assert_eq!(4, b.col);
84            },
85            Error(a, b) => assert!(false, "error")
86        }
87    }
88
89    struct S<'a> {
90        fst: &'a str,
91        snd: &'a str
92    }
93    impl<'a> Parser<String> for S<'a> {
94        fn _parse(&self, cs: &mut CharSeq) -> ParserResult<String> {
95            cs.accept(&self.fst).and_then(|x| cs.accept(&self.snd))
96        }
97    }
98}