【问题标题】:How to implement a fsm如何实现 fsm
【发布时间】:2021-12-17 11:58:27
【问题描述】:

我想使用 fsm 编程模型解析命令行工具的输出。对于这项任务来说,最简单的 fsm 实现是什么?

【问题讨论】:

    标签: c implementation fsm


    【解决方案1】:

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

    一个简单的方法是使用一个整数变量(或一个enum)来存储状态,以及一个switch()语句来实现,对于每个案例,需要的逻辑。

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

    something
    begin
      something
      something2
    end
    something
    

    你的职责是打印开始/结束之间的部分。您逐行读取文件,并根据该行的内容切换状态:

    // 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;
      }
    }
    

    在这个例子中,只显示了核心思想:机器的“状态”和改变状态的手段(从文件中读取的“行”)。在现实生活的例子中,可能有更多的变量来为每个状态保留更多的信息,也许机器的“状态”可以存储在函数指针中,以避免 switch() 语句,但即便如此,编程范式仍然干净且强大。

    【讨论】:

      【解决方案2】:

      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. */
      }
      
      

      【讨论】:

        猜你喜欢
        • 2017-03-13
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 2011-10-09
        • 1970-01-01
        • 2016-11-12
        相关资源
        最近更新 更多