C 如何在Ragel中实现前瞻

C 如何在Ragel中实现前瞻,c,ragel,C,Ragel,我有两个州;一个是另一个更一般的状态的具体实例。 我认为避免同时进入这两个状态的正确方法是在k>1的情况下实现前瞻,但我找不到任何例子来说明如何做到这一点 Ragle用户指南说: 在fhold和fexec的使用中,用户必须谨慎地将产生的机器与另一台机器组合在一起,以使调整当前位置的转换不会与另一台机器的转换组合在一起 我不完全确定这意味着什么,除了“不要试图读过当前表达式的结尾” 我的机器看起来像这样: seglen16 = any{2} >{ swab(p, &len, 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标记后面将跟一个两字节的长度和字符串“
JFIF\0
”。这意味着在识别应用程序段时,我需要7字节的前瞻

我想标记一个JPEG头,跳过未知的片段,并处理众所周知的片段,如JFIF。JPEG应用程序段app0以0xFFE0开头。如果app0包含JFIF数据,app0标记后面将跟一个两字节的长度和字符串“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生成适当的状态和转换,同时处理这两种模式,直到处理了足够多的输入以消除歧义。只有当
未知\u段
不是
已知\u段
时,才会对该段执行结束操作,这似乎是您试图实现的行为。

使用前瞻功能可以使输入的转换明确无误。这将产生一个更简单的机器,并使实际的模式处理操作更容易实现。