2 つの状態があります。一方は、他方のより一般的な状態の特定のインスタンスです。両方の状態に同時に入るのを避ける正しい方法は、k>1 で先読みを実装することだと思いますが、これを行う方法の例は見つかりません。
Ragle のユーザー ガイドには次のように書かれています。
fhold と fexec の両方を使用する場合、ユーザーは、現在の位置が調整される遷移が他のマシンからの遷移と結合されないように、結果のマシンを別のマシンと結合することに注意する必要があります。
これが何を意味するのかは完全にはわかりませんが、おそらく「現在の式の最後を超えて読み取ろうとしないでください」ということを除いて.
私のマシンは次のようになります。
seglen16 = any{2} >{ swab(p, &len, 2); len = len - 2; };
action check {len--}
buffer = (any when check)* %when !check @{ printf("[%d]:%d\n", len, *p); };
# JPEG Markers
mk_app0 = 0xFF 0xE0;
mk_appx = 0xFF (0xE0..0xEF);
marker = 0xFF ^0x00;
nonmarker = !marker - zlen;
# JPEG APP Segments
seg_app0_jfif = mk_app0 seglen16 "JFIF" 0x00 buffer @{ printf("jfif app0\n"); };
seg_appx_unk = mk_appx nonmarker* @{ printf("unknown app content\n"); };
seg_app = (seg_app0_jfif | seg_app1_exif | seg_appx_unk);
# Main Machine
expr = (mk_soi @lerr(bad) nonmarker* seg_app* nonmarker* mk_eoi);
JPEG ヘッダーをトークン化し、未知のセグメントをスキップして、JFIF のような既知のセグメントを処理したいと考えています。JPEG アプリケーション セグメント app0 は で始まります0xFFE0
。app0 に JFIF データが含まれている場合、app0 マーカーの後に 2 バイトの長さと文字列 " JFIF\0
" が続きます。これは、アプリケーション セグメントを識別するときに 7 バイトの先読みが必要であることを意味します。