Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.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
Parsing 使用nom基于前面的元素有条件地解析数组_Parsing_Rust_Nom - Fatal编程技术网

Parsing 使用nom基于前面的元素有条件地解析数组

Parsing 使用nom基于前面的元素有条件地解析数组,parsing,rust,nom,Parsing,Rust,Nom,我需要从一个U8数组中解析一个32位整数的数组(小尾数),但是下一个整数只有在设置了当前整数的第31位时才存在。如果其余部分不存在,则应将数组的其余部分设置为零。我不知道如何有条件地解析下一个元素 假设该字段的长度为4字节。然后parse_field函数的结果将是使用le_u32解析4个字节,这将是[u32;8]数组中的第一个元素。但是,如果已设置此字段的第31位。然后还有另外4个字节,也和这个字段类似,它进入数组的下一个元素。如果未设置,则函数必须返回数组,并将其余元素设置为零。这将继续适用于

我需要从一个U8数组中解析一个32位整数的数组(小尾数),但是下一个整数只有在设置了当前整数的第31位时才存在。如果其余部分不存在,则应将数组的其余部分设置为零。我不知道如何有条件地解析下一个元素

假设该字段的长度为4字节。然后parse_field函数的结果将是使用le_u32解析4个字节,这将是[u32;8]数组中的第一个元素。但是,如果已设置此字段的第31位。然后还有另外4个字节,也和这个字段类似,它进入数组的下一个元素。如果未设置,则函数必须返回数组,并将其余元素设置为零。这将继续适用于每个现有领域

例如,对于以下输入:

0x8000000a
0x8000000b
...
您将得到
[0x800000a,0x800000b,0,0,0,0,0,0]

extern crate nom;

use nom::*;

#[derive(Clone, Copy, Debug)]
struct Derp {
    field: [u32; 8]
}

named!(parse_field<[u32; 8]>,

    // what do I do here

);


named!(parse_derp<Derp>,
    do_parse!(
        field: parse_field >>
        (Derp {
            field: field
        })
    )
);

fn main() {
    let temp = [0x0a, 0x00, 0x00, 0x80, 0x0b, 0x00, 0x00, 0x80];
    println!("{:?}", parse_derp(&temp));
}
但是如果输入是

0x8000000a
0x8000000b
0x8000000c
0x8000000d
0x8000000e
....
然后您将得到
[0x800000a,0x800000b,0x800000c,0x800000d,0x800000e,0,0,0]

extern crate nom;

use nom::*;

#[derive(Clone, Copy, Debug)]
struct Derp {
    field: [u32; 8]
}

named!(parse_field<[u32; 8]>,

    // what do I do here

);


named!(parse_derp<Derp>,
    do_parse!(
        field: parse_field >>
        (Derp {
            field: field
        })
    )
);

fn main() {
    let temp = [0x0a, 0x00, 0x00, 0x80, 0x0b, 0x00, 0x00, 0x80];
    println!("{:?}", parse_derp(&temp));
}
外部板条箱名称;
使用名称::*;
#[派生(克隆、复制、调试)]
结构Derp{
字段:[u32;8]
}
命名!(解析u字段,
//我在这里干什么
);
命名!(parse_derp,
别客气(
字段:解析\u字段>>
(德普{
字段:字段
})
)
);
fn main(){
设temp=[0x0a,0x00,0x00,0x80,0x0b,0x00,0x00,0x80];
println!(“{:?}”,parse_derp(&temp));
}

在这里使用Vec是否可能更好?

这里有一个与您输入的最后一个
u32
匹配的解析器:

named!(last_u32<u32>,
  verify!(le_u32, |n:u32| (n & 0b1) != 0) // Matches iff the 31st bit is set
);
命名!(最后),
验证!(leu u32,| n:u32 |(n&0b1)!=0)//设置第31位时匹配
);
然后您可以这样使用它:

named!(parse_field<Vec<u32>>,
  map!(
    many_till!(le_u32, last_u32),
    |(mut v,n)| { v.push(n); v } // Add the last u32 to the vector
  ) 
);
命名!(解析u字段,
地图(
还有很多!(le_u32,last_u32),
|(mut v,n){v.push(n);v}//将最后一个u32添加到向量
) 
);

您必须为此使用nom吗?你能不能只按位
&2
循环你的i32,直到你遇到一个错误?请重新格式化你的问题,为你的案例输入更多的例子,我谁都不懂你的问题。我已经更新了问题。我必须使用nom,因为这是更大的解析器的一部分。也许最好的方法是手动编写适合nom的解析函数,比如
fn parse_field(i:&[u8])->IResult{……}