如何实施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的状态?
答案 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的复杂程度(但不是状态数量)。但是,优点是:
此站点有一个Java和C ++实现:
答案 3 :(得分:1)
我记得我的第一个FSM计划。我用C语言写了一个非常简单的开关语句。从一种状态切换到另一种状态或者一直到下一个状态似乎很自然。
然后我继续使用表查找方法。我能够使用这种方法编写一些非常通用的编码风格。但是,当需求发生变化时,我被抓了几次,我必须支持一些额外的事件。
我最近没有写过任何FSM。我写的最后一篇是用于C ++中的comms模块,其中我使用了“状态设计模式”和“命令模式”(动作)。
答案 4 :(得分:0)
如果要创建复杂的状态机,那么您可能需要查看SMC - 状态机编译器。这需要一个状态机的文本表示,并将其编译成您选择的语言 - 它支持Java,C,C ++,C#,Python,Ruby,Scala和许多其他语言。