summaryrefslogtreecommitdiff
path: root/chain/src/lib.rs
blob: 4e21e1d3bf46f8cfb93702681d2e6a547834e673 (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
#![warn(missing_docs)]
//! This package implements the core algorithm of the entire
//! workspace: parsing with derivatives by means of chain rule and
//! regular nulling languages.
//!
//! Since I shall not name my crate "core" to avoid collisions with
//! the Rust's own core, I decided to name this crate after what I
//! think is the essence of this algorithm, the chain-rule for
//! derivatives of languages.

pub mod atom;

// TODO: Define errors.

/// The expected behaviours of a language which can take derivatives
/// by chain rule.
pub trait Chain: Default {
    /// The implementations should choose a type to represent errors.
    type Error: std::error::Error;

    /// Represents the language that is present after we parse the
    /// empty string, that is the initial configuration of the
    /// language.  This may or may not be different from what
    /// `Default::default` gives.
    fn unit() -> Self;

    /// Take the derivative by a terminal symbol.
    ///
    /// This takes care of the union and the prepending operations.
    ///
    /// # A little remark about the design
    ///
    /// I have thought to separate different operations (like the
    /// union, the prepending, and single derivatives) and then define
    /// a function to put everything together.  But I think that
    /// design is not convenient to use.  Also, I really do not need
    /// those operations other than to provide this derivative
    /// operation, so why define them?  And putting all things
    /// together may reduce the number of bugs caused by wrong uses of
    /// those component functions, and can reduce the amount of
    /// documentation strings a library user needs to read, in order
    /// to make use of this trait.  So I ended up with this design.
    fn chain(&mut self, t: usize);

    /// Return true if and only if the language contains the empty
    /// string.
    fn epsilon(&self) -> bool;
}

pub mod default;