#![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;