#状态机 #有限状态机 #确定性的 #状态转换 #非确定性的 #构建器 #自动机

automafish

Automafish是一个状态机构建器,用于将非确定性状态机定义转换为确定性状态机

1个不稳定版本

0.1.0 2020年11月20日

#1506算法

MIT/Apache

47KB
656

::<automa>

创建确定性状态机的状态机构建器

crates.io Docs

Automafish是一个状态机构建器,可以将非确定性有限自动机转换为确定性有限自动机。其主要用途是驱动metamorfish的选择器逻辑,以允许在proxide中对protofish值进行变异。

use std::iter::FromIterator;
use automafish::{Builder, State, Transition, Criteria, Condition};

let mut builder : Builder<Condition<char>, &mut dyn FnMut(&mut char)> = Builder::new();

// Set up an automata that capitalizes first character of a word.
let mut upper_case = |mut c: &mut char| { c.make_ascii_uppercase(); };
let wait_not_space = builder.create_initial_state();
let first_not_space = builder.add_state(State::with_action(&mut upper_case));
let wait_for_space = builder.add_state(State::new());

builder.add_transition(Transition::new(
    wait_not_space, Condition::Is(vec![' ']), wait_not_space));
builder.add_transition(Transition::new(
    wait_not_space, Condition::Not(vec![' ']), first_not_space));
builder.add_transition(Transition::new(
    first_not_space, Condition::Not(vec![' ']), wait_for_space));
builder.add_transition(Transition::new(
    first_not_space, Condition::Is(vec![' ']), wait_not_space));
builder.add_transition(Transition::new(
    wait_for_space, Condition::Not(vec![' ']), wait_for_space));
builder.add_transition(Transition::new(
    wait_for_space, Condition::Is(vec![' ']), wait_not_space));

// Set up an automata that counts all exclamation marks.
// This automata modifies a value outside the state machine.
let mut exclamations = 0;
let mut exclamation_counter = |_: &mut char| { exclamations += 1; };
let wait_exclamation = builder.create_initial_state();
let exclamation = builder.add_state(State::with_action(&mut exclamation_counter));

builder.add_transition(Transition::new(
    wait_exclamation, Condition::Any, wait_exclamation));
builder.add_transition(Transition::new(
    wait_exclamation, Condition::Is(vec!['!']), exclamation));

// Build the machine.
let mut machine = builder.build();

// Execute the machine on an input string.
let mut current_state = machine.start();
let mut input : Vec<char> = "hello world! this is rust!".chars().collect();
for i in &mut input {
    current_state = machine.step_and_execute_mut(current_state, i);
}

let output : String = String::from_iter(input);

assert_eq!("Hello World! This Is Rust!", output);
assert_eq!(2, exclamations);
  • Proxide - 一个用于HTTP/2和特别是gRPC流量的调试代理。这是使用Automafish在其脚本实现中通过Metamorfish的主要应用。
  • Metamorfish - 一个基于选择器的变异引擎,旨在允许轻松定义修改Proxide截获的数据结构的操作。使用Automafish为选择器实现状态机。

此外,在查找选项时似乎还有其他通用的状态机crate。如果您在此寻找一个,您可能也会对以下crate感兴趣。请注意,我还没有亲自测试过这些crate。

  • automata - 一个通用自动机crate,根据其描述,实现DFA/NFA/正则表达式转换操作。有一长串计划中的功能,尽管开发似乎已经停止。
  • nifty - 一个生成DFAs的crate。根据其readme,基于宏的方法对于静态DFAs来说相当巧妙。我的用例需要根据用户脚本在运行时指定DFAs,这使我转向了其他选择。该crate似乎也仅限于DFAs,没有提供从NFA构建它们的支持。
  • rustomaton - 一个自动机操作库。似乎包括各种自动机(包括确定有限状态自动机(DFA)和非确定有限状态自动机(NFA))之间的转换函数。然而,自动机的执行阶段似乎需要事先获取所有输入,所以我不是很确定它是否适合我的需要,即能够执行各种中间状态的摩尔机。

目标

Automafish目前唯一的目标是为Metamorfish提供一个相对高效的有限状态机实现。

Metamorfish之外的使用场景当然不在范围之内,但目前我可能不会添加Automafish的新功能,除非Metamorfish需要。当然,功能和pull请求是欢迎的!只是没有其他优先事项,Metamorfish和Proxide本身对我更有吸引力。 :)

也许在未来

目前,由于需要解决这些标准之间的交集和差异,定义自定义Criteria相当痛苦。我将简化处理Criteria的过程,但当前我并不知道如何在没有(至少)交集处理的情况下构建幂集。

此外,我还没有深入研究此类用例的可用算法。

依赖关系

~87KB