The third category of construct appearing at the highest syntactic level in a FunnelWeb input file is the macro definition. A macro definition binds a unique macro name to a macro body containing an expression consisting of text, calls to other macros, and formal parameters. The syntax for a macro definition is as follows:
macro = ("@O" | "@$") name [formal_parameter_list] ["@Z"] ["@M"] ["==" | "+="] "@{" expression "@}"
The complexity of the macro definition syntax is mostly to enable the user to attach various attributes to the macro.macroattributes If the user chooses @O, then the macro cannot be called, but is instead attached to a product file. If the user chooses @$, then the macro is an ordinary macro definition that is not attached to a file.
By default, a non-file macro must be invoked exactly once by one other macro. Macros that aren't are flagged with errors by the FunnelWeb analyser. However, if the user uses the @Z@Z sequence in the macro definition, the macro is then permitted to be invoked zero times, as well as once. Similarly, if the user uses the @M@M sequence in the macro definition, the macro is permitted to be called many times as well as once. If both @Z and @M are present then the macro is permitted to be invoked zero, one, or many times.
The purpose of enforcing the default exactly one call rule is to flag pieces of code that the user may have defined in a macro but not hooked into the rest of the program. Experience shows that this is a common error. Similarly, it can be dangerous to multiply invoke a macro intended to be invoked only once. For example, it may be dangerous to invoke a scrap of non-idempotent initialization code in two different parts of the main function of a program! However, FunnelWeb will not generate an error if a macro without @M is called by another macro that is called more than once.
If the text string ==== (or nothing) follows the macro name, the expression that follows is the entire text of the macro body. If the text string +=+= follows the macro name, then more than one such definition is allowed (but not required) in the document and the body of the macro consists of the concatenation of all such expressions in the order in which they occur in the input file. Such a macro is said to be additive and is additively defined. Thus a macro body can either be defined in one place using one definition (using ==) or it can be ıdistributed throughout the input file in a sequence of one or more macro definitions (using +=). If neither == and += are present, FunnelWeb assumes a default of ==.
Macros attached to product files cannot be additively defined. Additively defined macros can have parameter lists and @Z and @M attributes, but these must be specified only in the first definition of the macro. However, += must appear in each definition.