macro_rules! series {
($iter:expr, $root:ident, $matcher_gen:ident, $id_gen:expr) => { ... };
($iter:expr, $root:ident, $matcher_gen:ident, $id_gen:expr, $default_exec:expr) => { ... };
($iter:expr, $root:ident, $matcher_gen:ident, $id_gen:expr, $default_exec:expr, $inter_state_exec:expr) => { ... };
}
Expand description
Simplifies creation of series by creating states based on provided iterator and connects them coninously starting from root. Returns all states created in the process. Function can be passed to be executed at any default state switch (when no states from series can be matched). Function to be executed while switching states can also be provided. Most useful for long patterns. !!! WARNING Won’t create returning connections for matched starting patterns (starting elements existing in further parts of matched pattern meanining that new match could be possible while current match is still being processed).
§Examples
use std::{cell::RefCell, rc::Rc};
use automata_like_programming::{
series,
automaton::Automaton,
automaton_state::new_shared_concrete_state,
simple_impl::simple_state::{
KeyProvidingData,
SimpleInterStateConnection,
SimpleStateImplementation,
}
};
let mut automaton = Automaton::new({
let root: Rc<RefCell<SimpleStateImplementation<'_, (usize, char), u8, MatchListCopiedTestData<char>, String>>> = new_shared_concrete_state(SimpleStateImplementation::new(0));
let a2: Rc<RefCell<SimpleStateImplementation<'_, (usize, char), u8, MatchListCopiedTestData<char>, String>>> = new_shared_concrete_state(SimpleStateImplementation::new(4));
let defined_states = series!(
// Iterator for generating states
"abb".chars(),
// Root node which will be the start of the series
root,
// Generator for matchers - creates matchers for enumerated elements from iterator
enumerated_char_matcher,
// Id generator - creates id values to be assigned to states
|i, _| i as u8
);
assert_eq!(defined_states.len(), 3);
defined_states.get(2).unwrap().borrow_mut().register_connection(
SimpleInterStateConnection::new(enumerated_char_matcher('a'),
|data, k| {
data.set_match(k.0);
Result::Ok(())
},
&a2));
defined_states.get(2).unwrap().borrow_mut().register_connection(
SimpleInterStateConnection::new_no_action(enumerated_char_matcher('a'), defined_states.get(0).unwrap())
);
a2.borrow_mut().register_connection(SimpleInterStateConnection::new_no_action_always_matched(&root));
root.borrow_mut().register_connection(SimpleInterStateConnection::new_no_action_always_matched(&root));
root
});
// Searched pattern starts at index 2 and ends on index 5 (abba).
let mut data = MatchListCopiedTestData::new("aaabbaba".chars().collect());
let automaton_result = automaton.run(&mut data);
assert!(automaton_result.is_empty_iter());
// Found one match.
assert_eq!(data.matches().len(), 1);
// Found match ending on 5th character.
assert_eq!(*data.matches().get(0).unwrap(), 5);