2017-09-12 6 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