Ragel,最终状态和EOF

时间:2013-07-25 04:20:41

标签: state-machine ragel

我不明白Ragel认为什么是“最终”状态。 IIRC用户指南说,在机器简化之前的最终状态在此之后仍然是最终的。 什么时候确定状态是最终的,人们如何认识到这一点?


应用

我正在使用状态机语法来实现字符串查找器 - 查找长度大于n的ASCII字符串,然后打印它们。这意味着实现最大长度匹配器,如下所示。

尽管点输出没有显示最终状态,但EOF转换的行为会有所不同,具体取决于使用{$%@}eof的风格。我不明白为什么会这样。例如,在下面的has_string状态下,使用%eof代替@eof会导致从生成的/中的一个调用commit_nonstring_eofcommit_string_eof操作合成状态终止匹配状态。

这是一个工作状态机。请注意,最右侧的节点退出操作只有一个操作:commit_nonstring_eofWorking state machine

这是一台破损的状态机。请注意,最右侧的节点退出操作会同时调用它们 commit_string_eofcommit_nonstring_eof Bad state machine

action commit_string { }
action commit_string_eof { }
action commit_nonstring_eof { }
action set_mark { }

action reset {
   /* Force the machine back into state 1. This happens after
    * an incomplete match when some graphical characters are
    * consumed, but not enough for use to keep the string. */
    fgoto start;
 }

 # Matching classes union to 0x00 .. 0xFF
 graphic = (0x09 | 0x20 .. 0x7E);
 non_graphic =  (0x00 .. 0x08 | 0x0A .. 0x1F | 0x7F .. 0xFF);

 collector = (

 start: (
     # Set the mark if we have a graphic character,
     # otherwise go to non_graphic state and consume input
     graphic @set_mark -> has_glyph |
     non_graphic -> no_glyph
 ) $eof(commit_nonstring_eof),

 no_glyph: (
     # Consume input until a graphic character is encountered
     non_graphic -> no_glyph |
     graphic @set_mark -> has_glyph
 ) $eof(commit_nonstring_eof),

 has_glyph: (
      # We already matched one graphic character to get here
      # from start or no_glyph. Try to match N-1 before allowing
      # the string to be committed. If we don't get to N-1,
      # drop back to the start state
      graphic{3} $lerr(reset) -> has_string
  ) @eof(commit_nonstring_eof),

  has_string: (
      # Already consumed our quota of N graphic characters;
      # consume input until we run out of graphic characters
      # then reset the machine. All exiting edges should commit
      # the string. We differentiate between exiting on a non-graphic
      # input that shouldn't be added to the string and exiting
      # on a (graphic) EOF that should be added.
      graphic* non_graphic -> start
  ) %from(commit_string) @eof(commit_string_eof) // okay
 #) %from(commit_string) %eof(commit_string_eof) // bad

); #$debug;

main := (collector)+;

1 个答案:

答案 0 :(得分:1)

认为对于连接的机器a.b,当a转换为{{1}的第一个字符时,a的最终状态会发生1}}。 (参见手册中的“常规语言操作符/连接”)。

  

尽管点输出显示没有最终状态

点输出显示了很多最终状态。例如,从7到6的过渡使得7最终。从6过渡到1使得6最终,依此类推。