Skip to content

Commit

Permalink
Refactor state quantification into nfa::model::Input for transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
exellentcoin26 committed Jul 23, 2023
1 parent 707f22a commit 84fb589
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 308 deletions.
16 changes: 2 additions & 14 deletions src/fsm/nfa/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Compiler {
pub(super) fn compile(mut self, expr: &ExprKind) -> Nfa {
let end_state = self
.nfa
.get_final_states()
.get_final_state_ids()
.next()
.expect("exected at least one final state for the NFA to start with");

Expand All @@ -40,7 +40,7 @@ impl Compiler {
start_state: StateId,
end_state: StateId,
) -> StateId {
let quantifier_state = self.nfa.add_quantified_state(quantifier, end_state);
let quantifier_state = self.nfa.add_quantified_state(false, quantifier, end_state);

self.nfa
.add_transition(start_state, quantifier_state, Input::Eps);
Expand Down Expand Up @@ -79,12 +79,6 @@ impl Compiler {
self.expr(rhs, start, end);
}
ExprKind::Lit(lit, quantifier) => {
// TODO: Decide on how to implement quantification of states. Right now I think it
// might be possible to combine quantifiers and take min/max values of the range
// values to decide the new quantifier.
//
// Quantification can be implemented using an extra gateway state and a

let (start, end) = match quantifier {
Some(quantifier) => {
let quantifier_state =
Expand All @@ -98,12 +92,6 @@ impl Compiler {
.add_transition(start, end, Input::Literal(lit.clone()));
}
ExprKind::Group(expr, quantifier) => {
// TODO: Decide on how to implement quantification of expressions. A quantification
// can be expressed as a wrapped expression with a gateway state that counts how
// many times it is passed and can both go to the end state for the quantification
// wrapper and redo the expression when the quantification is still or not yet
// valid.

let (start, end) = match quantifier {
Some(quantifier) => {
let quantifier_state =
Expand Down
46 changes: 8 additions & 38 deletions src/fsm/nfa/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,22 @@ impl Nfa {
let final_dot = format!(
"node [shape = doublecircle]; {}",
self.get_final_states()
.map(|s| s.get_id().to_string())
.map(|State { id, .. }| id.to_string())
.collect::<Vec<String>>()
.join(" ")
);

let guard_dot = self
.states
.iter()
.filter_map(|s| match s {
State::QuantGuard { id, quantifier, .. } => {
Some(format!("{} [label = \"{} ({:?})\"];\n", id, id, quantifier))
}
_ => None,
})
.collect::<String>();

format!(
"digraph nfa {{\n\
\trankdir = LR;\n\
\n\
\t// final states\n\
\t{}\n\
{}\n\
\tnode [shape = circle]; 0;\n\
\n\
{}\n\
}}",
final_dot,
guard_dot
.lines()
.map(|l| format!("\t{}", l))
.collect::<Vec<String>>()
.join("\n"),
self.transition_dot()
.map(|l| format!("\t{}", l))
.collect::<Vec<String>>()
Expand All @@ -56,27 +40,13 @@ impl Nfa {
}

impl State {
fn transition_tuples(&self) -> Box<dyn Iterator<Item = (StateId, StateId, String)> + '_> {
match self {
State::Reg {
id, transitions, ..
} => Box::new(transitions.iter().flat_map(move |(input, dest_states)| {
fn transition_tuples(&self) -> impl Iterator<Item = (StateId, StateId, String)> + '_ {
self.transitions
.iter()
.flat_map(move |(input, dest_states)| {
dest_states
.iter()
.map(move |dest| (*id, *dest, format!("{:?}", input)))
})),
State::QuantGuard {
id,
transitions,
quantifier_done,
..
} => Box::new(
std::iter::once((*id, *quantifier_done, "quant".to_string())).chain(
transitions
.iter()
.map(|dest| (*id, *dest, format!("{:?}", Input::Eps))),
),
),
}
.map(move |dest| (self.id, *dest, format!("{:?}", input)))
})
}
}
Loading

0 comments on commit 84fb589

Please sign in to comment.