summaryrefslogtreecommitdiff
path: root/repcore/src/grammar.rs
blob: ee9f0337f3290403b40196320fc3803b9b45ba05 (plain)
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! This file implements the extected behaviours of grammars.

// NOTE: We shall first start with a parser that works at the level of
// characters.  The purpose is to first experiment with the workings
// and the performance of the algorithms, before optimising by using
// regular expressions to classify inputs into tokens.  In other
// words, the current focus is not on the optimisations, whereas
// scanners are for optimisations only, so to speak.

/// The type of a terminal.
///
/// For the time being this is a wrapper around a string, but in the
/// future it may hold more information of scanners.
pub struct Terminal {
    // If we want to use scanners, per chance add them as a new field
    // here.
    name: String,
}

impl Terminal {
    /// Create a terminal with the given name.
    #[inline]
    pub fn new(name: String) -> Self {
        Self { name }
    }

    /// Return the name of the terminal.
    #[inline]
    pub fn name(&self) -> &str {
        &self.name
    }
}

/// The type of a non-terminal.
///
/// This is just a wrapper around a string.
pub struct Nonterminal(String);

impl Nonterminal {
    /// Return the name of the nonterminal.
    ///
    /// Just to improve readability.
    #[inline]
    pub fn name(&self) -> &str {
        &self.0
    }
}

/// The type of a terminal or a non-terminal.
///
/// Only an index is stored here.  Actual data are stored in two other
/// arrays.
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy, Ord, PartialOrd)]
pub enum TNT {
    /// Terminal variant
    Ter(usize),
    /// Nonterminal variant
    Non(usize),
}