Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为任何已知长度的数据优化Ragel语义条件_Ragel - Fatal编程技术网

为任何已知长度的数据优化Ragel语义条件

为任何已知长度的数据优化Ragel语义条件,ragel,Ragel,6.5语义条件中有一个例子,演示了如何使用when子句编写可变大小结构的语法 action rec_num { i = 0; n = getnumber(); } action test_len { i++ < n } data_fields = ( ’d’ [0-9]+ %rec_num ’:’ ( [a-z] when test_len )* )**; action rec_num{i=0;n=getnumber();} 动作测试{i++

6.5语义条件中有一个例子,演示了如何使用when子句编写可变大小结构的语法

action rec_num { i = 0; n = getnumber(); }
action test_len { i++ < n }
data_fields = (
’d’
[0-9]+ %rec_num
’:’
( [a-z] when test_len )*
)**;
action rec_num{i=0;n=getnumber();}
动作测试{i++
对于小的结构,它工作得很好,但是对于大的结构,它会变慢,因为解析器试图对每个字符求值

我试图做的是跳过扫描,只是将数据复制到缓冲区中,对于这样的语法(注意any*):

action rec_num{i=0;n=getnumber();}
动作测试{i++

所以我想直接复制长度为n的缓冲区,不需要迭代。如何在不离开解析器上下文的情况下完成此操作?

您可能需要自己处理问题。ragel用户指南提到,您可以在机器内更改
fpc
/
p
变量,这样应该足够安全。这假设您在一个块中处理所有数据(即,数据字段不会被拆分)


好主意,但是如果我有多个流水线命令,并且其中一些命令是分块的呢?重置eof有帮助吗?
action rec_num { i = 0; n = getnumber(); }
action test_len { i++ < n }
data_fields = (
’d’
[0-9]+ %rec_num
’:’
( any* when test_len )*
)**;
machine foo;

action rec_num { i = 0; n = getnumber(); }
action test_len { i++ < n }
action buffer_data_field {
  /* p is still pointing to ':' at this point. */
  if (p + 1 + n >= pe) { fgoto *foo_error; }
  buffer(p + 1, n);
  p += n;
}
action buffer_data_field_eof {
  /* check for eof while data was expected */
  /* p is pointing past the ':' at this point */
  if (n) { fgoto *foo_error; }
}

data_fields = (
'd'
[0-9]+ %rec_num
':' 
$buffer_data_field
$eof(buffer_data_field_eof)

)**;
buffer_data :=
    any+
    $eof{ fnext *foo_error; }
    ${
        size_t avail = pe - p;
        if (avail >= n) {
            buffer(p, n);
            p += n - 1;
            fnext data_fields;
        } else {
            buffer_partial(p, avail);
            n -= avail;
            p += avail - 1;
        }
    }
    ;


data_fields = (
    'd'
    [0-9]+ %rec_num
    ':'  ${ if (n) fnext buffer_data; }
    )**;