![]() |
<Syntax Macros> |
[ Macro Syntax | Packages | Overloading | Alpha Conversion | Order of Expansion | Nonterminals | Macro Libraries ]
| package | : req_ext macro |
| req_ext | : require <URL> | require stringconst |
| | extend <URL> | extend stringconst | |
| macro | : syntax <nonterm> id param ::= { body } |
| metamorph <nonterm> id --> param ::= { body } | |
| param | : token |
| | <nonterm id> | |
| | <id: nonterm id> |
A syntax macro has four constituents; a nonterminal result type, an identifier naming the macro, a parameter list specifying the invocation syntax, and a body that must comply with the result type. The body is allowed to contain placeholders corresponding to the formal macro arguments declared in the parameter list. The syntax of a placeholder is <A>, where A is the name of the argument.
A metamorphism has the four constituents: a nonterminal result type, an identifier naming a user defined nonterminal (left-hand side meta grammar production), a parameter list specifying the invocation syntax, and a body that must comply with the result type. The metamorphism body is also allowed to contain placeholders.

Syntax macros: operators on parse trees.
See the macro tutorial for information on how to use the macros.
A package is a file containing macro definitions. A package is viewed as a set of macro definitions. That is, all macro definitions have two pass scope rules (i.e. all definitions are visible to each other and the order is insignificant). A dependency analysis intercepts and rejects cyclic definitions.
A package may require or extend other
packages. Consider a package P that contains a set of macro
definitions M, requires a package R, and extends another package
E. The definitions visible inside the bodies of macros in M are
M
R
E and those that are exported from P are M
E. Thus, require is used for obtaining local
macros.
There is no scoping mechanism for undeclaring a macro.
Macros may be overloaded meaning that two macro definitions the same identifier name but have different invocation syntax (different parameters) and different bodies. However, macros with the same name must have same nonterminal return type.
When there are more than one macro with the same name, we base the invocation selection on the concept of specificity which is independent of the macro definition order. This is done by gradually challenging each parameter list with the input tokens. There are four cases for a challenge:
q defined as
(q)
(p),
where
is:
: param 2TOKEN |
|||
|---|---|---|---|
(token) |
= | {token} | |
(<N id>) |
= | first(N) | ...in the host grammar |
(<M: N a>) |
= | first(M) | ...in the metamorph grammar. |
The tails of the surviving lists are then challenged with the next input token, and so on.
Note that the strategy is greedy, since it prefers to continue with longer parameter lists.
The body of a macro constitutes a closed scope. Free identifiers in a macro body are alpha converted to avoid identifier clashes and shading after the expansion. Alpha conversion can also be supressed using the identifier prefix operator: ` (backping), which only makes sense in the bodies of macro definitions.
The predicate
determines if an identifier will be
-converted:
(`i) = false;
(i~j) =
(i)
(j);
(<i>) = false, if <i> is a macro argument of type id; and
(i) = true, otherwise.
In the presence of nested macro invocations, we expand the innermost first yielding applicative order of reduction. This results in a call-by-value expansion semantics.
The nonterm above can be any of the 55 syntactic categories below:
[ argument | argument_list | attr | attribute | attribute_list | boolconst | charconst | compound_stm | constraint | constraintbody | constraintbody_list | decl | decl_list | defattr | exp | exp_list | field | field_list | floatconst | format | formula | getinput | getinput_list | html | htmlbody | htmlbody_list | identifier | identifier_list | intconst | label | mode | mode_list | modifier | modifier_list | plug | plug_list | regexp | regexp_list | schema | service | session | stm | stm_list | stringconst | switchbranch | switchbranch_list | toplevel | toplevel_list | trigexp | trigger | tupleexp | tupleexp_list | type | waitbranch | waitbranch_list ]
|
bigwig@brics.dk Last updated: November 2, 2001 |
|