.Open Macros Macros are a useful technique for describing languages, and if used correctly leave the complexity of the processor unchanged. . Macros Functions that map sets of strings into sets of strings can be used as macros. If they are not recursive and defined with the same formula as any other definition then they can be removed. They can be treated as 'macros' or abreviations. Even so they are are convenient. Set_of_abreviations::= macro_definition #macro_definition, macro_definition_pack::= "For" #(variable ",") macro_definition #(punctuator, macro_definition), macro_definition::= name "(" bound_symbol #("," bound_symbol)")" "::= " regular_expression(element=>(string|variable)) The expressions in the above may not use macros, etc. macro_reference::= name "(" expression #("," expression)")" There are the same number of expressions in a macro_reference as symbols in the macro_definition. Examples useful for describing languages (See Ada and C) For x, non(x) ::= character~{x}, O(x) ::= (x|), N(x) ::= x #x, P(x) ::= "(" x #(comma x) ")". For x,y, L(x,y) ::= x #(y x). Macros redefined using the above macros and other extensions Set_of_abreviations::= N(macro_definition_pack), macro_definition_pack::= "For" L(variable,",") "," L(macro_definition, punctuator), macro_definition::=name P(variable) "::=" regular_expression(element=>(string|variable)) macro_reference::= name P(expression). It is also possible to include more complex mappings than the context free macros described above. A nice example occurs in most programming languages in the definition of a litteral character string. Coming up with a clear, unambiguous and universal notation is not easier and there have been half-a-dozen solutions proposed [Higman, Chapter ??]. By using the more advanced (non-Chomsky) notations of MATHS many of these can be defined as follows: There is a designated quote character `q` and a partial 1-1 map called 'escaping' (`E`) which associates some of the characters with a unique string. The domain of definition of E are the escapable characters. The image of E are the escape strings. `q` is one of these escapable character. The escape strings are NOT characters. Therefore q is not one of the escape strings (but may be a character in an escape string. Strings are then defined unambiguously by For E:char<>->#char, q:/E(#char), string(q,E) ::= q #( E(char) | char~/E(#char) ) q. In MATHS, q = double_quote, E = q+>backslash!q | backslash +> backslash!backslash. In C, q = double_quote, E(char)==>backslash #char, For x:{q, backslash, ...}, E(x) = backslash!x, E(CR)=backslash!"r", E(HT)=backslash!"t",... In Pascal, q = single_quote, E=(single_quote+>single_quote single_quote). .Close Macros .Open Standard Forms . Macros Examples useful for describing languages (See Ada and C) macro::=@#char->@#char non::macro= character~(_), O::macro= ((_) |), N::nacro= (_) #(_), P::macro= "(" (_) #(comma (_) ) ")". For x,y, L(x,y) ::= x #(y x). For A:@lexeme, R::=map[ x:@#A ] ("(" #( x comma) identifier "=>" x #( comma identifier "=>" x ) ")"), N::=map[ a:@#A ] (a #a). L::=map[ x, y:@#A ] (x #(y x)). P::=map[ a:@#A ] ( "(" L(a, comma) ")" ). . Typical Expression Types POSTFIX::=map[ e, R:@#A ]("("e")"R), PREFIX::=map[ e, R:@#A ] (R"("e")"), LISP_S_expression::=CAMBRIDGE::=map[ e, R:@#A ] ("(" R e")"), RPN::=map[ e, R:@#A ] (e R). UNARY::=map[ a, f:@#A ] ( POSTFIX(a,f) | PREFIX(a,f)), BINARY::=map[ a, b, o:@#A ] ( "(" a o b ")"). INFIX::=map[ a:@#A, o:#A ]( "(" a #(o a) ")" ). BRA-KET::=map[ p:@(A>