Crate nifty

Source
Expand description

|

§Description

The goal of this crate is not to be an efficient parsing library. Use a regex for that.
Rather, this crate aims to preserve the integrity of stepping through a DFA state diagram.

It allows you to build a DFA with states of a generic type S that recognizes a language whose symbols are of a generic type T. You can traverse each transition symbol one by one, or you can consume an iterator of symbols, which the DFA will either Accept or Reject.

DFAs are created using a DFABuilder, or by using the make_dfa! macro. Both methods ensure that the DFA has valid transitions for every symbol in its alphabet.

§Documentation

nifty::dfa
nifty::make_dfa!

§Examples

§Building a DFA

§Code

use nifty::make_dfa;

let q0 = "q0";
let q1 = "q1";
let q2 = "q2";
let q3 = "q3";

let mut dfa = make_dfa! {
    states { q0, q1, q2, q3 }
    accept { q0, q1 }
    start  { q0 }
    dead   { q3 }
    transitions {
        d(q0, 'a') = q1
        d(q0, 'b') = q3

        d(q1, 'a') = q1
        d(q1, 'b') = q2

        d(q2, 'a') = q1
        d(q2, 'b') = q2
    }
    recognizes {
        "empty, or starts and ends with { a }"
    }
};

dfa.evaluate("".chars());      //    Accept
dfa.evaluate("a".chars());     //    Accept
dfa.evaluate("b".chars());     // Reject
dfa.evaluate("aa".chars());    //    Accept
dfa.evaluate("ab".chars());    // Reject
dfa.evaluate("abb".chars());   // Reject
dfa.evaluate("aba".chars());   //    Accept
dfa.evaluate("abba".chars());  //    Accept
dfa.evaluate("babba".chars()); // Reject

§Tracing a Path

§Code

use nifty::make_dfa;

fn main() {
    let q0 = "Seen { }";
    let q1 = "Seen { b }";
    let q2 = "Seen { ba }";
    let q3 = "Seen { bab }";

    let mut dfa = make_dfa! {
        states { q0, q1, q2, q3 }
        start  { q0 }
        goal   { q3 }
        transitions {
            d(q0, 'a') = q0
            d(q1, 'a') = q2
            d(q2, 'a') = q0

            d(q0, 'b') = q1
            d(q1, 'b') = q1
            d(q2, 'b') = q3
        }
        recognizes {
            "contains { bab }"
        }
    };  

    let path = "abaababa".chars()
        .map(|c| (c, dfa.get_next(&c)))
        .collect::<Vec<_>>();

    for tuple in &path {
        println!("{:?}", tuple);
    }   
}

§Output

('a', "Seen { }")
('b', "Seen { b }")
('a', "Seen { ba }")
('a', "Seen { }")
('b', "Seen { b }")
('a', "Seen { ba }")
('b', "Seen { bab }")
('a', "Seen { bab }")

Modules§

dfa
make_dfa
Macro make_dfa! creates a DFA using the DFABuilder.

Macros§

make_dfa
Creates a DFA using the DFABuilder.