It seems that the Rust macro system is inspired by a similar idea: In the first step (the "reader" in this article's terminology), the source is converted into something called a token tree.
A token tree is not a full parse tree with resolved operator precedence and whatnot. It only has child nodes for bracket pairs ((), [] and {}) and their contents, in part to determine where the macro call ends. Otherwise, it's a flat list of tokens that the macro (what this article would call the "parser") can interpret in any way it wants.