nifty/
lib.rs

1//! |     
2//! # Description
3//!
4//! The goal of this crate is not to be an efficient parsing library. Use a regex for that.  
5//! Rather, this crate aims to preserve the integrity of stepping through a DFA state diagram.   
6//!
7//! It allows you to build a DFA with states of a generic type `S` that recognizes a language
8//! whose symbols are of a generic type `T`. You can traverse each transition symbol one by one, or you can
9//! consume an iterator of symbols, which the DFA will either `Accept` or `Reject`.
10//!
11//! DFAs are created using a `DFABuilder`, or by using the `make_dfa!` macro.
12//! Both methods ensure that the DFA has valid transitions for every symbol in its alphabet.
13//!
14//! # Documentation
15//!
16//! [nifty::dfa](dfa/index.html)  
17//! [nifty::make_dfa!](macro.make_dfa!.html)
18//!
19//! # Examples
20//!
21//! ## Building a DFA
22//!
23//! <img src="https://raw.githubusercontent.com/ObliqueMotion/nifty/master/images/example.png">
24//!
25//! ### Code
26//!
27//! ```
28//! use nifty::make_dfa;
29//!
30//! let q0 = "q0";
31//! let q1 = "q1";
32//! let q2 = "q2";
33//! let q3 = "q3";
34//!
35//! let mut dfa = make_dfa! {
36//!     states { q0, q1, q2, q3 }
37//!     accept { q0, q1 }
38//!     start  { q0 }
39//!     dead   { q3 }
40//!     transitions {
41//!         d(q0, 'a') = q1
42//!         d(q0, 'b') = q3
43//!
44//!         d(q1, 'a') = q1
45//!         d(q1, 'b') = q2
46//!
47//!         d(q2, 'a') = q1
48//!         d(q2, 'b') = q2
49//!     }
50//!     recognizes {
51//!         "empty, or starts and ends with { a }"
52//!     }
53//! };
54//!
55//! dfa.evaluate("".chars());      //    Accept
56//! dfa.evaluate("a".chars());     //    Accept
57//! dfa.evaluate("b".chars());     // Reject
58//! dfa.evaluate("aa".chars());    //    Accept
59//! dfa.evaluate("ab".chars());    // Reject
60//! dfa.evaluate("abb".chars());   // Reject
61//! dfa.evaluate("aba".chars());   //    Accept
62//! dfa.evaluate("abba".chars());  //    Accept
63//! dfa.evaluate("babba".chars()); // Reject
64//!
65//! ```
66//!
67//! ## Tracing a Path
68//!
69//! <img src="https://raw.githubusercontent.com/ObliqueMotion/nifty/master/images/example2.png">
70//!
71//! ### Code
72//!
73//! ```
74//! use nifty::make_dfa;
75//!
76//! fn main() {
77//!     let q0 = "Seen { }";
78//!     let q1 = "Seen { b }";
79//!     let q2 = "Seen { ba }";
80//!     let q3 = "Seen { bab }";
81//!
82//!     let mut dfa = make_dfa! {
83//!         states { q0, q1, q2, q3 }
84//!         start  { q0 }
85//!         goal   { q3 }
86//!         transitions {
87//!             d(q0, 'a') = q0
88//!             d(q1, 'a') = q2
89//!             d(q2, 'a') = q0
90//!
91//!             d(q0, 'b') = q1
92//!             d(q1, 'b') = q1
93//!             d(q2, 'b') = q3
94//!         }
95//!         recognizes {
96//!             "contains { bab }"
97//!         }
98//!     };  
99//!
100//!     let path = "abaababa".chars()
101//!         .map(|c| (c, dfa.get_next(&c)))
102//!         .collect::<Vec<_>>();
103//!
104//!     for tuple in &path {
105//!         println!("{:?}", tuple);
106//!     }   
107//! }
108//! ```
109//!
110//! ### Output
111//!
112//! ```text
113//! ('a', "Seen { }")
114//! ('b', "Seen { b }")
115//! ('a', "Seen { ba }")
116//! ('a', "Seen { }")
117//! ('b', "Seen { b }")
118//! ('a', "Seen { ba }")
119//! ('b', "Seen { bab }")
120//! ('a', "Seen { bab }")
121//! ```
122
123pub mod dfa;
124/// Macro [make_dfa!](macro.make_dfa!.html) creates a [DFA](dfa/struct.DFA.html) using the [DFABuilder](dfa/struct.DFABuilder.html).
125///
126/// 1. `make_dfa!` **must** take `states{...}` first.
127/// 2. `make_dfa!` **may** take any of `start{...}`, `accept{...}`, `dead{...}`, `goal{...}` in any order.
128/// 3. `make_dfa!` **may** take any of `transitions{...}`, `recognizes{...}` in any order.
129///
130/// ### Example
131///
132/// <img src="https://raw.githubusercontent.com/ObliqueMotion/nifty/master/images/example2.png">
133///
134/// ### Code
135///
136/// ```
137/// use nifty::make_dfa;
138///
139/// let q0 = "Seen { }";
140/// let q1 = "Seen { b }";
141/// let q2 = "Seen { ba }";
142/// let q3 = "Seen { bab }";
143///
144/// let mut dfa = make_dfa! {
145///     states { q0, q1, q2, q3 }
146///     start  { q0 }
147///     goal   { q3 }
148///     transitions {
149///         d(q0, 'a') = q0
150///         d(q1, 'a') = q2
151///         d(q2, 'a') = q0
152///
153///         d(q0, 'b') = q1
154///         d(q1, 'b') = q1
155///         d(q2, 'b') = q3
156///     }
157///     recognizes {
158///         "contains { bab }"
159///     }
160/// };
161/// ```
162pub mod make_dfa;