FSM状态的实现技术

时间:2010-06-21 11:20:48

标签: language-agnostic finite-automata states

如何实施FSM(编辑:有限状态机)状态? 我通常认为FSM就像一组函数, 调度员, 以及表示当前运行状态的线程。 意思是,我阻止了对函数/仿函数表示的调用 的状态。

刚才我用不同的风格实现了一个, 我仍然用函数(对象)s表示状态,但线程 只需调用state->step()方法,该方法会尝试返回 尽快。如果状态已经完成并且a 过渡应该发生,它表明相应。 我称之为'轮询'风格,因为功能大多看起来 像:

void step()
{
  if(!HaveReachedGoal)
  {
    doWhateverNecessary();
    return; // get out as fast as possible
  }
  // ... test perhaps some more subgoals
  indicateTransition();
}

我知道它是FSM中的FSM。

感觉相当简单,但它有一定的优势。 虽然一个线程被阻止,或者被某种线程所占据 while (!CanGoForward)checkGoForward(); 循环可能很麻烦,不实用, 调查更容易调试。 那是因为FSM对象之后重新获得了控制权 每一步,并发布一些调试信息是轻而易举的。

好吧,我偏离了我的问题: 如何实现FSM的状态?

5 个答案:

答案 0 :(得分:1)

我总是称之为Flying Spaghetti Monster实现FSM(FSM风格的FSM)的风格:使用lota goto s。例如:

state1:
  do_something();
  goto state2;

state2:
  if (condition) goto state1;
  else           goto state3;

state3:
  accept;

非常好的意大利面条代码: - )

答案 1 :(得分:1)

我把它作为一个表,在内存中的一个平面数组,每个单元格都是一个状态。请查看the abandoned DFA project的cvs来源。对于example

class DFA {
    DFA();
    DFA(int mychar_groups,int mycharmap[256],int myi_state);
    ~DFA();
    void add_trans(unsigned int from,char sym,unsigned int to);
    void add_trans(unsigned int from,unsigned int symn,unsigned int to);
    /*adds a transition between state from to state to*/
    int add_state(bool accepting=false);
    int to(int state, int symn);
    int to(int state, char sym);
    void set_char(char used_chars[],int);
    void set_char(set<char> char_set);
    vector<int > table; /*contains the table of the dfa itself*/
    void normalize();

    vector<unsigned int> char_map;
    unsigned int char_groups; /*number of characters the DFA uses,
                    char_groups=0 means 1 character group is used*/
    unsigned int i_state; /*initial state of the DFA*/
    void switch_table_state(int first,int sec);
    unsigned int num_states;
    set<int > accepting_states;
};

但这是一个非常具体的需求(匹配正则表达式)

答案 2 :(得分:1)

状态设计模式是实现FSM的一种有趣方式:

http://en.wikipedia.org/wiki/State_pattern

这是实现FSM的一种非常干净的方式,但它可能会很麻烦,具体取决于FSM的复杂程度(但不是状态数量)。但是,优点是:

  • 您消除了代码重复(特别是if / else语句)
  • 使用新状态更容易扩展
  • 你的类具有更好的凝聚力,所以所有相关的逻辑都在一个地方 - 这也应该使你的代码更容易编写测试。

此站点有一个Java和C ++实现:

http://www.vincehuston.org/dp/state.html

答案 3 :(得分:1)

我记得我的第一个FSM计划。我用C语言写了一个非常简单的开关语句。从一种状态切换到另一种状态或者一直到下一个状态似乎很自然。

然后我继续使用表查找方法。我能够使用这种方法编写一些非常通用的编码风格。但是,当需求发生变化时,我被抓了几次,我必须支持一些额外的事件。

我最近没有写过任何FSM。我写的最后一篇是用于C ++中的comms模块,其中我使用了“状态设计模式”和“命令模式”(动作)。

答案 4 :(得分:0)

如果要创建复杂的状态机,那么您可能需要查看SMC - 状态机编译器。这需要一个状态机的文本表示,并将其编译成您选择的语言 - 它支持Java,C,C ++,C#,Python,Ruby,Scala和许多其他语言。