1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
extern crate regex;

use super::*;
use regex::Regex;

pub struct Flexer<T> {
    definitions: Vec<TokenDefinition<T>>,
}

impl<T> Flexer<T> {
    pub fn new(definitions: Vec<TokenDefinition<T>>) -> Self {
        Flexer {
            definitions,
        }
    }

    pub fn tokens<'a, 'b>(&'b self, source: &'a str) -> Tokens<'a, 'b, T> {
        let regex = self.definitions_regex();
        Tokens::new(&self.definitions, regex.captures_iter(source).collect())
    }

    pub fn definitions_regex(&self) -> Regex {
        let mut regex = String::new();
        for (index, definition) in self.definitions.iter().enumerate() {
            regex += &format!("(?P<{}>{})", definition.name(), definition.regex().as_str());
            if index < self.definitions.len() - 1 {
                regex += "|";
            }
        }
        Regex::new(&regex).unwrap()
    }
}