有没有可能定义一个宏来处理语法格?

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

这不可行,因为我不能同时使用两种语法情况。
1个回答

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

(在Playground上查看)

请注意,在每组标记后,您需要收集所有剩余的标记,并将它们留给稍后调用callme!处理,最后使用() => {}表示完成条件。


谢谢你的回答。这个方法可行!你的回答帮助我理解了 Rust 宏的令牌流。不幸的是,我现在还不能给你点赞。 - Leonard7E

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接