2017-06-09 6 views
2

nomを使用して、いくつかのバイナリ65c816アセンブリデータを解析しています。私のパーサ構造の一部は、オペコードを別々のフォームに分割し、パラメータがあればそれらのパラメータを取得します。例えば、パーサーは現在、次のようになります。nomのいくつかのバイトの1つに一致します

opcode!は、私は次のことを行い作られたマクロです
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)))); 

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))); 

私はこのマクロを作っていたましたが、それはほとんどすぐに再帰限度に実行され、それがreall思わ最も近いです一般的には次善のy:

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を使用できるはずですが、バイトで動作させることができません。

答えて

3

我々は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()で配列をキャストして1つを得ることができます。

+0

ありがとうございました!私は 'one_of! 'でかなり時間をかけてみましたが、私がRustには新しいので、' .as_ref() 'やスライスに関連するエラーをどのように解釈するのか分かりませんでした。それは私のマクロを取り除き、これらのすべてのパーサーをよりきれいに見せるようなものにします。 – ozdrgnaDiies

+0

配列とスライスの構文はややこしいことがあります。あなたは歓迎です=) – Centril

関連する問題