2

Ragel が「最終」状態と見なすものを理解できません。IIRC のユーザーズ ガイドによると、マシンの単純化の前に最終的な状態は、その後も最終的なままです。状態が最終的なのはいつで、これをどのように認識しますか?


応用:

ステート マシンの構文を使用して、文字列ファインダーを実装しています。n より大きい長さの ASCII 文字列を見つけて、それらを出力します。これは、以下のように最大長マッチャーを実装することを意味します。

ドット出力が最終状態を示さないという事実にもかかわらず、EOF 遷移は、使用されるフレーバーによって異なる動作をします{$%@}eof。なぜこれが必要なのかわかりません。たとえば、has_string以下の状態では、%eof代わりにを使用すると、とアクション@eofの両方が、一致する状態を終了する生成/合成状態の 1 つから呼び出されます。commit_nonstring_eofcommit_string_eof

これが動作中のステートマシンです。右端のノードの終了アクションには、アクションが 1 つだけあることに注意してくださいcommit_nonstring_eofワーキング ステート マシン

これは壊れたステートマシンです。右端のノードの exit アクションは、 と の両方 commit_string_eofを呼び出すことに注意してください。commit_nonstring_eof 悪いステートマシン

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)+;
4

1 に答える 1