differential_engine/lang/
generic.rs1use std::sync::LazyLock;
12
13use regex::bytes::Regex;
14
15static STR_RE: LazyLock<Regex> =
17 LazyLock::new(|| Regex::new(r#"(?-u)"[^"]*"|'[^']*'|`[^`]*`"#).unwrap());
18static NUM_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?-u)\b\d+\b").unwrap());
19static IDENT_RE: LazyLock<Regex> =
20 LazyLock::new(|| Regex::new(r"(?-u)[A-Za-z_][A-Za-z0-9_\-]{3,}").unwrap());
21static WS_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?-u)\s+").unwrap());
22
23pub fn normalize_line(line: &[u8]) -> Vec<u8> {
26 let s = STR_RE.replace_all(line, b"\"S\"".as_slice());
27 let s = NUM_RE.replace_all(&s, b"N".as_slice());
28 let s = IDENT_RE.replace_all(&s, b"I".as_slice());
29 let s = WS_RE.replace_all(&s, b" ".as_slice());
30 trim_ascii(&s).to_vec()
31}
32
33fn trim_ascii(s: &[u8]) -> &[u8] {
34 let start = s
35 .iter()
36 .position(|b| !b.is_ascii_whitespace())
37 .unwrap_or(s.len());
38 let end = s
39 .iter()
40 .rposition(|b| !b.is_ascii_whitespace())
41 .map_or(start, |e| e + 1);
42 &s[start..end]
43}