Macros let a grammar defer part of its accepted vocabulary to runtime. Instead of hard-coding every possible value into the grammar, the grammar references a macro name, and the host application supplies the valid choices dynamically.
A macro is a named placeholder in the grammar. Its valid runtime choices come from a resolver registered by the host application.
${available_tasks}
${environmentNames}
${reportTemplates}
The canonical form is ${macroName}. The macro name is matched exactly against the registry. This lookup is case-sensitive.
<available_tasks>
Some environments may still preserve legacy angle-bracket syntax for backward compatibility. Use it only when you need compatibility with older grammars. New definitions should prefer ${...}.
That means ${available_tasks} and ${Available_Tasks} are different macro references, while a registered choice such as full backup may still match user input written as FULL BACKUP.
Macro choices may contain multiple tokens. The engine tokenizes each available choice and compares it against the current input position.
When choices share a prefix, the engine should prefer the longest matching choice in token count. This keeps overlapping choices deterministic.
Registered choices:
- backup
- full backup
- COMPLEX.TASK
Input:
EXECUTE full backup ON db01 ;
A quoted macro choice still binds its normalized semantic value. The outer quotes are not part of the bound value, and doubled apostrophes inside the quoted text become literal apostrophes.
Registered choice: 'COMPLEX.TASK'
Input: EXECUTE 'COMPLEX.TASK' ;
Bound value: COMPLEX.TASK
Macro resolution happens during parsing, not during grammar compilation. This allows the host application to expose a runtime-controlled vocabulary while keeping the grammar structure itself stable.
For a given registry state and input, macro resolution is expected to remain deterministic.
EXECUTE ${available_tasks} ON target_name ;
EXECUTE full backup ON db01 ;
EXECUTE backup ON db01 ;
EXECUTE 'COMPLEX.TASK' ON db01 ;
Use macros when the accepted values belong to a dynamic registry, not when the grammar should expose a stable fixed vocabulary. If the domain language itself is fixed, declare explicit keywords instead.