ASN.1 provides a mechanizm whereby users can extend the notation for
their own use, or for use by others. A user does so by defining one or
more **macros **using the **macro definition notation**. A macro
can be imported and exported just like any type or value definitions. To
the macro user, the macro appears as a new ASN.1 type with its own notation
which can be used wherever a type can be placed, and similarly with value
notation. In case of encoding, the macro is turned into equivalent value
of ASN.1 types, so it can be !!!pokladane!!! as a **delivered value**.
Macros are not used very commonly, so if you a re not very keen on ASN.1,
you can skip this section without loosing too much information.

Each macro has its own reference name. It is like a type reference,
but typed with all caps and followed by keyword `MACRO`. Its borders
are signed with keywords `BEGIN` and `END` and between them
are two sections called **productions** for type and value notation
and optionaly the third one containing the other productions equal to type
definitions. Each production starts with its reference name, first two
are keywords `TYPE NOTATION` and `VALUE NOTATION`:

`MY1STMACRO MACRO ::=`

`BEGIN`

`TYPE NOTATION ::= ...`

`VALUE NOTATION ::= ...`

`...`

`END`

One production consists of its reference name, assignment sign (`::=`)
and one or more alternatives separated by pipe sign (`|`). Each
alternative is a list of items and/or embedded definition and/or name of
the subsidiary productions. Each item has a corresponding character string,
which it recognises, as follows:

"aaaa" | the string of characters "aaaa" excluding the double quotes |

string |
any sequence of characters (delimited by the following item) |

identifier |
a string obeying the rules for identifiers or references |

number |
a string of digits |

empty |
null string (always recognised) |

type |
any string which can be recognised as ASN.1 type notation |

type (typeref) |
as above, but as a side effect of recognition, the type is assigned to the typeref |

value (type) |
any string which can be recognised as ASN.1 value notation for the type |

value (valueref type) |
as above, but as a side effect of recognition, the value is assigned to the valueref |

Items may be separated by spaces and newlines.

Embedded definitions are simply a series of ASN.1 type and value assignments
enclosed within "`<>`". They come into effect at
the point in the alternative where they appear.

So, that' for theory, now let's have a look at some examples. The first
one is macro `POSSIBLE`, which is very strange and probably unusable
in praxis, but demonstrates most of macro possibilities:

`POSSIBLE MACRO ::=`

`BEGIN`

`TYPE NOTATION ::=`

`type(X)`

`<PossibleX :: CHOICE {present X, omitted NULL}>`

`VALUE NOTATION ::=`

`"OMITTED"`

`<VALUE PossibleX ::= omitted NULL> |`

`value (x X)`

`<VALUE PossibleX ::= present x>`

`END`

Before explaining all that happens, let's have these assignments:

`A ::= POSSIBLE SEQUENCE OF INTEGER`

`a1 A ::= OMITTED`

`a2 A ::= {1, 2, 0}`

First of them assignes an A instance of macro `POSSIBLE` with
'parameter' that is a type, values of which possibly can be assined to
a variable in following value notation.

Assignment of `a1` contains string `OMITTED`, that means,
supported value for omitted from macro, which results in assigning `NULL`
to `a1`.

The last assignment contains a sequence of tree numbers, which is valid
for type `SEQUENCE OF INTEGER`. Because as a 'parameter'
of assignment is this sequence, the second branch of `VALUE NOTATION`
is taken and results in assigning this sequence to `a2`.

As you can see, this macro can be easily substituted by:

`A ::= CHOICE {SEQUENCE OF INTEGER, NULL}`

The only diference is that `NULL` must be then assigned to `a1`.

But, here is another example of macro which is more usable. It is taken from standard for Remote Operation.

`OPERATION MACRO ::=`

`BEGIN`

`TYPE NOTATION ::= Argument Result Errors`

`VALUE NOTATION ::= value (VALUE OperationCode)`

`Argument ::= "ARGUMENT" ResultType | empty`

`Result ::= "RESULT" ResultType | empty`

`Errors ::= "ERRORS" "{" ErrorName "}"
| empty`

`ResultType ::= type | empty`

`ErrorNames ::= ErrorList | empty`

`ErrorList ::= Error | ErrorList "," Error`

`Error ::= value (ERROR)`

`END`

`OperationCode ::= INTEGER`

A typical example of the use of this macro is as follows:

`get OPERATION`

`ARGUMENT AttributeType`

`RESULT ArgumentValue`

`ERRORS {noSuchAttribute, accessBarred}`

`::= 5`

The last examle is more funny. At compile time it 'eats' the rest of any module within used until any other macro is reached:

`VOCAIOUS MACRO ::=`

`BEGIN`

`TYPE NOTATION ::= Eat`

`VALUE NOTATION ::= empty`

`Eat ::= "END" | "MACRO" | EatSomething
Eat`

`EatSomething ::= type | identifier | number | Keyword | Special`

`Keyword ::= "NULL" | "TRUE" | "FALSE"
| "PLUS-INFINITY" | "MINUS-INFINITY"`

`Special ::= "::=" | "," | "{" | "}"
| "." | "(" | ")" | "'" string
"'B" | "'" string "'H" | """"
string """"`

`END`