macro_rules Reference¶
See also
macro_polo.macros.macro_rules.MacroRulesParserMacroAPI reference for the
macro_rulesdeclaration parser macro.macro_polo.matchAPI reference for the pattern matching machinary used by
macro_rules.macro_polo.transcribeAPI reference for the output transcribing machinary used by
macro_rules.
macro_rules! declarations consist of one or more rules, where each rule consists of
a matcher and a transcriber.
When the macro is invoked, its input is compared to each matcher (in the order in which they were defined). If the input macthes, the capture variables are extracted and passed to the transcriber, which creates a new token sequence to replace the macro invocation.
This is the syntax for defining a macro_rules! macro:
macro_rules! macro_name:
[matcher0]:
transcriber0
...
[matcher0]:
transcribern
Matchers¶
The following constructs are supported in macro_rules! matchers:
- Capture Variable
$name:type- Repeater
$(pattern)?|$(pattern)*|$(pattern)sep*|$(pattern)+|$(pattern)sep+A pattern repeater. Matches
pattern≤1 (?), ≥0 (*), or ≥1 (+) times.If
sepis present, it is a single-token separator that must match between each repitition.Capture variables inside repeaters become “repeating captures.”
- Union
$[(pattern)|...|(pattern)]A union of patterns. Patterns are tried sequentially from left to right.
All pattern variants must contain the same capture variable names at the same levels of repitition depth. The capture variable types, on the other hand, need not match.
- Negative Lookahead
$[!pattern]A negative lookahead. Matches zero tokens if
patternfails to match. Ifpatterndoes match, the negative lookahead will fail.- Escape Sequences
All other tokens are matched exactly (ex:
123matches aNUMBERtoken with string'123').
Capture Variables¶
Capture variables are patterns that, when matched, bind the matching token(s) to a name
(unless that name is _).
They can then be used in a transcriber to insert the matched token(s) into the macro
output.
Capture variables consist of a name and a type. The name
can be any NAME token. The supported types are described
below:
tokenMatches any single token, except delimiters.
nameMatches a
NAMEtoken.opMatches a
OPtoken, except delimiters.numberMatches a
NUMBERtoken.stringMatches a
STRINGtoken.ttMatches a “token tree”: either a single non-delimiter token, or a pair of (balanced) delimiters and all of the tokens between them.
nullAlways matches zero tokens. Useful for counting repitions, or for filling in missing capture variables in union variants.
Transcribers¶
The following constructs are supported in macro_rules! transcribers:
- Capture Variable Substitution
$nameTranscribes the token(s) bound to
name.If the corresponding capture variable appears within a repeater, the substitution must also be in a repeater at the same or greater nesting depth.
- Repeater
$(pattern)*|$(pattern)sep*A pattern repeater. There must be at least one repeating substitution in
pattern, which determines how many times the pattern will be transcribed. Ifpatterncontains multiple repeating substitutions, they must repeat the same number of times (at the current nesting depth).If
sepis present, it is a single-token separator that will be transcribed before each repitition after the first.- Escape Sequences
All other tokens are transcribed unchanged.
Delimiters¶
Delimiters are pairs of tokens that enclose other tokens, and must always be balanced.
There are five types of delimiters:
Parentheses (
(,))Brackets (
[,])Curly braces (
{,})Indent/dedent
f-strings
Note that f-strings come in many forms:
f'...', rf"""...""", Fr'''...''', ….
Invoking¶
macro_rules macros have four invocation styles:
macro_name!(input tokens)
macro_name![input tokens]
macro_name!{input tokens}
macro_name!:
input
tokens
Important
Due to the way Python’s tokenizer works, indentation and newlines are only preserved by the last (block) style.