X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/ba375a80263cbbc155f66c6046e485d56935e5c6..00d59354c311fb28730b7c9b117b0d91aac092cc:/doc/syntax.tex diff --git a/doc/syntax.tex b/doc/syntax.tex index 6dd5cf7..6c05acc 100644 --- a/doc/syntax.tex +++ b/doc/syntax.tex @@ -51,20 +51,20 @@ could be a token. ::= | "_" - ::= @! + ::= | - ::= "A" | "B" | \dots\ | "Z" -\alt "a" | "b" | \dots\ | "z" -\alt + ::= "A" | "B" | $\cdots$ | "Z" + | "a" | "b" | $\cdots$ | "z" + | ::= "0" | - ::= "1" | "2" $| \ldots |$ "9" + ::= "1" | "2" | $\cdots$ | "9" \end{grammar} The precise definition of @ is left to the function -\textsf{alpha-char-p} in the hosting Lisp system. For portability, -programmers are encouraged to limit themselves to the standard ASCII letters. +@|alpha-char-p| in the hosting Lisp system. For portability, programmers are +encouraged to limit themselves to the standard ASCII letters. There are no reserved words at the lexical level, but the higher-level syntax recognizes certain identifiers as \emph{keywords} in some contexts. There is @@ -80,11 +80,11 @@ level. ::= "'" "'" - ::= any character other than "\\" or "\"" -\alt "\\" + :: "\\" + | any character other than "\\" or "\"" - ::= any character other than "\\" or "'" -\alt "\\" + :: "\\" + | any character other than "\\" or "'" ::= any single character \end{grammar} @@ -96,29 +96,30 @@ and the simple syntax seems adequate. For the sake of future compatibility, the use of character sequences which resemble C escape sequences is discouraged. -\subsubsection{Integer literals} \label{sec:syntax.lex.int} + +\subsection{Integer literals} \label{sec:syntax.lex.int} \begin{grammar} ::= -\alt -\alt -\alt + | + | + | ::= "0" | @^* - ::= "0" @("b"|"B"@) @^+ + ::= "0" @("b" | "B"@) @^+ ::= "0" | "1" - ::= "0" @["o"|"O"@] @^+ + ::= "0" @["o" | "O"@] @^+ - ::= "0" | "1" $| \ldots |$ "7" + ::= "0" | "1" | $\cdots$ | "7" - ::= "0" @("x"|"X"@) @^+ + ::= "0" @("x" | "X"@) @^+ ::= -\alt "A" | "B" | "C" | "D" | "E" | "F" -\alt "a" | "b" | "c" | "d" | "e" | "f" + | "A" | "B" | "C" | "D" | "E" | "F" + | "a" | "b" | "c" | "d" | "e" | "f" \end{grammar} Sod understands only integers, not floating-point numbers; its integer syntax @@ -129,15 +130,16 @@ binary. However, length and signedness indicators are not permitted. \subsection{Punctuation} \label{sec:syntax.lex.punct} \begin{grammar} - ::= any nonalphanumeric character other than "_", "\"" or "'" + ::= "<<" | ">>" | "||" | "&&" + | "<=" | ">=" | "==" | "!=" | "\dots" +\alt any nonalphanumeric character other than "_", "\"", or "'" \end{grammar} \subsection{Comments} \label{sec:syntax.lex.comment} \begin{grammar} - ::= -\alt + ::= | ::= "/*" @@ -189,9 +191,356 @@ during translation. They are read using a simple scanner which nonetheless understands C comments and string and character literals. A C fragment is terminated by one of a small number of delimiter characters -determined by the immediately surrounding context -- usually a closing brace -or bracket. The first such delimiter character which is not enclosed in -brackets, braces or parenthesis ends the fragment. +determined by the immediately surrounding context -- usually some kind of +bracket. The first such delimiter character which is not enclosed in +brackets, braces or parentheses ends the fragment. + +%%%-------------------------------------------------------------------------- +\section{C types} \label{sec:syntax.type} + +Sod's syntax for C types closely mirrors the standard C syntax. A C type has +two parts: a sequence of @s and a @. In +Sod, a type must contain at least one @ (i.e., +`implicit @|int|' is forbidden), and storage-class specifiers are not +recognized. + + +\subsection{Declaration specifiers} \label{sec:syntax.type.declspec} + +\begin{grammar} + ::= +\alt "struct" | "union" | "enum" +\alt "void" | "char" | "int" | "float" | "double" +\alt "short" | "long" +\alt "signed" | "unsigned" +\alt "bool" | "_Bool" +\alt "imaginary" | "_Imaginary" | "complex" | "_Complex" +\alt +\alt +\alt +\alt + + ::= | "const" | "volatile" | "restrict" + + ::= @^+ + + ::= "(" ")" + + ::= "atomic" | "_Atomic" + + ::= "(" ")" + + ::= "alignas" "_Alignas" + + ::= +\end{grammar} + +Declaration specifiers may appear in any order. However, not all +combinations are permitted. A declaration specifier must consist of zero or +more @s, zero or more @s, and one of the +following, up to reordering: +\begin{itemize} +\item @; +\item @; +\item @"struct" @; @"union" @; @"enum" @; +\item @"void"; +\item @"_Bool", @"bool"; +\item @"char"; @"unsigned char"; @"signed char"; +\item @"short", @"signed short", @"short int", @"signed short int"; + @"unsigned short", @"unsigned short int"; +\item @"int", @"signed", @"signed int"; @"unsigned", @"unsigned int"; +\item @"long", @"signed long", @"long int", @"signed long int"; @"unsigned + long", @"unsigned long int"; +\item @"long long", @"signed long long", @"long long int", @"signed long long + int"; @"unsigned long long", @"unsigned long long int"; +\item @"float"; @"double"; @"long double"; +\item @"float _Imaginary", @"float imaginary"; @"double _Imaginary", @"double + imaginary"; @"long double _Imaginary", @"long double imaginary"; +\item @"float _Complex", @"float complex"; @"double _Complex", @"double + complex"; @"long double _Complex", @"long double complex". +\end{itemize} +All of these have their usual C meanings. Groups separated by commas mean +the same thing, and Sod will not preserve the distinction. + +Almost all of these mean the same as they do in C. There are some minor +differences: +\begin{itemize} +\item In C, the `tag' namespace is shared between @|struct|, @|union|, and + @|enum|; Sod has three distinct namespaces for tags. This may be fixed in + the future. +\item The @ production is a syntactic extension point, where + extensions can introduce their own additions to the type system. +\end{itemize} + +C standards from C99 onwards have tended to introduce new keywords beginning +with an underscore followed by an uppercase letter, so as to avoid conflicts +with existing code. More conventional spellings are then provided by macros +in new header files. For example, C99 introduced @"_Bool", and a header file +@|| which defines the macro @|bool|. Sod recognizes both the ugly +underscore names and the more conventional macro names on input, but always +emits the ugly names. This doesn't cause a compatibility problem in Sod, +because Sod's parser recognizes keywords only in the appropriate context. +For example, the (ill-advised) slot declaration +\begin{prog} + bool bool; +\end{prog} +is completely acceptable, and will cause the C structure member +\begin{prog} + \_Bool bool; +\end{prog} +to be emitted on output, which will be acceptable to C as long as +@|| is not included. + +A @ is an identifier which has been declared as being a type name, +using the @"typename" or @"class" definitions. The following type names are +defined in the built-in module. +\begin{itemize} +\item @|va_list| +\item @|size_t| +\item @|ptrdiff_t| +\item @|wchar_t| +\end{itemize} + + +\subsection{Declarators} \label{sec:syntax.type.declarator} + +\begin{grammar} +$[k, a]$ ::= @^* $[k, a]$ + +$[k, a]$ ::= $k$ +\alt "(" $[k, a]$ ")" +\alt $[k, a]$ @$[a]$ + + ::= "*" @^* + +$[a]$ ::= "[" "]" +\alt "(" $a$ ")" + + ::= $\epsilon$ | "\dots" +\alt $[\mbox{@}]$ @["," "\dots"@] + + ::= @^+ + + ::= $[\epsilon, \mbox{@}]$ + + ::= + $[\mbox{@ | $\epsilon$}, \mbox{@}]$ + + ::= + $[\mbox{@}, \mbox{@}]$ +\end{grammar} + +The declarator syntax is taken from C, but with some differences. +\begin{itemize} +\item Array dimensions are uninterpreted @, terminated by a + closing square bracket. This allows array dimensions to contain arbitrary + constant expressions. +\item A declarator may have either a single @ at its centre or a + pair of @s separated by a @`.'; this is used to refer to + slots or messages defined in superclasses. +\end{itemize} +The remaining differences are (I hope) a matter of presentation rather than +substance. + +There is additional syntax to support messages and methods which accept +keyword arguments. + +\begin{grammar} + ::= @["=" @] + + ::= + @[$[\mbox{@}]$@] + "?" @[$[\mbox{@}]$@] + + ::= | + + ::= "." + +$[k]$ ::= + $[k, \mbox{@}]$ +\end{grammar} + +%%%-------------------------------------------------------------------------- +\section{Properties} \label{sec:syntax.prop} + +\begin{grammar} + ::= "[" $[\mbox{@}]$ "]" + + ::= "=" + + ::= + + ::= + | "||" + + ::= + | "&&" + + ::= + | "|" + + ::= + | "^" + + ::= + | "&" + + ::= + | "==" + | "!=" + + ::= + | "<" + | "<=" + | ">=" + | ">" + + ::= + | "<<" + | ">>" + + ::= + | "+" + | "--" + + ::= + | "*" + | "/" + + ::= + | "!" | "~" factor + | "+" | "--" + + ::= + | | | +\alt "<" ">" | "{" "}" | "?" + | "(" ")" +\end{grammar} + +\emph{Property sets} are a means for associating miscellaneous information +with compile-time metaobjects such as modules, classes, messages, methods, +slots, and initializers. By using property sets, additional information can +be passed to extensions without the need to introduce idiosyncratic syntax. +(That said, extensions can add additional first-class syntax, if necessary.) + +An error is reported if an unrecognized property is associated with an +object. + + +\subsection{Property values} \label{sec:syntax.prop.value} + +A property has a name, given as an @, and a value computed by +evaluating an @. The value can be one of a number of types. + +\begin{itemize} + +\item An @ denotes a value of type @|int|. + +\item Similarly @ and @ denote @|string| and + @|char| values respectively. Note that, as properties, characters are + quite distinct from integers, whereas in C, a character literal denotes a + value of type @|int|. + +\item There are no variables in the property-value syntax. Rather, an + @ denotes that identifier, as a value of type @|id|. + +\item A C type (a @, as described in \xref{sec:syntax.type}) + between angle brackets, e.g., @||, or @||, or @||, denotes that C type, as a value of type @|type|. + +\item A @ within braces denotes the tokens between (and not + including) the braces, as a value of type @|c-fragment|. + +\end{itemize} + +As shown in the grammar, there are four binary operators, @"+" (addition), +@"--" (subtraction), @"*" (multiplication), and @"/" (division); +multiplication and division have higher precedence than addition and +subtraction, and operators of the same precedence associate left-to-right. +There are also unary @"+" (no effect) and @"--" (negation) operators, with +higher precedence. All of the above operators act only on integer operands +and yield integer results. (Although the unary @"+" operator yields its +operand unchanged, an error is still reported if it is applied to a +non-integer value.) There are currently no bitwise, logical, or comparison +operators. + +Finally, an S-expression preceded by @|?| causes the expression to be read in +the current package (which is always @|sod-user| at the start of a module) +and immediately evaluated (using @|eval|); the resulting value is converted +into a property value using the \descref{gf}{decode-property}[generic +function]. + + +\subsection{Property output types and coercions} +\label{sec:syntax.prop.coerce} + +When a property value is inspected by the Sod translator, or an extension, it +is \emph{coerced} so as to conform to a requested output type. This coercion +process is performed by the \descref{gf}{coerce-property-value}[generic +function], and additional output types and coercions can be defined by +extensions. The built-in output types coercions, from the value types listed +above, are as follows. + +\begin{itemize} + +\item The output types @|int|, @|string|, @|char|, @|id|, and @|c-fragment| + correspond to the like-named value types described above. No coercions to + these output types are defined for the described value types.\footnote{% + There is a coercion to @|id| from the value type @|symbol|, but it is + only possible to generate a property value of type @|symbol| using Lisp.} + +\item The output type @|type| denotes a C type, as does the value type + @|type|. In addition, a value of type @|id| can be coerced to a C type if + it is the name of a class, a type name explicitly declared by @|typename|, + or it is one of: @|bool|, @|_Bool|, @|void|, @|char|, @|short|, @|int|, + @|signed|, @|unsigned|, @|long|, @|size_t|, @|ptrdiff_t|, @|wchar_t|, + or @|va_list|. + +\item The @|boolean| output type denotes a boolean value, which may be either + true or false. A value of type @|id| is considered true if it is @|true|, + @|t|, @|yes|, @|on|, @|yup|, or @|verily|; or false if it is @|false|, + @|nil|, @|no|, @|off|, @|nope|, or @|nowise|; it is erroneous to provide + any other identifier where a boolean value is wanted. A value of type + @|int| is considered true if it is nonzero, or false if it is zero. + +\item The @|symbol| output type denotes a Lisp symbol. + + A value of type @|id| is coerced to a symbol as follows. First, the + identifier name is subjected to \emph{case inversion}: if all of the + letters in the name have the same case, either upper or lower, then they + are replaced with the corresponding letters in the opposite case, lower or + upper; if the name contains letters of both cases, then it is not changed. + For example, @|foo45| becomes @|FOO45|, or \emph{vice-versa}; but @|Splat| + remains as it is. Second, the name is subjected to \emph{separator + switching}: all underscores in the name are replaced with hyphens (and + \emph{vice-versa}, though hyphens aren't permitted in identifiers in the + first place). Finally, the resulting name is interned in the current + package, which will usually be @|sod-user| unless changed explicitly by the + module. + + A value of type @|string| is coerced to a symbol as follows. If the string + contains no colons, then it is case-inverted (but not separator-switched) + and interned in the current package. Otherwise, the string either has the + form $p @|:| q$, where $q$ does not begin with a colon (the + \emph{single-colon} case) or $p @|::| q$ (the \emph{double-colon} case); + where $p$ does not contain a colon. Both $p$ and $q$ are case-inverted + (but not separator-switched). If $p$ does not name a package, then an + error is reported; as a special case, if $p$ is empty, then it is + considered to name the @|keyword| package. Otherwise, $q$ is looked up as + a symbol name in package~$p$; in the single-colon case, if the symbol is + not an exported symbol in package~$p$, then an error is reported; in the + double-colon case, $q$ is interned in package~$p$ (and so there needn't be + an exported symbol -- or, indeed, and symbol at all -- named $q$ + beforehand). + +\item The @|keyword| output type denotes symbols within the @|keyword| + package. Value of type @|id| or @|string| can be coerced to a @|keyword| + in the same way as to a @|symbol|, as described above, only the converted + name is looked up in the @|keyword| package rather than the current + package. (A @|string| can override this by specifying an explicit package + name, but this is unlikely to be very helpful.) + +\end{itemize} %%%-------------------------------------------------------------------------- \section{Module syntax} \label{sec:syntax.module} @@ -199,16 +548,20 @@ brackets, braces or parenthesis ends the fragment. \begin{grammar} ::= @^* - ::= + ::= \fixme{undefined} +\alt \alt \alt \alt \alt \alt +\alt \fixme{undefined} \end{grammar} -A @ is the top-level syntactic item. A module consists of a sequence -of definitions. +A @ is the top-level syntactic item: a source file presented to Sod +is expected to conform with the @ syntax. + +A module consists of a sequence of definitions. \fixme{describe syntax; expand} Properties: @@ -233,9 +586,9 @@ A search is made for a module source file as follows. \begin{itemize} \item The module name @ is converted into a filename by appending @`.sod', if it has no extension already.\footnote{% - Technically, what happens is \textsf{(merge-pathnames name (make-pathname - :type "SOD" :case :common))}, so exactly what this means varies - according to the host system.} % + Technically, what happens is @|(merge-pathnames name (make-pathname :type + "SOD" :case :common))|, so exactly what this means varies according to + the host system.} % \item The file is looked for relative to the directory containing the importing module. \item If that fails, then the file is looked for in each directory on the @@ -245,7 +598,7 @@ A search is made for a module source file as follows. \end{itemize} At this point, if the file has previously been imported, nothing further happens.\footnote{% - This check is done using \textsf{truename}, so it should see through simple + This check is done using @|truename|, so it should see through simple tricks like symbolic links. However, it may be confused by fancy things like bind mounts and so on.} % @@ -262,23 +615,22 @@ A search is made for a Lisp source file as follows. \begin{itemize} \item The name @ is converted into a filename by appending @`.lisp', if it has no extension already.\footnote{% - Technically, what happens is \textsf{(merge-pathnames name (make-pathname - :type "LISP" :case :common))}, so exactly what this means varies - according to the host system.} % + Technically, what happens is @|(merge-pathnames name (make-pathname :type + "LISP" :case :common))|, so exactly what this means varies according to + the host system.} % \item A search is then made in the same manner as for module imports (\xref{sec:syntax-module}). \end{itemize} -If the file is found, it is loaded using the host Lisp's \textsf{load} -function. +If the file is found, it is loaded using the host Lisp's @|load| function. Note that Sod doesn't attempt to compile Lisp files, or even to look for existing compiled files. The right way to package a substantial extension to the Sod translator is to provide the extension as a standard ASDF system (or similar) and leave a dropping @|foo-extension.lisp| in the module path saying something like -\begin{quote} - \textsf{(asdf:load-system :foo-extension)} -\end{quote} +\begin{prog} + (asdf:load-system :foo-extension) +\end{prog} which will arrange for the extension to be compiled if necessary. (This approach means that the language doesn't need to depend on any @@ -318,14 +670,18 @@ declarations instead. \begin{grammar} ::= - "code" ":" @[@] + "code" ":" @[@] "{" "}" +\alt + "code" ":" ";" + + ::= ::= "[" $[\mbox{@}]$ "]" ::= @^+ - ::= @! "(" @^+ ")" + ::= | "(" @^+ ")" \end{grammar} The @ will be output unchanged to one of the output files. @@ -354,180 +710,25 @@ preprocessor directives in order to declare types and functions for use elsewhere in the generated output files. -\subsection{Property sets} \label{sec:syntax.module.properties} -\begin{grammar} - ::= "[" $[\mbox{@}]$ "]" - - ::= "=" -\end{grammar} +\subsection{Static instance definitions} \label{sec:syntax.module.instance} -Property sets are a means for associating miscellaneous information with -classes and related items. By using property sets, additional information -can be passed to extensions without the need to introduce idiosyncratic -syntax. - -A property has a name, given as an @, and a value computed by -evaluating an @. The value can be one of a number of types, -though the only operators currently defined act on integer values only. - -\subsubsection{The expression evaluator} \begin{grammar} - ::= | "+" | "--" - - ::= | "*" | "/" + ::= + "instance" + @[":" $[\mbox{@}]$@] ";" - ::= | "+" | "--" - - ::= - | | | -\alt "<" ">" -\alt "?" -\alt "(" ")" -\end{grammar} - -The arithmetic expression syntax is simple and standard; there are currently -no bitwise, logical, or comparison operators. - -A @ expression may be a literal or an identifier. Note that -identifiers stand for themselves: they \emph{do not} denote values. For more -fancy expressions, the syntax -\begin{quote} - @"?" @ -\end{quote} -causes the @ to be evaluated using the Lisp \textsf{eval} -function. -%%% FIXME crossref to extension docs - - -\subsection{C types} \label{sec:syntax.module.types} - -Sod's syntax for C types closely mirrors the standard C syntax. A C type has -two parts: a sequence of @s and a @. In -Sod, a type must contain at least one @ (i.e., -`implicit @"int"' is forbidden), and storage-class specifiers are not -recognized. - -\subsubsection{Declaration specifiers} -\begin{grammar} - ::= -\alt "struct" | "union" | "enum" -\alt "void" | "char" | "int" | "float" | "double" -\alt "short" | "long" -\alt "signed" | "unsigned" -\alt "bool" | "_Bool" -\alt "imaginary" | "_Imaginary" | "complex" | "_Complex" -\alt -\alt -\alt - - ::= | "const" | "volatile" | "restrict" - - ::= @^+ - - ::= - "(" ")" - - ::= "atomic" | "_Atomic" - - ::= "(" ")" - - ::= "alignas" "_Alignas" - - ::= + ::= "." "=" \end{grammar} -A @ is an identifier which has been declared as being a type name, -using the @"typename" or @"class" definitions. The following type names are -defined in the built-in module. -\begin{itemize} -\item @"va_list" -\item @"size_t" -\item @"ptrdiff_t" -\item @"wchar_t" -\end{itemize} - -Declaration specifiers may appear in any order. However, not all -combinations are permitted. A declaration specifier must consist of zero or -more @s, zero or more @s, and one of the -following, up to reordering. -\begin{itemize} -\item @ -\item @ -\item @"struct" @, @"union" @, @"enum" @ -\item @"void" -\item @"_Bool", @"bool" -\item @"char", @"unsigned char", @"signed char" -\item @"short", @"unsigned short", @"signed short" -\item @"short int", @"unsigned short int", @"signed short int" -\item @"int", @"unsigned int", @"signed int", @"unsigned", @"signed" -\item @"long", @"unsigned long", @"signed long" -\item @"long int", @"unsigned long int", @"signed long int" -\item @"long long", @"unsigned long long", @"signed long long" -\item @"long long int", @"unsigned long long int", @"signed long long int" -\item @"float", @"double", @"long double" -\item @"float _Imaginary", @"double _Imaginary", @"long double _Imaginary" -\item @"float imaginary", @"double imaginary", @"long double imaginary" -\item @"float _Complex", @"double _Complex", @"long double _Complex" -\item @"float complex", @"double complex", @"long double complex" -\end{itemize} -All of these have their usual C meanings. - -\subsubsection{Declarators} -\begin{grammar} -$[k, a]$ ::= @^* $[k, a]$ - -$[k, a]$ ::= $k$ -\alt "(" $[k, a]$ ")" -\alt $[k, a]$ @$[a]$ - - ::= "*" @^* - -$[a]$ ::= "[" "]" -\alt "(" $a$ ")" - - ::= $\epsilon$ | "\dots" -\alt $[\mbox{@}]$ @["," "\dots"@] - - ::= @^+ - - ::= $[\epsilon, \mbox{@}]$ - - ::= - $[\mbox{@ @! $\epsilon$}, \mbox{@}]$ - - ::= - $[\mbox{@}, \mbox{@}]$ -\end{grammar} - -The declarator syntax is taken from C, but with some differences. -\begin{itemize} -\item Array dimensions are uninterpreted @, terminated by a - closing square bracket. This allows array dimensions to contain arbitrary - constant expressions. -\item A declarator may have either a single @ at its centre or a - pair of @s separated by a @`.'; this is used to refer to - slots or messages defined in superclasses. -\end{itemize} -The remaining differences are (I hope) a matter of presentation rather than -substance. - -There is additional syntax to support messages and methods which accept -keyword arguments. - -\begin{grammar} - ::= @["=" @] - - ::= - @[$[\mbox{@}]$@] - "?" @[$[\mbox{@}]$@] - - ::= @! - - ::= "." - -$[k]$ ::= - $[k, \mbox{@}]$ -\end{grammar} +Properties: +\begin{description} +\item[@"extern"] A boolean flag: if true, then the instance is public, and + will be declared in the output header file; if false (the default), then + the instance is only available to code defined within the module. +\item[@"const"] A boolean flag: if true (the default), then the instance is + read-only, and may end up in write-protected storage at run-time; if false, + then the instance will be writable. +\end{description} \subsection{Class definitions} \label{sec:syntax.module.class} @@ -572,6 +773,7 @@ class Sub: Super \{ \\ \ind \alt \alt \alt +\alt \fixme{undefined} \end{grammar} A full class definition provides a complete description of a class. @@ -585,8 +787,9 @@ The @$[\mbox{@}]$ names the direct superclasses for the new class. It is an error if any of these @s does not name a defined class. The superclass list is required, and must not be empty; listing @|SodObject| as your class's superclass is a good choice if nothing else -seems suitable. It's not possible to define a \emph{root class} in the Sod -language: you must use Lisp to do this, and it's quite involved. +seems suitable. A class with no direct superclasses is called a \emph{root +class}. It is not possible to define a root class in the Sod language: you +must use Lisp to do this, and it's quite involved. The @ provide additional information. The standard class properties are as follows. @@ -721,6 +924,9 @@ Properties: \begin{description} \item[@|message_class|] A symbol naming the Lisp class to use to represent the message. +\item[@|readonly|] A boolean indicating whether the message guarantees not to + modify its receiver. If this is true, the receiver will be declared + @"const". \item[@|combination|] A keyword naming the aggregating method combination to use. \item[@|most_specific|] A keyword, either @`first' or @`last', according to