【问题标题】:Is it possible to define a macro which handles grammatical cases?是否可以定义一个处理语法案例的宏?
【发布时间】:2017-09-12 21:57:32
【问题描述】:

我想定义一个可以像这样应用的宏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);
        ) *
    );
}

这不起作用,因为我不能同时使用这两种语法情况。

【问题讨论】:

    标签: macros rust


    【解决方案1】:

    当您使用令牌流时,在这种情况下,将其留给递归处理您的片段会更容易。例如,您可以这样做:

    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! 处理,最后一个() => {} 表示完成条件。

    【讨论】:

    • 感谢您的回答。这行得通!您的回答帮助我理解了 rust 宏的令牌流。遗憾的是,我还不能 +1 你的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    相关资源
    最近更新 更多