topdown/
re.rs

1use super::{CharSeq, ParserResult, Parser, Succ};
2use regex::Regex;
3
4pub struct Re {
5    pattern: Regex
6}
7
8#[allow(unused_variables)]
9pub fn re(p: &str) -> Re {
10    match Regex::new(p) {
11        Ok(r) => return Re{pattern: r},
12        Err(e) => panic!("{}", p)
13    }
14}
15
16impl Parser<String> for Re {
17    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<String> {
18        match self.pattern.find(cs.view()) {
19            Some((a, b)) => {
20                if a != 0 {
21                    return cs.fail(self.pattern.as_str());
22                }
23                let r = cs.view()[..b].to_string();
24                cs.pos += b;
25                return Succ(r);
26            },
27            None => return cs.fail(self.pattern.as_str())
28        }
29    }
30}
31
32#[cfg(test)]
33#[allow(unused_variables)]
34#[allow(unused_imports)]
35mod tests {
36    use super::re;
37    use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
38
39    #[test]
40    fn test_re1() {
41        let mut cs = CharSeq::new("int x = 10;", "");
42        let ident = re("[a-zA-Z_][a-zA-Z0-9_]*");
43        let num = re("[1-9][0-9]*");
44        let r = cs.accept(&ident).and_then(|t|
45                  cs.accept(&" ").and_then(|a|
46                  cs.accept(&ident).and_then(|v|
47                  cs.accept(&" = ").and_then(|a|
48                  cs.accept(&num).map(|n| {
49                      return vec!(t.clone(), v.clone(), n.clone());
50                }))))
51            );
52        match r {
53            Succ(c) => {
54                assert_eq!(c[0].as_slice(), "int");
55                assert_eq!(c[1].as_slice(), "x");
56                assert_eq!(c[2].as_slice(), "10");
57            },
58            _ => assert!(false, "bug")
59        }
60    }
61
62
63}