macro_rules Reference

See also

macro_polo.macros.macro_rules.MacroRulesParserMacro

API reference for the macro_rules declaration parser macro.

macro_polo.match

API reference for the pattern matching machinary used by macro_rules.

macro_polo.transcribe

API 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

A capture variable.

Repeater

$(pattern)? | $(pattern)* | $(pattern)sep* | $(pattern)+ | $(pattern)sep+

A pattern repeater. Matches pattern ≤1 (?), ≥0 (*), or ≥1 (+) times.

If sep is 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 pattern fails to match. If pattern does match, the negative lookahead will fail.

Escape Sequences
$$

Matches a single $ token.

$>

Matches an INDENT token.

$<

Matches a DEDENT token.

$^

Matches a NEWLINE token.

All other tokens are matched exactly (ex: 123 matches a NUMBER token 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:

token

Matches any single token, except delimiters.

name

Matches a NAME token.

op

Matches a OP token, except delimiters.

number

Matches a NUMBER token.

string

Matches a STRING token.

tt

Matches a “token tree”: either a single non-delimiter token, or a pair of (balanced) delimiters and all of the tokens between them.

null

Always 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

$name

A capture variable.

Transcribes 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. If pattern contains multiple repeating substitutions, they must repeat the same number of times (at the current nesting depth).

If sep is present, it is a single-token separator that will be transcribed before each repitition after the first.

Escape Sequences
$$

Transcribes a single $ token.

$>

Transcribes an INDENT token.

$<

Transcribes a DEDENT token.

$^

Transcribes a NEWLINE token.

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.