General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
|
FunnelWebProducing Specifications
Output Files
outputfile ::= (`@N' | `@O') filename [`=='] `@{' expression `@}' . When processing to obtain the specification, these directives create an output file named filename that contains an expression consisting of text and calls to macros (defined later). Filenames must be unique within a FunnelWeb-file. The `=='-part is optional an can be left out. It is included to pair the same option for macros.
When processing to obtain the documentation, the expression is
printed using the The difference between `@N' and `@O' lies in the way in which the files are treated by Eli. A file extracted by `@O' becomes part of the specification described by the FunnelWeb file, while a file extracted by `@N' does not. Most files should be extracted by `@O'; non-product files, extracted by `@N', are those that are used in the derivation of product components, but are not themselves components of the product. As an example of the use of a non-product file, consider the problem of making keywords case-insensitive but retaining case sensitivity in identifiers (see Making Literal Symbols Case Insensitive of Lexical Analysis). Here is a portion of a FunnelWeb file implementing such a processor:
@O@<nolit.gla@>==@{ identifier: C_IDENTIFIER @} @N@<keyword.gla@>==@{ $[a-z]+ @} @O@<keyword.specs@>==@{ keyword.gla :kwd @} Note that the file `keyword.gla' can not form part of the final product specification. If it did, the specified processor would treat all completely lower case identifiers as comments! Nevertheless, file `keyword.gla' is necessary to specify the representation of the keywords in the grammar so that they can be extracted and processed separately (see Making Literal Symbols Case Insensitive of Lexical Analysis). Thus file `keyword.gla' is extracted by `@N', while the other files are extracted by `@O'.
Extracting Output Files with Eli
Within Eli, the derivation
MacrosA 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 ::= `@$' 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.
By default, a macro must be invoked exactly once by one other
macro or by an output file command. However, if the user uses the 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!
If the text string
Additively defined macros can have parameter lists and Names
Names are used to identify macros and sections. A name consists of a
sequence of from zero to 80 printable characters, including the blank
character. End of line characters are not permitted in names. Names are
case sensitive; two different macros are permitted to have names that
differ in case only. Like free text, names are typeset by FunnelWeb and
are safe from misinterpretation by the target typesetter. For example,
it is quite acceptable to use the macro name
name ::= `@<' name_text `@>' . name_text ::= {ordinary_char / text_special} . Formal Parameter Lists
FunnelWeb allows macros to have up to nine macro parameters, named
Because FunnelWeb parameters have predictable names, the only information that a formal parameter list need convey is how many parameters a macro has. For this reason a formal parameter list takes the form of the highest numbered formal parameter desired, enclosed in parentheses sequences.
formal_parameter_list ::= `@(' formal_parameter `@)' . formal_parameter ::= `@1' / `@2' / `@3' / `@4' / `@5' / `@6' / `@7' / `@8' / `@9' .
Macro CallsA macro call consists of a name optionally followed by an actual parameter list. The number of parameters in the actual parameter list must be the same as the number of formal parameters specified in the definition of the macro. If the macro has no formal parameter list, its call must have no actual parameter list.
macro_call ::= name [actual_parameter_list] . actual_parameter_list ::= `@(' actpar { `@,' actpar } `@)' . actpar ::= expression / ( whitespace `@"' expression `@"' whitespace ) . whitespace ::= {` ' / eol} . FunnelWeb allows parameters to be passed directly, or delimited by special double quotes. Each form is useful under different circumstances. Direct specification is useful where the parameters are short and can be all placed on one line. Double quoted parameters allow whitespace on either side (that is not considered part of the parameter) and are useful for laying out rather messy parameters. Here are examples of the two forms.
@<Generic Loop@>@( @"x:=1;@" @, @"x<=10;@" @, @"print "x=%u, x^2=%u",x,x*x; x:=x+1;@+@" @) @<Colours@>@(red@,green@,blue@,yellow@) As shown, the two forms may be mixed within the same parameter list. Formal parameters can appear in the expressions forming macro bodies in accordance with the syntax rules defined above. A formal parameter expands to the text of the expansion of its corresponding actual parameter. There is nothing preventing a formal parameter being provided as part of an expression that forms an actual parameter. If that happens, the formal parameter is bound to the actual parameter of the calling macro, not the called macro. After the following definitions,
@$@<One@>@(@1@)=@{A walrus in @1 is a walrus in vain.@} @$@<Two@>@(@1@)=@{@<One@>@(S@1n@)@}the call
@<Two@>@(pai@)will result in the expansion
A walrus in Spain is a walrus in vain.
Controlling Macro Expansion
IndentationWhen FunnelWeb expands a macro, it can do so in two ways. First it can treat the text it is processing as a one-dimensional stream of text, and merely insert the body of the macro in place of the macro call. Second, it can treat the text of the macro as a two dimensional object and indent each line of the macro body by the amount that the macro call itself was indented. Consider the following macros.
@$@<Loop Structure@>@{@- i=1; while (i<=N) @<Loop body@> endwhile @} @$@<Loop body@>@{@- a[i]:=0; i:=i+1;@} Under the regime of no indentation the loop structure macro expands to:
i=1; while (i<=N) a[i]:=0; i:=i+1; endwhile Under the regime of blank indentation the loop structure macro expands to:
i=1; while (i<=N) a[i]:=0; i:=i+1; endwhile
The
pragma_indent ::= ps `indentation' s `=' s (`blank' / `none') . s ::= {` '}+ . ps ::= (`@p' / `@P') ` ' . Its two forms look like this:
@p indentation = blank @p indentation = none In the current version of FunnelWeb, the indentation regime is an attribute that is attached to an entire run of Tangle; it is not possible to bind it to particular product files or to particular macros. As a result, it doesn't matter where indentation pragmas occur in the input file or how many there are so long as they are all the same. By default FunnelWeb uses blank indentation.
Output LengthFunnelWeb also keeps an eye on the line lengths of product files and flags all lines longer than a certain limit with error messages. Unlike the maximum input line length, which can vary dynamically throughout the input file, the maximum product file line length remains fixed throughout the generation of all the product files. The maximum product file line length pragma allows this value to be set. If there is more than one such pragma in an input file, the pragmas must all specify the same value.
pragma_moll ::= ps `maximum_output_line_length' s `=' s numorinf . s ::= {` '}+ . ps ::= (`@p' / `@P') ` ' . number ::= { decimal_digit }+ . numorinf ::= number / `infinity' . The default value is 80 characters.
|