Problems making a macro which parses a recursive expression


I’m trying to make a recursive macro that parses a recursive syntax and makes an expression out of it. It looks something like this:

macro_rules! test_macro {
    (($x:tt)) => {test_macro! ($x)};
    ([$x:expr]) => {$x};
    ($x:ident : $($y:tt)*) => {($x($(test_macro! ($y)),*))};

fn add(x: u32, y: u32) -> u32 {x + y}

fn main() {
    test_macro! (add: (add: [3] [2]) [1]);

The first pattern match was made so that the third pattern match would work in a recursive context. The macro expansion I am expecting is test_macro! (A: (B: ...) ...) => A(test_macro! ((B: ...), ...) => A(test_macro! (B: ...), ...).

However, the above code doesn’t compile, but returns the error message: 10:24 error: expected ident, found (     test_macro! (add: (add: [3] [2]) [1]);

Why does this error occur? How do I make the macro behave the way I want?


Now that I think about it I believe this question is more suited to Stack Overflow.


The error occurs because there is no matching pattern to the part (add: [3] [2]) and rustc does its best to give a hint. Now you may think “but what about the first one?”. Yes, that’s a close one, but there is one problem: it matches only one token tree and (add: [3] [2]) contains four token trees. Changing that line to (($($x:tt)*)) => {test_macro! ($($x)*)}; matches zero or more token trees, and the code compiles.