gpt4 book ai didi

macros - 匹配 nom 中的几个字节之一

转载 作者:行者123 更新时间:2023-11-29 08:06:15 24 4
gpt4 key购买 nike

我正在使用 nom解析一些二进制 65c816 汇编数据。我的解析器结构的一部分将操作码拆分为单独的形式,然后获取它们的参数(如果有的话)。一个示例解析器目前看起来像这样:

named!(absolute_long<Instruction>, 
do_parse!(op: bits!(alt!(
opcode!(0x0F) | opcode!(0x22) | opcode!(0x2F) | opcode!(0x4F) |
opcode!(0x5C) | opcode!(0x6F) | opcode!(0x8F) | opcode!(0xAF) |
opcode!(0xCF) | opcode!(0xEF)))
>> param: le_u24
>> (Instruction::AbsoluteLong(op, param))));

opcode! 是我制作的宏,它执行以下操作:

macro_rules! opcode(
($i:expr, $op:expr) => (
tag_bits!($i, u8, 8, $op);
);
($i:expr, $f:expr) => (
opcode!($i, call!($f));
);
);

相反,我希望有如下代码,但无法弄清楚如何制作宏或函数来执行此操作:

named!(absolute_long<Instruction>, 
do_parse!(op: opcodes!(
0x0F, 0x22, 0x2F, 0x4F, 0x5C, 0x6F, 0x8F, 0xAF,
0xCF, 0xEF)
>> param: le_u24
>> (Instruction::AbsoluteLong(op, parm)));

我得到的最接近的是制作这个宏,但它几乎立即遇到递归限制并且总体上看起来真的不是最优的:

macro_rules! opcodes(
($i:expr, $op:expr) => {
opcode!($i, $op)
};

($i:expr, $op:expr, $($more:expr), *) => (
bits!($i, alt!(opcode!($op) | opcodes!($($more),*)))
);
);

有什么方法可以实现这样的功能,还是只使用 tag_bits 会更好?我觉得我应该可以使用 one_of,但我无法让它与字节一起工作。

最佳答案

我们可以使用one_of!(..)喜欢so :

#[macro_use]
extern crate nom;
use nom::*;

// Your type might look a different, I infered what I could:
#[derive(Debug)]
enum Instruction {
AbsoluteLong(u8, u32)
}

named!(absolute_long<Instruction>, do_parse!(
op: one_of!([0x0F, 0x22, 0x2F, 0x4F, 0x5C, 0x6F, 0x8F, 0xAF, 0xCF, 0xEF].as_ref())
>> param: le_u24
>> (Instruction::AbsoluteLong(op as u8, param))
));

fn main() {
println!("{:?}", absolute_long(&[0x0F, 0x01, 0x01, 0x01, 0x01]));
}

one_of! 必须指定一个切片才能使用。我们可以通过使用 .as_ref() 将数组转换到它来获得一个.

关于macros - 匹配 nom 中的几个字节之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44449354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com