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}