如何实现 FSM

How to implement a fsm

我想使用 fsm 编程模型解析命令行工具的输出。此任务可能的最简单的 fsm 实现是什么?

fsm 模型在 C 中通过将函数指针分配给必须处理特定数据的特定函数来工作。 fsms 的一个很好的用途是解析命令行参数,解析捕获的输出......函数指针被分配给一个预设的启动函数。 start 函数将 必须 传递的函数指针分配给适当的下一个函数。这决定了下一个功能等等。 这是一个非常简单的 fsm 实现:

struct _fsm
{
    void (*ptr_to_fsm)(struct _fsm fsm);
    char *data;
}

struct _fsm fsm;
fsm->ptr_to_fsm = start; // There is a function called start.
while (fsm->ptr_to_fsm != NULL)
{
    fsm->ptr_to_fsm(&fsm);
}

void start (struct _fsm fsm)
{
    if (fsm->data == NULL)
    {
         fsm->ptr_to_fsm = stop; // There is a function called stop.
    }
    /* Check more more conditions, and branch out on other functions based on the results. */
    return;
}

void stop (struct _fsm fsm)
{ 
   fsm->ptr_to_fsm = NULL; /* The while loop will terminate. */
   /* And you're done (unless you have to do free`ing. */
}

基本上,有限状态机的核心思想是机器处于一个“状态”,对于每个状态,机器的行为都不同于其他状态。

一个简单的方法是使用一个整数变量(或一个 enum)来存储状态,以及一个 switch() 语句,它为每种情况实现所需的逻辑。

假设您有以下类型的文件:

something
begin
  something
  something2
end
something

而你的职责是打印 begin/end 之间的部分。您逐行读取文件,并根据行的内容切换状态:

// pseudo-C code
enum state {nothing, inblock};
enum state status;
string line;

status = nothing;

while (!eof(file)) {
  readline(line);
  switch(status) {
    case nothing:
      if (line == "begin") status=inblock;
      break;
    case inblock:
      if (line == "end")
        status=nothing;
        else print(line);
      break;
  }
}

在此示例中,仅显示了核心思想:机器的“状态”和更改状态的方法(从文件中读取的“行”)。在现实生活中的例子中,可能有更多变量来为每个状态保存更多信息,也许机器的“状态”可以存储在函数指针中,以避免 开关的负担和僵化( ) 声明,但即便如此,编程范式还是干净而强大的。