moore_vhdl_syntax/lexer/
categorizer.rs

1// Copyright (c) 2016-2021 Fabian Schuiki
2
3use moore_common::errors::DiagBuilder2;
4use moore_common::grind::Grinder;
5
6/// A grinder that categorizes characters into different groups as per the VHDL
7/// language standard.
8pub struct Categorizer<T> {
9    inner: T,
10}
11
12impl<T> Categorizer<T>
13where
14    T: Grinder<Item = Option<(usize, char, u8)>, Error = DiagBuilder2>,
15{
16    /// Create a new categorizer.
17    pub fn new(inner: T) -> Categorizer<T> {
18        Categorizer { inner: inner }
19    }
20}
21
22impl<T> Grinder for Categorizer<T>
23where
24    T: Grinder<Item = Option<(usize, char, u8)>, Error = DiagBuilder2>,
25{
26    type Item = Option<(usize, char, u8, Category)>;
27    type Error = DiagBuilder2;
28
29    fn emit(&mut self, err: Self::Error) {
30        self.inner.emit(err);
31    }
32
33    fn next(&mut self) -> Self::Item {
34        let (offset, c, sz) = match self.inner.next() {
35            Some(v) => v,
36            None => return None,
37        };
38        let cat = match c {
39            '"' | '#' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';'
40            | '<' | '=' | '>' | '?' | '@' | '[' | ']' | '_' | '`' | '|' => Category::Special,
41            c if c.is_alphabetic() => Category::Letter,
42            c if c.is_digit(10) => Category::Digit,
43            c if c.is_whitespace() => Category::Space,
44            _ => Category::Other,
45        };
46        Some((offset, c, sz, cat))
47    }
48}
49
50/// A character category. Special means the special characters as defined by the
51/// VHDL standard to be meaningful syntactically.
52#[derive(Copy, Clone, PartialEq, Eq, Debug)]
53pub enum Category {
54    Letter,
55    Digit,
56    Special,
57    Space,
58    Other,
59}