2017-09-12 7 views
4

このように適用できるマクロcallmeを定義したいと思います。文法的な事例を扱うマクロを定義することはできますか?

fn main() { 
    let a=4; 
    let b=5; 
    callme!(
     a (b) => { a+b } ; 
     a (b) => { a*b } ; 
     a (b) ~ C 
    ); 
} 

私はcallmeのために働いてマクロ定義を取得する方法がわかりません。現在、私は次のようなものを試しています。

macro_rules! callme { 
    (
     $($A: ident ($B: ident) => {$E: expr}) ; * 
    ) => (
     $(
      println!("{:?} {:?} {:?}", $A, $B, $E); 
     ) * 
    ); 
    (
     $($A: ident ($B: ident) ~ $Q: ident) ; * 
    ) => (
     $(
      println!("We got {:?} . {:?} . {:?}", $A, $B, $Q); 
     ) * 
    ); 
} 

私は一度に両方の構文を使うことができないので、これはうまくいきません。

答えて

8

トークンストリームを使って作業しているときは、このような場合に再帰処理をして処理する方が簡単です。あなたは、インスタンスのために行うことができます:

macro_rules! callme { 
    ($A:ident ($B:ident) => { $E:expr }; $($rest:tt)*) => { 
     println!("{:?} {:?} {:?}", $A, $B, $E); 

     callme!($($rest)*); 
    }; 
    ($A:ident ($B:ident) ~ $Q:ident; $($rest:tt)*) => { 
     println!("We got {:?} . {:?} . {:?}", $A, $B, $Q); 

     callme!($($rest)*); 
    }; 
    () => {}; 
} 

fn main() { 
    let a=4; 
    let b=5; 
    let c = "C"; 
    callme!(
     a (b) => { a+b } ; 
     a (b) => { a*b } ; 
     a (b) ~ c; 
    ); 
} 

On Playground

注意をトークンの各セットの後、あなたは残りのすべてのトークンを収集し、最終的に、callme!に後で呼び出しによって処理されるようにそれらを残すこと完了条件を示すために() => {}

+0

ありがとうございます。これは動作します!あなたの答えは、私に錆のマクロのトークンストリームを理解させる助けになりました。残念ながら、あなたの答えはまだ+1できません。 – Leonard7E

関連する問題