1

我有两种状态;一个是另一个更一般的状态的特定实例。我相信避免同时进入两种状态的正确方法是使用 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仅当它不是 a 时才会发生完成操作known_segment,这似乎是您想要实现的行为。

于 2012-11-30T23:19:23.637 回答