3. Input syntax

  1. 3.1. Basic syntax
  2. 3.2. Sorts
  3. 3.3. Numbers and strings
  4. 3.4. Tokens, tags, alignment tags and labels

3.1. Basic syntax

The basic input syntax is very simple. A construct consists of an identifier followed by a list of arguments, all enclosed in brackets in a Lisp-like fashion. Each argument can be an identifier, a number, a string, a blank, a bar, or another construct. There are further restrictions on this basic syntax, described below.

construct	: ( identifier arglist )

argument	: construct
		| identifier
		| number
		| string
		| blank
		| bar

arglist		: (empty)
		| argument arglist

The construct ( identifier ), with an empty argument list, is equivalent to the identifier argument identifier. The two may be used interchangeably.

3.2. Sorts

Except at the outermost level, which forms a special case discussed below, every construct and argument has an associated sort. This is one of the basic TDF sorts: access, al_tag, alignment, bitfield_variety, bool, callees, error_code, error_treatment, exp, floating_variety, label, nat, ntest, procprops, rounding_mode, shape, signed_nat, string, tag, transfer_mode, variety, tdfint or tdfstring.

Ignoring for the moment the shorthands discussed below, the ways of creating constructs of sort exp say, correspond to the TDF constructs delivering an exp. For example, contents takes a shape and an exp and delivers an exp. Thus:

( contents arg1 arg2 )

where arg1 is an argument of sort shape and arg2 is an argument of sort exp, is a sort-correct construct. Only constructs which are sort correct in this sense are allowed.

As another example, because of the rule concerning constructs with no arguments, both

( true )

and

false

are valid constructs of sort bool.

TDF constructs which take lists of arguments are easily dealt with. For example:

( make_nof arg1 ... argn )

where arg1, ..., argn are all arguments of sort exp, is valid. A vertical bar may be used to indicate the end of a sequence of repeated arguments.

Optional arguments should be entered normally if they are present. Their absence may be indicated by means of a blank (minus sign), or by simply omitting the argument.

The vertical bar and blank should be used whenever the input is potentially ambiguous. Particular care should be taken with apply_proc (which is genuinely ambiguous) and labelled.

The TDF specification should be consulted for a full list of valid TDF constructs and their argument sorts. Alternatively the tnc help facility may be used. The command:

% tnc -help cmd1 ... cmdn

prints sort information on the constructs or sorts cmd1, ..., cmdn. Alternatively:

% tnc -help

prints this information for all constructs. (To obtain help on the sort alignment as opposed to the construct alignment use alignment_sort. This confusion cannot occur elsewhere.)

3.3. Numbers and strings

Numbers can occur in two contexts, as the argument to the TDF constructs make_nat and make_signed_nat. In the former case the number must be positive. The following shorthands are understood by tnc:

number for ( make_nat number )
number for ( make_signed_nat number )

depending on whether a construct of sort nat or signed_nat is expected.

Strings are nominally of sort tdfstring. They are taken to be simple strings (8 bits per character). Multibyte strings (those with other than 8 bits per character) may be represented by means of the multi_string construct. This takes the form:

( multi_string b c1 ... cn )

where b is the number of bits per character and c1, ...,cn are the codes of the characters comprising the string. These multibyte strings cannot be used as external names.

In addition, a simple (8 bit) string can be used as a shorthand for a TDF construct of sort string, as follows:

string for ( make_string string )

3.4. Tokens, tags, alignment tags and labels

In TDF simple tokens, tags, alignment tags and labels are represented by numbers which may, or may not, be associated with external names. In tnc however they are represented by identifiers. This brings the problem of scoping which does not occur in TDF. The rules are that all tokens, tags, alignment tags and labels must be declared before they are used. Externally defined objects have global scope, and the scope of a formal argument in a token definition is the definition body. For those constructs which introduce a local tag or label - for example, identify, make_proc, make_general_proc and variable for tags and conditional, labelled and repeat for labels - the scope of the object is as set out in the TDF specification.

The following shorthands are understood by tnc, according to the argument sort expected:

tag_id for ( make_tag tag_id )
al_tag_id for ( make_al_tag al_tag_id )
label_id for ( make_label label_id )

The syntax for token applications is as follows:

( apply_construct ( token_id arg1 ... argn ) )

where apply_construct is the appropriate TDF token application construct, for example, exp_apply_token for tokens declared to deliver exp's. The token arguments arg1, ..., argn must be of the sorts indicated in the token declaration or definition. For tokens without any arguments the alternative form:

( apply_construct token_id )

is allowed.

The token application above may be abbreviated to:

( token_id arg1 ... argn )

the result sort being known from the token declaration. This in turn may be abbreviated to:

token_id

when there are no token arguments.

Care needs to be taken with these shorthands, as they can lead to confusion, particularly when, due to optional arguments or lists of arguments, tnc is not sure what sort is coming next. The five categories of objects represented by identifiers - TDF constructs, tokens, tags, alignment tags and labels - occupy separate name spaces, but it is a good idea to try to avoid duplication of names.

By default all these shorthands are used by tnc in write mode. If this causes problems, the -V flag should be passed to tnc.