1

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 バイトの先読みが必要であることを意味します。

4

1 に答える 1

2

JPEG ヘッダーをトークン化し、不明なセグメントをスキップして、JFIF のような既知のセグメントを処理したいと考えています。JPEG アプリケーション セグメント app0 は 0xFFE0 で始まります。app0 に JFIF データが含まれている場合、app0 マーカーの後に 2 バイトの長さと文字列 "JFIF\0" が続きます。

わかった。

これは、アプリケーション セグメントを識別するときに 7 バイトの先読みが必要であることを意味します。

なんで?一般的なパターンを使用して既知のセグメントを除くすべてのセグメントに「不明な」パターンを適用することができます。

seg_app0_jfif = mk_app0 seglen16 "JFIF" 0x00 buffer @{ printf("jfif app0\n"); };
known_segment = (seg_app0_jfif | seg_app1_exif);
unknown_segment = ((mk_appx nonmarker*) - known_segment) @{ printf("unknown app content\n"); };
seg_app = (known_segment | unknown_segment);

この方法では、先読みは必要ありません。Ragel は適切な状態と遷移を生成し、十分な入力が処理されて曖昧さがなくなるまで、両方のパターンを同時に処理します。の仕上げアクションunknown_segmentは、それが ではない場合にのみ発生しknown_segmentます。これは、達成しようとしている動作のようです。

于 2012-11-30T23:19:23.637 に答える