From c3c4e63ce48fdf1d9bd62217db8c0f319ffa5a2d Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 20 Sep 2018 11:12:14 +0000 Subject: [PATCH] Adjusted spec to use package syntax, thus eliminating bnf.sty Also fixed many syntax related glitches. Change-Id: I926b93a54ad28d05389a44c969fc2288933f8584 Reviewed-on: https://dart-review.googlesource.com/75580 Reviewed-by: Lasse R.H. Nielsen --- docs/language/dart.sty | 39 +- docs/language/dartLangSpec.tex | 1608 +++++++++++++++----------------- 2 files changed, 789 insertions(+), 858 deletions(-) diff --git a/docs/language/dart.sty b/docs/language/dart.sty index a7e9cb7c26e..d6c265d2947 100644 --- a/docs/language/dart.sty +++ b/docs/language/dart.sty @@ -1,6 +1,5 @@ -\def\code#1{\textsf{#1}} -\def\builtinId#1{\code{\textbf{#1}}} -\def\keyword#1{\code{\textbf{#1}}} +\def\builtinId#1{\textsf{\textbf{#1}}} +\def\keyword#1{\textsf{\textbf{#1}}} \def\metavar#1{\ensuremath{\mathit{#1}}} \def\ABSTRACT{\builtinId{abstract}} @@ -66,20 +65,16 @@ \def\WITH{\keyword{with}} \def\YIELD{\keyword{yield}} +% Used for inline code snippets. +\def\code#1{\texttt{#1}} + % `call` has no special lexical status, so we just use \code{}. \def\CALL{\code{call}} -% Used in regular text to indicate that #1 consists of non-terminals. -%% TODO(eernst): Update to use grammar font when we start using that; -%% at this point we just make it "regular text" using \mbox. -\newcommand{\NonTerminal}[1]{\mbox{#1}} - -% Angle brackets used for operators in grammar context. -\def\lt{\ensuremath{<}} -\def\gt{\ensuremath{>}} - -% A quoted comma as used in the grammar: needs spacing fix. -\newcommand{\gcomma}{\mbox{`,\hspace{-0.1em}'}} +% Define commands for `<<`, `>>`, `>>>` that avoid introducing guillemets. +\def\ltlt{<\mbox <} +\def\gtgt{>\mbox >} +\def\gtgtgt{>\mbox >\mbox >} % Used as line break in the right hand side of a grammar % alternative, that is, when starting a "continuation line". @@ -102,15 +97,15 @@ \newcommand{\Case}[1]{\textbf{Case }$\langle\hspace{0.1em}${#1}$\hspace{0.1em}\rangle$\textbf{.}} \newenvironment{dartCode}[1][!ht] { -% \begin{verbatim}[#1] - \def\@programcr{\@addfield\strut} - \let\\=\@programcr - \relax\@vobeyspaces\obeylines + \def\@programcr{\@addfield\strut}% + \let\\=\@programcr% + \relax\@vobeyspaces\obeylines% + \ttfamily% + \vspace{1em} +}{\vspace{1em}} - \sffamily -}{ - %\end{verbatim} -} +% Used for comments in a code context. +\def\comment#1{\textsf{#1}} % A commonly used name for an identifier \newcommand{\id}{\metavar{id}} diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex index b37d43865e3..e310010c9ca 100644 --- a/docs/language/dartLangSpec.tex +++ b/docs/language/dartLangSpec.tex @@ -1,8 +1,8 @@ \documentclass{article} \usepackage{epsfig} \usepackage{color} +\usepackage{syntax} \usepackage{dart} -\usepackage{bnf} \usepackage{hyperref} \usepackage{lmodern} \usepackage[T1]{fontenc} @@ -263,18 +263,16 @@ An example would be: } \begin{grammar} -{\sf -{\bf AProduction:}AnAlternative; - AnotherAlternative; - OneThing After Another; - ZeroOrMoreThings*; - OneOrMoreThings+; - AnOptionalThing?; - (Some Grouped Things); - \~{}NotAThing; - A\_LEXICAL\_THING - . -} + ::= + \alt + \alt + \alt * + \alt + + \alt ? + \alt ( ) + \alt \~{} + \alt `aTerminal' + \alt \end{grammar} \LMHash{} @@ -624,44 +622,46 @@ If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately Variables are storage locations in memory. \begin{grammar} -{\bf variableDeclaration:}declaredIdentifier (`,' identifier)* - . + ::= (`,' )* -{\bf declaredIdentifier:}metadata finalConstVarOrType identifier - . + ::= -{\bf finalConstVarOrType:}\FINAL{} type?; - \CONST{} type?; - varOrType - . + ::= \FINAL{} ? + \alt \CONST{} ? + \alt -{\bf varOrType:}\VAR{}; - type - . + ::= \VAR{} + \alt -{\bf initializedVariableDeclaration:}declaredIdentifier (`=' expression)? (`,' initializedIdentifier)* - . + ::= + (`=' )? (`,' )* -{\bf initializedIdentifier:}identifier (`=' expression)? - . + ::= (`=' )? -{\bf initializedIdentifierList:}initializedIdentifier (`,' initializedIdentifier)* - . + ::= (`,' )* \end{grammar} \LMHash{} A variable declaration that contains one or more terms of the form -\NonTerminal{initializedIdentifier} +\syntax{} (\commentary{i.e., a declaration that declares two or more variables}) is equivalent to multiple variable declarations declaring the same set of variable names in the same order, +with the same type and modifiers. + +\LMHash{} +An initialized variable declaration that contains one or more terms of the form +\syntax{} +(\commentary{a declaration that declares two or more initialized variables}) +is equivalent to multiple variable declarations declaring +the same set of variable names in the same order, with the same initialization, type, and modifiers. \commentary{ For example, -\code{\VAR{} x = 1, y;} +\code{\VAR{} x, y;} is equivalent to -\code{\VAR{} x = 1; \VAR{} y;} +\code{\VAR{} x; \VAR{} y;} and \code{\STATIC{} \FINAL{} String s1, s2 = "foo";} is equivalent to @@ -673,7 +673,7 @@ In a variable declaration of one of the forms \code{$N$ $v$;} \code{$N$ $v$ = $e$;} where $N$ is derived from -\NonTerminal{metadata finalConstVarOrType}, +\syntax{ }, we say that $v$ is the {\em declaring occurrence} of the identifier. For every identifier which is not a declaring occurrence, we say that it is an {\em referencing occurrence}. @@ -684,7 +684,7 @@ a {\em declaring identifier} respectively an {\em referencing identifier}. In an expression of the form \code{$e$.\id} it is possible that $e$ has static type \DYNAMIC{} and \id{} cannot be associated with any declaration named \id{} at compile-time, -but in this situation \id{} is still an referencing identifier. +but in this situation \id{} is still a referencing identifier. } \LMHash{} @@ -916,22 +916,17 @@ The result of executing the getter method is the value stored in $v$. Functions abstract over executable actions. \begin{grammar} -{\bf functionSignature:}metadata returnType? identifier formalParameterPart - . + ::= ? -{\bf formalParameterPart:}typeParameters? formalParameterList - . + ::= ? -{\bf returnType:}\VOID{}; - type - . + ::= \VOID{} + \alt -{\bf functionBody:}\ASYNC{}? `={\escapegrammar \gt}' expression `{\escapegrammar ;}'; - (\ASYNC{} $|$ \ASYNC* $|$ \SYNC*)? block - . + ::= \ASYNC{}? `=>' `;' + \alt (\ASYNC{} | \ASYNC `*' | \SYNC `*')? -{\bf block:}`\{' statements `\}' - . + ::= `{' `}' \end{grammar} \LMHash{} @@ -950,7 +945,7 @@ The formal parameter part optionally specifies the formal type parameter list of and it always specifies its formal parameter list. A function body is either: \begin{itemize} -\item A block statement (\ref{blocks}) containing the statements (\ref{statements}) executed by the function, optionally marked with one of the modifiers: \ASYNC, \ASYNC* or \SYNC*. +\item A block statement (\ref{blocks}) containing the statements (\ref{statements}) executed by the function, optionally marked with one of the modifiers: \ASYNC, \code{\ASYNC*} or \code{\SYNC*}. \commentary{ Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression. @@ -978,9 +973,9 @@ OR \end{itemize} \LMHash{} -A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \ASYNC* modifier. +A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \code{\ASYNC*} modifier. Otherwise the function is {\em synchronous}. -A function is a {\em generator} if its body is marked with the \SYNC* or \ASYNC* modifier. +A function is a {\em generator} if its body is marked with the \code{\SYNC*} or \code{\ASYNC*} modifier. \commentary{ Whether a function is synchronous or asynchronous is orthogonal to whether it is a generator or not. @@ -991,7 +986,7 @@ Dart also allows both synchronous and asynchronous functions that produce a sing } \LMHash{} -It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached to the body of a setter or constructor. +It is a compile-time error if an \ASYNC, \code{\ASYNC*} or \code{\SYNC*} modifier is attached to the body of a setter or constructor. \rationale{ An asynchronous setter would be of little use, since setters can only be used in the context of an assignment (\ref{assignment}), @@ -1004,15 +999,15 @@ Calling such a beast via \NEW{} would be very confusing. If you need to produce an object asynchronously, use a method. One could allow modifiers for factories. -A factory for \code{Future} could be modified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and a factory for \code{Iterable} could be modified by \SYNC*. +A factory for \code{Future} could be modified by \ASYNC{}, a factory for \code{Stream} could be modified by \code{\ASYNC*} and a factory for \code{Iterable} could be modified by \code{\SYNC*}. No other scenario makes sense because the object returned by the factory would be of the wrong type. This situation is very unusual so it is not worth making an exception to the general rule for constructors in order to allow it. } \LMHash{} It is a compile-time error if the declared return type of a function marked \ASYNC{} is not a supertype of \code{Future<$T$>} for some type $T$. -It is a compile-time error if the declared return type of a function marked \SYNC* is not a supertype of \code{Iterable<$T$>} for some type $T$. -It is a compile-time error if the declared return type of a function marked \ASYNC* is not a supertype of \code{Stream<$T$>} for some type $T$. +It is a compile-time error if the declared return type of a function marked \code{\SYNC*} is not a supertype of \code{Iterable<$T$>} for some type $T$. +It is a compile-time error if the declared return type of a function marked \code{\ASYNC*} is not a supertype of \code{Stream<$T$>} for some type $T$. \subsection{Function Declarations} @@ -1112,27 +1107,22 @@ The body scope of a function $f$ is enclosed in the scope introduced by the form It is a compile-time error if a formal parameter is declared as a constant variable (\ref{variables}). \begin{grammar} -{\bf formalParameterList:}`(' `)'; - `(' normalFormalParameters \gcomma{}? `)'; - `(' normalFormalParameters \gcomma{} optionalFormalParameters `)'; - `(' optionalFormalParameters `)' - . + ::= `(' `)' + \alt `(' `,'? `)' + \alt `(' `,' `)' + \alt `(' `)' -{\bf normalFormalParameters:}normalFormalParameter (\gcomma{} normalFormalParameter)* - . + ::= (`,' )* -{\bf optionalFormalParameters:}optionalPositionalFormalParameters; - namedFormalParameters - . + ::= + \alt -{\bf optionalPositionalFormalParameters:}`[' defaultFormalParameter (\gcomma{} defaultFormalParameter)* \gcomma{}? `]' - . + ::= `[' (`,' )* `,'? `]' -{\bf namedFormalParameters:}`\{' defaultNamedParameter (\gcomma{} defaultNamedParameter)* \gcomma{}? `\}' - . + ::= `{' (`,' )* `,'? `}' \end{grammar} -Formal parameter lists allow an optional trailing comma after the last parameter (\gcomma{}?). +Formal parameter lists allow an optional trailing comma after the last parameter (\syntax{`,'?}). A parameter list with such a trailing comma is equivalent in all ways to the same parameter list without the trailing comma. All parameter lists in this specification are shown without a trailing comma, but the rules and semantics apply equally to the corresponding parameter list with a trailing comma. @@ -1150,21 +1140,17 @@ It is a compile-time error if any default values are specified in the signature \end{itemize} \begin{grammar} -{\bf normalFormalParameter:}functionFormalParameter; - fieldFormalParameter; - simpleFormalParameter - . + ::= + \alt + \alt -{\bf functionFormalParameter:}metadata \COVARIANT{}? returnType? identifier - \gnewline{} formalParameterPart - . + ::= \COVARIANT{}? ? + \gnewline{} -{\bf simpleFormalParameter:}metadata \COVARIANT{}? finalConstVarOrType? identifier; - . + ::= \COVARIANT{}? ? -{\bf fieldFormalParameter:}metadata finalConstVarOrType? \THIS{} `{\escapegrammar .}' identifier - \gnewline{} formalParameterPart? - . + ::= ? \THIS{} `.' + \gnewline{} ? \end{grammar} \LMHash{} @@ -1187,22 +1173,16 @@ It is a compile-time error if the modifier \COVARIANT{} occurs on a parameter of Optional parameters may be specified and provided with default values. \begin{grammar} -{\bf defaultFormalParameter:}normalFormalParameter (`=' expression)? - . + ::= (`=' )? -{\bf defaultNamedParameter:}normalFormalParameter (`=' expression)?; - normalFormalParameter ( `{\escapegrammar :}' expression)? - . + ::= (`=' )? + \alt ( `:' )? \end{grammar} -A {\bf defaultNamedParameter} of the form: -\begin{code} - normalFormalParameter : expression -\end{code} +A \syntax{} of the form +\syntax{ `:' } is equivalent to one of the form: -\begin{code} - normalFormalParameter = expression -\end{code} +\syntax{ `=' }. The colon-syntax is included only for backwards compatibility. It is deprecated and will be removed in a later version of the language specification. @@ -1211,7 +1191,7 @@ It is a compile-time error if the default value of an optional parameter is not If no default is explicitly specified for an optional parameter an implicit default of \NULL{} is provided. \LMHash{} -It is a compile-time error if the name of a named optional parameter begins with an `\_' character. +It is a compile-time error if the name of a named optional parameter begins with an `_' character. \rationale{ The need for this restriction is a direct consequence of the fact that naming and privacy are not orthogonal. @@ -1323,48 +1303,41 @@ A {\em class} defines the form and behavior of a set of objects which are its {\ Classes may be defined by class declarations as described below, or via mixin applications (\ref{mixinApplication}). \begin{grammar} -{\bf classDefinition:}metadata \ABSTRACT{}? \CLASS{} identifier typeParameters? - \gnewline{} superclass? mixins? interfaces? - \gnewline{} `\{' (metadata classMemberDefinition)* `\}'; - metadata \ABSTRACT{}? \CLASS{} mixinApplicationClass - . + ::= \ABSTRACT{}? \CLASS{} ? + \gnewline{} ? ? ? + \gnewline{} `{' ( )* `}' + \alt \ABSTRACT{}? \CLASS{} -{\bf mixins:}\WITH{} typeList - . + ::= \WITH{} -{\bf classMemberDefinition:}declaration `{\escapegrammar ;}' ; - methodSignature functionBody - . + ::= `;' + \alt -{\bf methodSignature:}constructorSignature initializers?; - factoryConstructorSignature; + ::= ? + \alt % This doesn't work: `static @override foo() => 42`, but `functionSignature` starts with metadata. https://github.com/dart-lang/sdk/issues/29614 - \STATIC{}? functionSignature; - \STATIC{}? getterSignature; - \STATIC{}? setterSignature; - operatorSignature - . + \alt \STATIC{}? + \alt \STATIC{}? + \alt \STATIC{}? + \alt -{\bf declaration:}constantConstructorSignature (redirection $|$ initializers)?; - constructorSignature (redirection $|$ initializers)?; - \EXTERNAL{} constantConstructorSignature; - \EXTERNAL{} constructorSignature; - ((\EXTERNAL{} \STATIC{}?))? getterSignature; - ((\EXTERNAL{} \STATIC{}?))? setterSignature; - \EXTERNAL{}? operatorSignature; + ::= ( | )? + \alt ( | )? + \alt \EXTERNAL{} + \alt \EXTERNAL{} + \alt ((\EXTERNAL{} \STATIC{}?))? + \alt ((\EXTERNAL{} \STATIC{}?))? + \alt \EXTERNAL{}? % This doesn't work: `static @override foo() => 42`, but `functionSignature` starts with metadata. https://github.com/dart-lang/sdk/issues/29614 - ((\EXTERNAL{} \STATIC{}?))? functionSignature; - \STATIC{} (\FINAL{} $|$ \CONST{}) type? staticFinalDeclarationList; + \alt ((\EXTERNAL{} \STATIC{}?))? + \alt \STATIC{} (\FINAL{} | \CONST{}) ? % \CONST{} type? staticFinalDeclarationList; - \FINAL{} type? initializedIdentifierList; - (\STATIC{} $|$ \COVARIANT{})? (\VAR{} $|$ type) initializedIdentifierList - . + \alt \FINAL{} ? + \alt (\STATIC{} | \COVARIANT{})? (\VAR{} | ) -{\bf staticFinalDeclarationList:}staticFinalDeclaration (\gcomma{} staticFinalDeclaration)* - . + ::= (`,' )* -{\bf staticFinalDeclaration:}identifier `=' expression - . + ::= `=' \end{grammar} \LMHash{} @@ -1441,13 +1414,13 @@ The rules of inheritance determine what members a class has. \VAR{} j; f(x) => 3; \} - +\\ \CLASS{} B \EXTENDS{} A \{ - int i = 1; // getter i and setter i= override versions from A - \STATIC{} j; // compile-time error: static getter \& setter conflict with - // instance getter \& setter - - /* compile-time error: static method conflicts with instance method */ + int i = 1; // \comment{getter i and setter i= override versions from A} + \STATIC{} j; // \comment{compile-time error: static getter \& setter conflict with} + // \comment{instance getter \& setter} +\\ + // \comment{compile-time error: static method conflicts with instance method} \STATIC{} f(x) => 3; \} \end{dartCode} @@ -1492,68 +1465,118 @@ A method declaration may conflict with other declarations {\em Operators} are instance methods with special names. \begin{grammar} -{\bf operatorSignature:}returnType? \OPERATOR{} operator formalParameterList - . + ::= ? \OPERATOR{} -{\bf operator:}`\~{}'; - binaryOperator; - `[]' ; - `[]=' - . + ::= `~' + \alt + \alt `[]' + \alt `[]=' -{\bf binaryOperator:}multiplicativeOperator; - additiveOperator; - shiftOperator; - relationalOperator; - `=='; - bitwiseOperator - . + ::= + \alt + \alt + \alt + \alt `==' + \alt \end{grammar} \LMHash{} An operator declaration is identified using the built-in identifier (\ref{identifierReference}) \OPERATOR{}. \LMHash{} -The following names are allowed for user-defined operators: \code{<, >, <=, >=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, $>>>$, []=, [], \~{}}. +The following names are allowed for user-defined operators: +\syntax{`<'}, +\syntax{`>'}, +\syntax{`<='}, +\syntax{`>='}, +\syntax{`=='}, +\syntax{`-'}, +\syntax{`+'}, +\syntax{`/'}, +\syntax{`~'}, +\syntax{`*'}, +\syntax{`\%'}, +\syntax{`|'}, +\syntax{`^'}, +\syntax{`\&'}, +\syntax{`\ltlt'}, +\syntax{`\gtgt'}, +\syntax{`\gtgtgt'}, +\syntax{`[]='}, +\syntax{`[]'}, +\syntax{`~'}. \LMHash{} -It is a compile-time error if the arity of the user-declared operator \code{[]=} is not 2. -It is a compile-time error if the arity of a user-declared operator with one of the names: \code{<, >, <=, >=, ==, -, +, \~{}/, /, *, \%, $|$, \^{}, \&, $<<$, $>>$, $>>>$, []} is not 1. -It is a compile-time error if the arity of the user-declared operator \code{-} is not 0 or 1. +It is a compile-time error if the arity of the user-declared operator +\syntax{`[]='} is not 2. +It is a compile-time error if the arity of a user-declared operator with one of the names: +\syntax{`<'}, +\syntax{`>'}, +\syntax{`<='}, +\syntax{`>='}, +\syntax{`=='}, +\syntax{`-'}, +\syntax{`+'}, +\syntax{`~/'}, +\syntax{`/'}, +\syntax{`*'}, +\syntax{`\%'}, +\syntax{`|'}, +\syntax{`^'}, +\syntax{`\&'}, +\syntax{`\ltlt'}, +\syntax{`\gtgt'}, +\syntax{`\gtgtgt'}, +\syntax{`[]'} +is not 1. +It is a compile-time error if the arity of the user-declared operator +\syntax{`-'} +is not 0 or 1. \commentary{ -The \code{-} operator is unique in that two overloaded versions are permitted. +The \syntax{`-'} operator is unique +in that two overloaded versions are permitted. If the operator has no arguments, it denotes unary minus. If it has an argument, it denotes binary subtraction. } \LMHash{} -The name of the unary operator \code{-} is \code{unary-}. +The name of the unary operator \syntax{`-'} is \code{unary-}. \rationale{ This device allows the two methods to be distinguished for purposes of method lookup, override and reflection. } \LMHash{} -It is a compile-time error if the arity of the user-declared operator \code{\~{}} is not 0. +It is a compile-time error if the arity of the user-declared operator +\syntax{`~'} +is not 0. \LMHash{} It is a compile-time error to declare an optional parameter in an operator. \LMHash{} -It is a compile-time error if the return type of a user-declared operator \code{[]=} is explicitly declared and not \VOID{}. +It is a compile-time error if the return type of a user-declared operator +\syntax{`[]='} +is explicitly declared and not \VOID{}. \commentary{ -If no return type is specified for a user-declared operator \code{[]=}, its return type is \VOID{} (\ref{typeOfAFunction}). +If no return type is specified for a user-declared operator +\syntax{`[]='}, +its return type is \VOID{} (\ref{typeOfAFunction}). } \rationale{ The return type is \VOID{} because -a return statement in an implementation of operator \code{[]=} does not return a value. +a return statement in an implementation of operator +\syntax{`[]='} +does not return a value. Consider a non-throwing evaluation of an expression $e$ of the form \code{$e_1$[$e_2$] = $e_3$}, and assume that the evaluation of $e_3$ yields an instance $o$. $e$ will then evaluate to $o$, -and even if the executed body of operator \code{[]=} completes with a value $o'$, +and even if the executed body of operator +\syntax{`[]='} +completes with a value $o'$, that is, if $o'$ is returned, that value is simply ignored. The rationale for this behavior is that assignments should be guaranteed to evaluate to the assigned value. } @@ -1566,8 +1589,7 @@ The rationale for this behavior is that assignments should be guaranteed to eval Getters are functions (\ref{functions}) that are used to retrieve the values of object properties. \begin{grammar} -{\bf getterSignature:}returnType? \GET{} identifier - . + ::= ? \GET{} \end{grammar} \LMHash{} @@ -1602,8 +1624,7 @@ and the return type of $m_1$ is not a subtype of the return type of $m_2$. Setters are functions (\ref{functions}) that are used to set the values of object properties. \begin{grammar} -{\bf setterSignature:}returnType? \SET{} identifier formalParameterList - . + ::= ? \SET{} \end{grammar} \commentary{ @@ -1692,16 +1713,16 @@ However, code like the following should work: } \begin{dartCode} - class Base \{ - int get one => 1; - \} - - abstract class Mix \{ - int get one; - int get two => one + one; - \} - - class C extends Base with Mix \{ \} +class Base \{ + int get one => 1; +\} +\\ +\ABSTRACT{} \CLASS{} Mix \{ + int get one; + int get two => one + one; +\} +\\ +\CLASS{} C extends Base with Mix \{ \} \end{dartCode} \rationale{ @@ -1781,8 +1802,7 @@ If{}f no constructor is specified for a class $C$, it implicitly has a default c A {\em generative constructor} consists of a constructor name, a constructor parameter list, and either a redirect clause or an initializer list and an optional body. \begin{grammar} -{\bf constructorSignature:}identifier (`{\escapegrammar .}' identifier)? formalParameterList - . + ::= (`.' )? \end{grammar} \LMHash{} @@ -1858,8 +1878,7 @@ A redirecting constructor has no body; instead, it has a redirect clause that specifies which constructor the invocation is redirected to, and with which arguments. \begin{grammar} -{\bf redirection:}`{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments - . + ::= `:' \THIS{} (`.' )? \end{grammar} \def\ConstMetavar{\mbox{\CONST{}?}} @@ -1942,17 +1961,14 @@ Execution of the superinitializer causes the initializer list of the superconstr } \begin{grammar} -{\bf initializers:}`{\escapegrammar :}' initializerListEntry (\gcomma{} initializerListEntry)* - . + ::= `:' (`,' )* -{\bf initializerListEntry:}\SUPER{} arguments; - \SUPER{} `{\escapegrammar .}' identifier arguments; - fieldInitializer; - assertion - . + ::= \SUPER{} + \alt \SUPER{} `.' + \alt + \alt -{\bf fieldInitializer:}(\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression cascadeSection* - . + ::= (\THIS{} `.')? `=' * \end{grammar} \LMHash{} @@ -2053,7 +2069,8 @@ Execution then proceeds as follows: \LMHash{} The instance variable declarations of the immediately enclosing class are visited in the order they appear in the program text. -For each such declaration $d$, if $d$ has the form \code{\metavar{finalConstVarOrType} $v$ = $e$; } +For each such declaration $d$, if $d$ has the form +\code{\syntax{finalConstVarOrType} $v$ = $e$; } then $e$ is evaluated to an object $o$ and the instance variable $v$ of $i$ is bound to $o$. @@ -2151,8 +2168,7 @@ and the formal type parameters of $S$ are bound to $u_1, \ldots, u_p$. A {\em factory} is a constructor prefaced by the built-in identifier (\ref{identifierReference}) \FACTORY{}. \begin{grammar} -{\bf factoryConstructorSignature:}\FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalParameterList - . + ::= \FACTORY{} (`.' )? \end{grammar} %The enclosing scope of a factory constructor is the static scope \ref{} of the class in which it is declared. @@ -2186,9 +2202,8 @@ Likewise, factories can return instances of different classes. A {\em redirecting factory constructor} specifies a call to a constructor of another class that is to be used whenever the redirecting constructor is called. \begin{grammar} -{\bf redirectingFactoryConstructorSignature:}\CONST{}? \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalParameterList - \gnewline{} `=' type (`{\escapegrammar .}' identifier)? - . + ::= \CONST{}? \FACTORY{} (`.' )? + \gnewline{} `=' (`.' )? \end{grammar} Assume that @@ -2202,7 +2217,7 @@ then consider a declaration of a redirecting factory constructor $k$ of one of t \begin{dartCode} $\ConstMetavar$ \FACTORY{} $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1} = d_1 \ldots,\ T_{n+k}\ x_{n+k} = d_k$]) = $R$; - +\\ $\ConstMetavar$ \FACTORY{} $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1} = d_1 \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) = $R$; \end{dartCode} @@ -2360,8 +2375,7 @@ A {\em constant constructor} may be used to create compile-time constant (\ref{c A constant constructor is prefixed by the reserved word \CONST{}. \begin{grammar} -{\bf constantConstructorSignature:}\CONST{} qualified formalParameterList - . + ::= \CONST{} \end{grammar} %\commentary{Spell out subtleties: a constant constructor call within the initializer of a constant constructor is treated as a ordinary constructor call (a new), because the arguments cannot be assumed constant anymore. In practice, this means two versions are compiled and analyzed. One for new and one for const.} @@ -2445,9 +2459,9 @@ However, the following constructors are disallowed: \begin{dartCode} \CLASS{} D \{ \FINAL{} w; - \CONST{} D.makeList(p): w = \CONST{} [p]; // compile-time error - \CONST{} D.makeMap(p): w = \CONST{} \{``help'': q\}; // compile-time error - \CONST{} D.makeC(p): w = \CONST{} C(p, 12); // compile-time error + \CONST{} D.makeList(p): w = \CONST{} [p]; // \comment{compile-time error} + \CONST{} D.makeMap(p): w = \CONST{} \{``help'': q\}; // \comment{compile-time error} + \CONST{} D.makeC(p): w = \CONST{} C(p, 12); // \comment{compile-time error} \} \end{dartCode} @@ -2528,8 +2542,7 @@ If no \EXTENDS{} clause is specified, then either: It is a compile-time error to specify an \EXTENDS{} clause for class \code{Object}. \begin{grammar} -{\bf superclass:}\EXTENDS{} type - . + ::= \EXTENDS{} \end{grammar} %The superclass clause of a class C is processed within the enclosing scope of the static scope of C. @@ -2554,10 +2567,9 @@ The following code is therefore illegal and should cause a compile-time error: \begin{dartCode} class T \{\} - +\\ /* Compilation error: Attempt to subclass a type parameter */ class G extends T \{\} - \end{dartCode} \LMHash{} @@ -2766,8 +2778,7 @@ A class has a set of direct superinterfaces. This set includes the interface of its superclass and the interfaces specified in the \IMPLEMENTS{} clause of the class. \begin{grammar} -{\bf interfaces:}\IMPLEMENTS{} typeList - . + ::= \IMPLEMENTS{} \end{grammar} \LMHash{} @@ -2966,11 +2977,9 @@ a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}), or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}). \begin{grammar} -{\bf mixinApplicationClass:}identifier typeParameters? `=' mixinApplication `{\escapegrammar ;}' - . + ::= ? `=' `;' -{\bf mixinApplication:}type mixins interfaces? - . + ::= ? \end{grammar} \LMHash{} @@ -2996,6 +3005,7 @@ Let $N_C$ be the name of the mixin application class $C$, let $S$ be the superclass of $C$, and let $S_N$ be the name of $S$. For each generative constructor of the form \code{$S_q$($T_{1}$ $a_{1}$, $\ldots$, $T_{k}$ $a_{k}$)} of $S$ that is accessible to $L_C$, $C$ has an implicitly declared constructor of the form + \begin{dartCode} $C_q$($T_{1}$ $a_{1}$, \ldots, $T_{k}$ $a_{k}$):$\SUPER_q$($a_{1}$, $\ldots$, $a_{k}$); \end{dartCode} @@ -3009,6 +3019,7 @@ fields, $C_q$ is also a const constructor. \LMHash{} For each generative constructor of the form \code{$S_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, [$T_{k+1}$ $a_{k+1}$ = $d_1$, \ldots , $T_{k+p}$ $a_{k+p}$ = $d_p$])} of $S$ that is accessible to $L_C$, $C$ has an implicitly declared constructor of the form + \begin{dartCode} $C_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, [$T_{k+1}$ $a_{k+1}$ = $d'_{1}$, \ldots , $T_{k+p}$ $a_{k+p}$ = $d'_p$]) : $\SUPER_q$($a_{1}$, \ldots , $a_{k}$, $a_{k+1}$, \ldots, $a_p$); @@ -3125,28 +3136,26 @@ For any non-generic declaration, the corresponding type parameters may be elided An {\em enumerated type}, or {\em enum}, is used to represent a fixed number of constant values. \begin{grammar} -{\bf enumType:}metadata \ENUM{} identifier - \gnewline{} `\{' enumEntry (\gcomma{} enumEntry)* (\gcomma{})? `\}' - . + ::= \ENUM{} + \gnewline{} `{' (`,' )* (`,')? `}' -{\bf enumEntry:}metadata identifier - . + ::= \end{grammar} \LMHash{} The declaration of an enum of the form -\code{$m$ \ENUM{} E \{$m_0\,\,\id_0, \ldots,\ m_{n-1}\,\,\id_{n-1}$\}} +\code{$m$ \ENUM{} $E$ \{$m_0\,\,\id_0, \ldots,\ m_{n-1}\,\,\id_{n-1}$\}} has the same effect as a class declaration \begin{dartCode} -$m$ \CLASS{} E \{ +$m$ \CLASS{} $E$ \{ \FINAL{} int index; - \CONST{} E(\THIS{}.index); - $m_0$ \STATIC{} \CONST{} E id$_0$ = \CONST{} E(0); + \CONST{} $E$(\THIS{}.index); + $m_0$ \STATIC{} \CONST{} $E$ $\id_0$ = \CONST{} $E$(0); $\ldots$ - $m_{n-1}$ \STATIC{} \CONST{} E id$_{n-1}$ = const E(n - 1); - \STATIC{} \CONST{} List values = const [\id$_0, \ldots, $ \id$_{n-1}$]; - String toString() => \{ 0: `E.\id$_0$', $\ldots$, n-1: `E.\id$_{n-1}$'\}[index] + $m_{n-1}$ \STATIC{} \CONST{} $E$ $\id_{n-1}$ = const $E$(n - 1); + \STATIC{} \CONST{} List<$E$> values = const <$E$>[\id$_0, \ldots, $ \id$_{n-1}$]; + String toString() => \{ 0: `$E$.\id$_0$', $\ldots$, n-1: `$E$.\id$_{n-1}$'\}[index] \} \end{dartCode} @@ -3258,11 +3267,9 @@ where each formal type parameter has been replaced by the corresponding actual t } \begin{grammar} -{\bf typeParameter:}metadata identifier (\EXTENDS{} type)? - . + ::= (\EXTENDS{} )? -{\bf typeParameters:}`<' typeParameter (\gcomma{} typeParameter)* `>' - . + ::= `<' (`,' )* `>' \end{grammar} \LMHash{} @@ -3302,10 +3309,10 @@ This enables typechecking code such as: \begin{dartCode} \CLASS{} Ordered \{ - operator > (T x); + operator >(T x); \} -\CLASS{} Sorter>$ \{ +\CLASS{} Sorter l) {... l[n] < l[n+1] ...} \} @@ -3651,7 +3658,7 @@ function applications involving other types. Here is an example: \CLASS{} A \{ X x; \} - +\\ A a; \end{dartCode} @@ -3723,8 +3730,7 @@ of expressions whose type proceeds beyond the given finite unfolding. Dart supports metadata which is used to attach user defined annotations to program structures. \begin{grammar} -{\bf metadata:}(`@' qualified ({\escapegrammar `.'} identifier)? (arguments)?)* - . + ::= (`@' (`.' )? ()?)* \end{grammar} \LMHash{} @@ -3789,31 +3795,25 @@ and the evaluation of the other expression throws an exception and a stack trace the evaluation of $e$ stops at that point and throws the same exception object and stack trace. \begin{grammar} -{\bf expression:}assignableExpression assignmentOperator expression; - conditionalExpression cascadeSection*; - throwExpression - . + ::= + \alt * + \alt -{\bf expressionWithoutCascade:}assignableExpression assignmentOperator - \gnewline{} expressionWithoutCascade; - conditionalExpression; - throwExpressionWithoutCascade - . + ::= + \gnewline{} + \alt + \alt -{\bf expressionList:}expression (\gcomma{} expression)* - . -\end{grammar} + ::= (`,' )* -\begin{grammar} -{\bf primary:}thisExpression; - \SUPER{} unconditionalAssignableSelector; - functionExpression; - literal; - identifier; - newExpression; - constObjectExpression; - `(' expression `)' - . + ::= + \alt \SUPER{} + \alt + \alt + \alt + \alt + \alt + \alt `(' `)' \end{grammar} \LMHash{} @@ -3897,13 +3897,13 @@ For example, If C is a class or typedef, C is a constant, and if C is imported w \item A simple or qualified identifier denoting a top-level function (\ref{functions}) or a static method (\ref{staticMethods}) that is not qualified by a deferred prefix. \item A parenthesized expression \code{($e$)} where $e$ is a constant expression. \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $e_2$ are constant expressions and \code{identical()} is statically bound to the predefined dart function \code{identical()} discussed above (\ref{objectIdentity}). -\item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ != $e_2$} where $e_1$ and $e_2$ are constant expressions, and either both evaluate to a numeric, string or boolean value, or at least one of $e_1$ or $e_2$ evaluates to the null object (\ref{null}). -\item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or \code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a boolean value. -\item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \& $e_2$}, $e_1 | e_2$, $e_1 << e_2$, $e_1 >> e_2$ or $e_1 >>> e_2$, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to an integer value or to the null object (\ref{null}). -\item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numeric or string value or to the null object (\ref{null}). -\item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$}, \code{$e_1 > e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ >= $e_2$}, \code{$e_1$ <= $e_2$} or \code{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a numeric value or to the null object (\ref{null}). -\item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $e_3$ are constant expressions and $e_1$ evaluates to a boolean value. -\item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are constant expressions. +\item An expression of one of the forms \code{$e_1$\,==\,$e_2$} or \code{$e_1$\,!=\,$e_2$} where $e_1$ and $e_2$ are constant expressions, and either both evaluate to a numeric, string or boolean value, or at least one of $e_1$ or $e_2$ evaluates to the null object (\ref{null}). +\item An expression of one of the forms \code{!$e$}, \code{$e_1$\,\&\&\,$e_2$} or \code{$e_1$\,||\,$e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a boolean value. +\item An expression of one of the forms \code{\~{}$e$}, \code{$e_1$\,\^\,$e_2$}, \code{$e_1$\,\&\,$e_2$}, \code{$e_1$\,|\,$e_2$}, \code{$e_1$\,<\mbox<\,$e_2$}, \code{$e_1$\,\gtgt\,$e_2$} or \code{$e_1$\,\gtgtgt\,$e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to an integer value or to the null object (\ref{null}). +\item An expression of the form \code{$e_1$\,+\,$e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numeric or string value or to the null object (\ref{null}). +\item An expression of one of the forms \code{-$e$}, \code{$e_1$\,-\,$e_2$}, \code{$e_1$\,*\,$e_2$}, \code{$e_1$\,/\,$e_2$,} \code{$e_1$\,\~{}/\,$e_2$}, \code{$e_1$\,>\,$e_2$}, \code{$e_1$\,<\,$e_2$}, \code{$e_1$\,>=\,$e_2$}, \code{$e_1$\,<=\,$e_2$} or \code{$e_1$\,\%\,$e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a numeric value or to the null object (\ref{null}). +\item An expression of the form \code{$e_1$\,?\,$e_2$\,:\,$e3$} where $e_1$, $e_2$ and $e_3$ are constant expressions and $e_1$ evaluates to a boolean value. +\item An expression of the form \code{$e_1$\,??\,$e_2$} where $e_1$ and $e_2$ are constant expressions. \item An expression of the form \code{$e$.length} where $e$ is a constant expression that evaluates to a string value. \end{itemize} @@ -3928,18 +3928,18 @@ On the other hand, since implementations are free to compile code late, some com } \begin{dartCode} -\CONST{} x = 1 ~/ 0; -\FINAL{} y = 1 ~/ 0; - +\CONST{} x = 1 \~{}/ 0; +\FINAL{} y = 1 \~{}/ 0; +\\ \CLASS{} K \{ m1() \{ - \VAR{} z = \FALSE{}; - \IF{} (z) \{\RETURN{} x; \} + \VAR{} z = \FALSE{}; + \IF{} (z) \{ \RETURN{} x; \} \ELSE{} \{ \RETURN{} 2; \} \} - +\\ m2() \{ - \IF{} (\TRUE{}) \{\RETURN{} y; \} + \IF{} (\TRUE{}) \{ \RETURN{} y; \} \ELSE{} \{ \RETURN{} 3; \} \} \} @@ -3971,12 +3971,12 @@ We can evaluate it at compile time. } \rationale{ -One might reasonably ask why $e_1? e_1: e_3$ and $e_1?? e_2$ have constant forms. -For example, if $e_1$ is known statically, why do we need to test it?. +One might reasonably ask why $e_1$\,?\,$e_1$\,:\,$e_3$ and $e_1$\,??\,$e_2$ have constant forms. +For example, if $e_1$ is known statically, why do we need to test it? The answer is that there are contexts where $e_1$ is a variable. In particular, constant constructor initializers such as -\code{\CONST{} C(foo) : \THIS.foo = foo ?? someDefaultValue;} +\code{\CONST{} C(foo): \THIS.foo = foo ?? someDefaultValue;} } \LMHash{} @@ -3987,22 +3987,21 @@ As an example, consider: } \begin{dartCode} -\CLASS{} CircularConsts\{ -// Illegal program - mutually recursive compile-time constants - \STATIC{} \CONST{} i = j; // a compile-time constant - \STATIC{} \CONST{} j = i; // a compile-time constant +\CLASS{} CircularConsts \{ + // \comment{Illegal program - mutually recursive compile-time constants} + \STATIC{} \CONST{} i = j; // \comment{a compile-time constant} + \STATIC{} \CONST{} j = i; // \comment{a compile-time constant} \} \end{dartCode} \begin{grammar} -{\bf literal:}nullLiteral; - booleanLiteral; - numericLiteral; - stringLiteral; - symbolLiteral; - mapLiteral; - listLiteral - . + ::= + \alt + \alt + \alt + \alt + \alt + \alt \end{grammar} @@ -4013,8 +4012,7 @@ As an example, consider: The reserved word \NULL{} evaluates to the {\em null object}. \begin{grammar} -{\bf nullLiteral:}\NULL{} - . + ::= \NULL{} \end{grammar} \LMHash{} @@ -4034,25 +4032,20 @@ The static type of \NULL{} is the \code{Null} type. A {\em numeric literal} is either a decimal or hexadecimal numeral representing an integer value, or a decimal double representation. \begin{grammar} -{\bf numericLiteral:}NUMBER; - HEX\_NUMBER - . + ::= + \alt -{\bf NUMBER:}DIGIT+ (`{\escapegrammar.}' DIGIT+)? EXPONENT?; - {`\escapegrammar .}' DIGIT+ EXPONENT? - . + ::= + (`.' +)? ? + \alt `.' + ? -{\bf EXPONENT:}(`e' $|$ `E') (`+' $|$ `-')? DIGIT+ - . + ::= (`e' | `E') (`+' | `-')? + -{\bf HEX\_NUMBER:}`0x' HEX\_DIGIT+; - `0X' HEX\_DIGIT+ - . + ::= `0x' + + \alt `0X' + -{\bf HEX\_DIGIT:}`a'{\escapegrammar ..}`f'; - `A'{\escapegrammar ..}`F'; - DIGIT - . + ::= `a' .. `f' + \alt `A' .. `F' + \alt \end{grammar} \LMHash{} @@ -4091,7 +4084,7 @@ and $l$ is not the operand of a unary minus operator, then evaluation of $l$ proceeds as follows: \begin{itemize} \item{} If $l$ is a hexadecimal integer literal, - $2^{63} \le{} i \lt{} 2^{64}$ and the \code{int} class is implemented as + $2^{63} \le i < 2^{64}$ and the \code{int} class is implemented as signed 64-bit two's complement integers, then $l$ evaluates to an instance of the \code{int} class representing the numeric value $i - 2^{64}$, @@ -4145,9 +4138,8 @@ The reserved words \TRUE{} and \FALSE{} evaluate to objects {\em true} and {\em They are the {\em boolean literals}. \begin{grammar} -{\bf booleanLiteral:}\TRUE{}; - \FALSE{} - . + ::= \TRUE{} + \alt \FALSE{} \end{grammar} \LMHash{} @@ -4173,19 +4165,17 @@ Programmers should not depend on this distinction. } \begin{grammar} -{\bf stringLiteral:}(multilineString $|$ singleLineString)+ - . + ::= ( | )+ \end{grammar} \LMHash{} A string can be a sequence of single line strings and multiline strings. \begin{grammar} -{\bf singleLineString:}`{\escapegrammar \code{"}}' stringContentDQ* `{\escapegrammar \code{"}}'; - `{\escapegrammar \code{'}}' stringContentSQ* `{\escapegrammar \code{'}}'; - `r{\escapegrammar \code{'}}' (\~{}( `{\escapegrammar \code{'}}' $|$ NEWLINE ))* `{\escapegrammar \code{'}}'; - `r{\escapegrammar \code{"}}' (\~{}( `{\escapegrammar \code{"}}' $|$ NEWLINE ))* `{\escapegrammar \code{"}}' - . + ::= `"' * `"' + \alt `\'' * `\'' + \alt `r\'' (\~{}( `\'' | ))* `\'' + \alt `r"' (\~{}( `"' | ))* `"' \end{grammar} \LMHash{} @@ -4208,7 +4198,7 @@ Here is an example } \begin{dartCode} -print("A string" "and then another"); // prints: A stringand then another +print("A string" "and then another"); // \comment{A stringand then another} \end{dartCode} \rationale{ @@ -4249,31 +4239,28 @@ This can be expressed by writing smaller strings separated by whitespace, as sho \end{dartCode} \begin{grammar} -{\bf multilineString:}`{\escapegrammar \texttt{"""}}' stringContentTDQ* `{\escapegrammar \texttt{"""}}'; - `{\escapegrammar \code{'}\code{'}\code{'}}' stringContentTSQ* `{\escapegrammar \code{'}\code{'}\code{'}}'; - `r{\escapegrammar \texttt{"""}}' (\~{} `{\escapegrammar \texttt{"""}}')* `{\escapegrammar \texttt{"""}}'; - `r{\escapegrammar \code{'}\code{'}\code{'}}' (\~{} `{\escapegrammar \code{'}\code{'}\code{'}}')* `{\escapegrammar \code{'}\code{'}\code{'}}' - . + ::= `"""' * `"""' + \alt `\'\mbox\'\mbox\'' * `\'\mbox\'\mbox\'' + \alt `r"""' (\~{} `"""')* `"""' + \alt `r\'\mbox\'\mbox\'' (\~{} `\'\mbox\'\mbox\'')* `\'\mbox\'\mbox\'' -{\bf ESCAPE\_SEQUENCE:}`$\backslash$n'; - `$\backslash$r'; - `$\backslash$f'; - `$\backslash$b'; - `$\backslash$t'; - `$\backslash$v'; - `$\backslash$x' HEX\_DIGIT HEX\_DIGIT; - `$\backslash$u' HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT; - `$\backslash$u\{' HEX\_DIGIT\_SEQUENCE `\}' - . + ::= `\\n' + \alt `\\r' + \alt `\\f' + \alt `\\b' + \alt `\\t' + \alt `\\v' + \alt `\\x' + \alt `\\u' + \alt `\\u{' `}' -{\bf HEX\_DIGIT\_SEQUENCE:}HEX\_DIGIT HEX\_DIGIT? HEX\_DIGIT? - \gnewline{} HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? - . + ::= ? ? + \gnewline{} ? ? ? \end{grammar} \LMHash{} Multiline strings are delimited by either matching triples of single quotes or matching triples of double quotes. -If the first line of a multiline string consists solely of the whitespace characters defined by the production {\em WHITESPACE} (\ref{lexicalRules}), possibly prefixed by $\backslash$, then that line is ignored, including the line break at its end. +If the first line of a multiline string consists solely of the whitespace characters defined by the production {\em WHITESPACE} (\ref{lexicalRules}), possibly prefixed by \syntax{`\\'}, then that line is ignored, including the line break at its end. \rationale{ The idea is to ignore a whitespace-only first line of a multiline string, where whitespace is defined as tabs, spaces and the final line break. @@ -4288,58 +4275,61 @@ These can be represented directly, but since for most characters prefixing by ba Strings support escape sequences for special characters. The escapes are: \begin{itemize} -\item $\backslash$n for newline, equivalent to $\backslash$x0A. -\item $\backslash$r for carriage return, equivalent to $\backslash$x0D. -\item $\backslash$f for form feed, equivalent to $\backslash$x0C. -\item $\backslash$b for backspace, equivalent to $\backslash$x08. -\item $\backslash$t for tab, equivalent to $\backslash$x09. -\item $\backslash$v for vertical tab, equivalent to $\backslash$x0B. -\item $\backslash$x $HEX\_DIGIT_1$ $HEX\_DIGIT_2$, equivalent to +\item \syntax{`\\n'} for newline, equivalent to \syntax{`\\x0A'}. +\item \syntax{`\\r'} for carriage return, equivalent to \syntax{`\\x0D'}. +\item \syntax{`\\f'} for form feed, equivalent to \syntax{`\\x0C'}. +\item \syntax{`\\b'} for backspace, equivalent to \syntax{`\\x08'}. +\item \syntax{`\\t'} for tab, equivalent to \syntax{`\\x09'}. +\item \syntax{`\\v'} for vertical tab, equivalent to \syntax{`\\x0B'}. +\item \syntax{`\\x' $_1$ $_2$}, equivalent to -$\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$\}. -\item $\backslash$u $HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$, equivalent to $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$\}. -\item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the Unicode code point represented by the $HEX\_DIGIT\_SEQUENCE$. -It is a compile-time error if the value of the $HEX\_DIGIT\_SEQUENCE$ is not a valid Unicode code point. -\item \$ indicating the beginning of an interpolated expression. -\item Otherwise, $\backslash k$ indicates the character $k$ for any $k$ not in $\{n, r, f, b, t, v, x, u\}$. +\syntax{`\\u{' $_1$ $_2$ `}'}. +\item \syntax{`\\u' $_1$ $_2$ $_3$ $_4$}, +equivalent to +\syntax{`\\u{' $_1$ $_2$ $_3$ $_4$ `}'}. +\item \syntax{`\\u{' `}'} is the Unicode code point represented by the +\syntax{}. +It is a compile-time error if the value of the +\syntax{} +is not a valid Unicode code point. +\item \syntax{`$'} indicating the beginning of an interpolated expression. +\item Otherwise, \syntax{`\\'$k$} indicates the character $k$ for any $k$ not in +\syntax{$\{$`n', `r', `f', `b', `t', `v', `x', `u'$\}$}. \end{itemize} \LMHash{} -Any string may be prefixed with the character `r', indicating that it is a {\em raw string}, in which case no escapes or interpolations are recognized. +Any string may be prefixed with the character \syntax{`r'}, +indicating that it is a {\em raw string}, +in which case no escapes or interpolations are recognized. \LMHash{} -Line breaks in a multiline string are represented by the {\em NEWLINE} production. +Line breaks in a multiline string are represented by the \syntax{} production. A line break introduces a single newline character into the string value. \LMHash{} -It is a compile-time error if a non-raw string literal contains a character sequence of the form $\backslash$x that is not followed by a sequence of two hexadecimal digits. -It is a compile-time error if a non-raw string literal contains a character sequence of the form $\backslash$u that is not followed by either a sequence of four hexadecimal digits, or by curly brace delimited sequence of hexadecimal digits. +It is a compile-time error if a non-raw string literal contains a character sequence of the form \syntax{`\\x'} that is not followed by a sequence of two hexadecimal digits. +It is a compile-time error if a non-raw string literal contains a character sequence of the form \syntax{`\\u'} that is not followed by either a sequence of four hexadecimal digits, or by curly brace delimited sequence of hexadecimal digits. \begin{grammar} -{\bf stringContentDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"}}' $|$ `\$' $|$ NEWLINE ); - `$\backslash$' \~{}( NEWLINE ); - stringInterpolation - . + ::= \~{}( `\\' | `"' | `$' | ) + \alt `\\' \~{}( ) + \alt -{\bf stringContentSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{'}}' $|$ `\$' $|$ NEWLINE ); - `$\backslash$' \~{}( NEWLINE ); - stringInterpolation - . + ::= \~{}( `\\' | `\'' | `$' | ) + \alt `\\' \~{}( ) + \alt -{\bf stringContentTDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"""}}' $|$ `\$'); - `$\backslash$' \~{}( NEWLINE ); - stringInterpolation - . + ::= \~{}( `\\' | `"""' | `$') + \alt `\\' \~{}( ) + \alt -{\bf stringContentTSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \code{'}\code{'}\code{'}}' $|$ `\$'); - `$\backslash$' \~{}( NEWLINE ); - stringInterpolation - . + ::= \~{}( `\\' | `\'\'\'' | `$') + \alt `\\' \~{}( ) + \alt -{\bf NEWLINE:}$\backslash$n; - $\backslash$r; - $\backslash$r$\backslash$n - . + ::= `\\n' + \alt `\\r' + \alt `\\r\\n' \end{grammar} \LMHash{} @@ -4356,9 +4346,8 @@ It is possible to embed expressions within non-raw string literals, such that th This process is known as {\em string interpolation}. \begin{grammar} -{\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; - `\$\{' expression `\}' - . + ::= `$' + \alt `${' `}' \end{grammar} \commentary{ @@ -4366,16 +4355,17 @@ The reader will note that the expression inside the interpolation could itself i } \LMHash{} -An unescaped \$ character in a string signifies the beginning of an interpolated expression. -The \$ sign may be followed by either: +An unescaped \syntax{`$'} character in a string signifies the beginning of an interpolated expression. +The \syntax{`$'} sign may be followed by either: \begin{itemize} -\item A single identifier \id{} that must not contain the \$ character. +\item A single identifier \id{} that must not contain the \syntax{`$'} character. \item An expression $e$ delimited by curly braces. \end{itemize} \LMHash{} The form \code{\$\id} is equivalent to the form \code{\$\{\id\}}. -An interpolated string, $s$, with content `\code{$s_0$\$\{$e_1$\}$s_1\ldots{}s_{n-1}\$\{e_n\}s_{n}$}' (where any of $s_0, \ldots, s_n$ can be empty) +An interpolated string, $s$, with content +`\code{$s_0$\$\{$e_1$\}$s_1\ldots{}s_{n-1}$\$\{$e_n$\}$s_{n}$}' (where any of $s_0, \ldots, s_n$ can be empty) is evaluated by evaluating each expression $e_i$ ($1 \le i \le n$) in to a string $r_i$ in the order they occur in the source text, as follows: \begin{itemize} \item{} Evaluate $e_i$ to an object $o_i$. @@ -4394,8 +4384,7 @@ A {\em symbol literal} denotes a name that would be either a valid declaration name or a valid library name in a Dart program. \begin{grammar} -{\bf symbolLiteral:}`\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) - . + ::= `#' ( | ( (`.' )*)) \end{grammar} \LMHash{} @@ -4458,8 +4447,7 @@ The static type of a symbol literal is \code{Symbol}. A {\em list literal} denotes a list, which is an integer indexed collection of objects. \begin{grammar} -{\bf listLiteral:}\CONST{}? typeArguments? `[' (expressionList \gcomma{}?)? `]' - . + ::= \CONST{}? ? `[' ( `,'?)? `]' \end{grammar} \LMHash{} @@ -4485,12 +4473,22 @@ The binding of a type parameter is not known at compile time, so we cannot use t } \LMHash{} -The value of a constant list literal \CONST{} $[e_1, \ldots, e_n]$ is an object $a$ whose class implements the built-in class $List$. +The value of a constant list literal +\code{\CONST{} <$E$>[$e_1, \ldots, e_n$]} +is an object $a$ whose class implements the built-in class +\code{List<$E$>}. The $i$th element of $a$ is $v_{i+1}$, where $v_i$ is the value of the compile-time expression $e_i$. -The value of a constant list literal \CONST{} $[e_1, \ldots, e_n]$ is defined as the value of the constant list literal \CONST{}$ <\DYNAMIC{}>[e_1, \ldots, e_n]$. +The value of a constant list literal +\code{\CONST{} [$e_1, \ldots, e_n$]} +is defined as the value of the constant list literal +\code{\CONST{} <\DYNAMIC{}>[$e_1, \ldots, e_n$]}. \LMHash{} -Let $list_1 =$ \CONST{} $[e_{11}, \ldots, e_{1n}]$ and $list_2 =$ \CONST{} $[e_{21}, \ldots, e_{2n}]$ be two constant list literals and let the elements of $list_1$ and $list_2$ evaluate to $o_{11}, \ldots, o_{1n}$ and $o_{21}, \ldots, o_{2n}$ respectively. +Let +$list_1 =$ \code{\CONST{} <$V$>[$e_{11}, \ldots, e_{1n}$]} +and +$list_2 =$ \code{\CONST{} <$U$>[$e_{21}, \ldots, e_{2n}$]} +be two constant list literals and let the elements of $list_1$ and $list_2$ evaluate to $o_{11}, \ldots, o_{1n}$ and $o_{21}, \ldots, o_{2n}$ respectively. If{}f \code{identical($o_{1i}$, $o_{2i}$)} for $i \in 1 .. n$ and $V = U$ then \code{identical($list_1$, $list_2$)}. \commentary{ @@ -4498,13 +4496,17 @@ In other words, constant list literals are canonicalized. } \LMHash{} -A run-time list literal $[e_1, \ldots, e_n]$ is evaluated as follows: +A run-time list literal +\code{<$E$>[$e_1, \ldots, e_n$]} +is evaluated as follows: \begin{itemize} \item First, the expressions $e_1, \ldots, e_n$ are evaluated in order they appear in the program, producing objects $o_1, \ldots, o_n$. -\item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class implements the built-in class $List$ is allocated. +\item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class implements the built-in class +\code{List<$E$>} +is allocated. \item -The operator \code{[]=} is invoked on $a$ with first argument $i$ and second argument +The operator \syntax{`[]='} is invoked on $a$ with first argument $i$ and second argument %The $i$th element of $a$ is set to $o_{i+1}, 0 \le i < n$. \item @@ -4518,18 +4520,33 @@ The order can only be observed in checked mode (and may not be relied upon): if } \LMHash{} -A run-time list literal $[e_1, \ldots, e_n]$ is evaluated as $<\DYNAMIC{}>[e_1, \ldots, e_n]$. +A run-time list literal +\code{[$e_1, \ldots, e_n$]} +is evaluated as +\code{<\DYNAMIC{}>[$e_1, \ldots, e_n$]}. \commentary{ There is no restriction precluding nesting of list literals. It follows from the rules above that -$>[[1, 2, 3], [4, 5, 6]]$ -is a list with type parameter $List$, containing two lists with type parameter \DYNAMIC{}. +\code{}, +containing two lists with type parameter \DYNAMIC{}. } \LMHash{} -The static type of a list literal of the form \CONST{}$ [e_1, \ldots, e_n]$ or the form $[e_1, \ldots, e_n]$ is $List$. -The static type a list literal of the form \CONST{} $[e_1, \ldots, e_n$] or the form $[e_1, \ldots, e_n$] is $List<\DYNAMIC{}>$. +The static type of a list literal of the form +\code{\CONST{} <$E$>[$e_1, \ldots, e_n$]} +or the form +\code{<$E$>[$e_1, \ldots, e_n$]} +is +\code{List}. +The static type a list literal of the form +\code{\CONST{} [$e_1, \ldots, e_n$]} +or the form +\code{[$e_1, \ldots, e_n$]} +is +\code{List<\DYNAMIC{}>}. \rationale{ It is tempting to assume that the type of the list literal would be computed based on the types of its elements. @@ -4551,12 +4568,10 @@ It is also much more uniform (and therefore predictable and understandable) to i A {\em map literal} denotes a map object. \begin{grammar} -{\bf mapLiteral:}\CONST{}? typeArguments? - \gnewline{} `\{' (mapLiteralEntry (\gcomma{} mapLiteralEntry)* \gcomma{}?)? `\}' - . + ::= \CONST{}? ? + \gnewline{} `{' ( (`,' )* `,'?)? `\}' -{\bf mapLiteralEntry:}expression `{\escapegrammar :}' expression - . + ::= `:' \end{grammar} \LMHash{} @@ -4573,19 +4588,29 @@ Attempting to mutate a constant map literal will result in a dynamic error. \LMHash{} It is a compile-time error if either a key or a value of an entry in a constant map literal is not a compile-time constant. It is a compile-time error if the key of an entry in a constant map literal is an instance of -a class that has a concrete operator \code{==} declaration different from the one in \code{Object}, +a class that has a concrete operator \syntax{`=='} declaration different from the one in \code{Object}, unless the key is a string or an integer, or the key expression is a literal symbol or an invocation of a constant constructor of class \code{Symbol}. It is a compile-time error if the type arguments of a constant map literal include a type variable. \LMHash{} -The value of a constant map literal \CONST{}$ \{k_1:e_1, \ldots, k_n :e_n\}$ is an object $m$ whose class implements the built-in class $Map$. +The value of a constant map literal +\code{\CONST{} <$K, V$>\{$k_1:e_1, \ldots, k_n:e_n$\}} +is an object $m$ whose class implements the built-in class +\code{Map<$K, V$>}. The entries of $m$ are $u_i:v_i, i \in 1 .. n$, where $u_i$ is the value of the compile-time expression $k_i$ and $v_i$ is the value of the compile-time expression $e_i$. -The value of a constant map literal \CONST{} $\{k_1:e_1, \ldots, k_n :e_n\}$ is defined as the value of a constant map literal \CONST{} $<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1, \ldots, k_n:e_n\}$. +The value of a constant map literal +\code{\CONST{} \{$k_1:e_1, \ldots, k_n:e_n$\}} +is defined as the value of a constant map literal +\code{\CONST{} <\DYNAMIC{}, \DYNAMIC{}>\{$k_1:e_1, \ldots, k_n:e_n$\}}. \LMHash{} -Let $map_1 =$ \CONST{}$ \{k_{11}:e_{11}, \ldots, k_{1n} :e_{1n}\}$ and $map_2 =$ \CONST{}$ \{k_{21}:e_{21}, \ldots, k_{2n} :e_{2n}\}$ be two constant map literals. +Let +$map_1 =$ \code{\CONST{} <$K, V$>\{$k_{11}:e_{11}, \ldots, k_{1n}:e_{1n}$\}} +and +$map_2 =$ \code{\CONST{} <$J, U$>\{$k_{21}:e_{21}, \ldots, k_{2n}:e_{2n}$\}} +be two constant map literals. Let the keys of $map_1$ and $map_2$ evaluate to $s_{11}, \ldots, s_{1n}$ and $s_{21}, \ldots, s_{2n}$ respectively, and let the elements of $map_1$ and $map_2$ evaluate to $o_{11}, \ldots, o_{1n}$ and $o_{21}, \ldots, o_{2n}$ respectively. If{}f \code{identical($o_{1i}$, $o_{2i}$)} and \code{identical($s_{1i}$, $s_{2i}$)} for $i \in 1 .. n$, and $K = J, V = U$ then \code{identical($map_1$, $map_2$)}. @@ -4594,24 +4619,29 @@ In other words, constant map literals are canonicalized. } \LMHash{} -A run-time map literal $\{k_1:e_1, \ldots, k_n :e_n\}$ is evaluated as follows: +A run-time map literal +\code{<$K, V$>\{$k_1:e_1, \ldots, k_n:e_n$\}} +is evaluated as follows: \begin{itemize} \item For each $i \in 1 .. n$ in numeric order, first the expression $k_i$ is evaluated producing object $u_i$, and then $e_i$ is evaluated producing object $o_i$. This produces all the objects $u_1, o_1, \ldots, u_n, o_n$. -\item A fresh instance (\ref{generativeConstructors}) $m$ whose class implements the built-in class $Map$ is allocated. +\item A fresh instance (\ref{generativeConstructors}) $m$ whose class implements the built-in class +\code{Map<$K, V$>} is allocated. \item -The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second argument $o_i$ for each $i \in 1 .. n$. +The operator \syntax{`[]='} is invoked on $m$ with first argument $u_i$ and second argument $o_i$ for each $i \in 1 .. n$. \item The result of the evaluation is $m$. \end{itemize} \LMHash{} -A run-time map literal $\{k_1:e_1, \ldots, k_n :e_n\}$ is evaluated as +A run-time map literal +\code{\{$k_1:e_1, \ldots, k_n:e_n$\}} +is evaluated as -$<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1, \ldots, k_n :e_n\}$. +\code{<\DYNAMIC{}, \DYNAMIC{}>\{$k_1:e_1, \ldots, k_n:e_n$\}}. \LMHash{} It is a compile-time error if two keys of a constant map literal are equal. @@ -4625,8 +4655,17 @@ Of course, if a key repeats, the order is defined by first occurrence, but the v } \LMHash{} -The static type of a map literal of the form \CONST{}$ \{k_1:e_1, \ldots, k_n :e_n\}$ or the form $\{k_1:e_1, \ldots, k_n :e_n\}$ is $Map$. -The static type of a map literal of the form \CONST{}$\{k_1:e_1, \ldots, k_n :e_n\}$ or the form $\{k_1:e_1, \ldots, k_n :e_n\}$ is $Map<\DYNAMIC{}, \DYNAMIC{}>$. +The static type of a map literal of the form +\code{\CONST{} <$K, V$>\{$k_1:e_1, \ldots, k_n:e_n$\}} +or the form +\code{<$K, V$>\{$k_1:e_1, \ldots, k_n:e_n$\}} +is +\code{Map<$K, V$>}. +The static type of a map literal of the form +\code{\CONST{} \{$k_1:e_1, \ldots, k_n:e_n$\}} +or the form +\code{\{$k_1:e_1, \ldots, k_n:e_n$\}} is +\code{Map<\DYNAMIC{}, \DYNAMIC{}>}. \subsection{Throw} @@ -4636,11 +4675,9 @@ The static type of a map literal of the form \CONST{}$\{k_1:e_1, \ldots, k_n :e_ The {\em throw expression} is used to throw an exception. \begin{grammar} -{\bf throwExpression:}\THROW{} expression - . + ::= \THROW{} -{\bf throwExpressionWithoutCascade:}\THROW{} expressionWithoutCascade - . + ::= \THROW{} \end{grammar} \LMHash{} @@ -4682,8 +4719,7 @@ The static type of a throw expression is $\bot$. A {\em function literal} is an object that encapsulates an executable unit of code. \begin{grammar} -{\bf functionExpression:}formalParameterPart functionBody - . + ::= \end{grammar} %% TODO[inference]: The static and dynamic type of a function literal @@ -4904,8 +4940,7 @@ it is considered to have been specified as \DYNAMIC{}. The reserved word \THIS{} denotes the target of the current instance member invocation. \begin{grammar} -{\bf thisExpression:}\THIS{} - . + ::= \THIS{} \end{grammar} \LMHash{} @@ -4964,8 +4999,7 @@ or is an enumerated type (\ref{enums}). The {\em new expression} invokes a constructor (\ref{constructors}). \begin{grammar} -{\bf newExpression:}\NEW{} type (`{\escapegrammar .}' identifier)? arguments - . + ::= \NEW{} (`.' )? \end{grammar} \LMHash{} @@ -5145,8 +5179,7 @@ A {\em constant object expression} invokes a constant constructor (\ref{constantConstructors}). \begin{grammar} -{\bf constObjectExpression:}\NEW{} type (`{\escapegrammar .}' identifier)? arguments - . + ::= \NEW{} (`.' )? \end{grammar} \LMHash{} @@ -5306,17 +5339,17 @@ To see how such situations might arise, consider the following examples: \FINAL{} x; \CONST{} A(p): x = p * 10; \} - +\\ \CLASS{} IntPair \{ \CONST{} IntPair(\THIS{}.x, \THIS{}.y); \FINAL{} int x; \FINAL{} int y; \OPERATOR *(v) => \NEW{} IntPair(x*v, y*v); \} - -\CONST a1 = \CONST{} A(true); // compile-time error -\CONST a2 = \CONST{} A(5); // legal -\CONST a3 = \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error +\\ +\CONST a1 = \CONST{} A(true); // \comment{compile-time error} +\CONST a2 = \CONST{} A(5); // \comment{legal} +\CONST a3 = \CONST{} A(\CONST{} IntPair(1,2)); // \comment{compile-time error} \end{dartCode} \commentary{ @@ -5380,7 +5413,7 @@ Completing normally or returning without a value is treated the same as returnin } \LMHash{} -If $f$ is marked \SYNC* (\ref{functions}), +If $f$ is marked \code{\SYNC*} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $i$ implementing \code{Iterable<$U$>} is immediately returned, where $U$ is determined as follows: @@ -5389,7 +5422,7 @@ If $T$ is \code{Iterable<$S$>} for some type $S$, then $U$ is $S$, otherwise $U$ is \code{Object}. \commentary{ -A Dart implementation will need to provide a specific implementation of \code{Iterable} that will be returned by \SYNC* methods. +A Dart implementation will need to provide a specific implementation of \code{Iterable} that will be returned by \code{\SYNC*} methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. } @@ -5415,14 +5448,14 @@ Further calls to \code{moveNext()} must return false. \end{itemize} Each iterator starts a separate computation. -If the \SYNC* function is impure, the sequence of values yielded by each iterator may differ. +If the \code{\SYNC*} function is impure, the sequence of values yielded by each iterator may differ. \commentary{ One can derive more than one iterator from a given iterable. Note that operations on the iterable itself can create distinct iterators. An example would be \code{length}. It is conceivable that different iterators might yield sequences of different length. -The same care needs to be taken when writing \SYNC* functions as when +The same care needs to be taken when writing \code{\SYNC*} functions as when writing an \code{Iterator} class. In particular, it should handle multiple simultaneous iterators gracefully. If the iterator depends on external state that might change, it should check that the state is still valid after every yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). @@ -5458,7 +5491,7 @@ so the future is not completed with an error {\em before} it has been returned. } \LMHash{} -If $f$ is marked \ASYNC* (\ref{functions}), +If $f$ is marked \code{\ASYNC*} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $s$ implementing \code{Stream<$U$>} is immediately returned, where $U$ is determined as follows: @@ -5497,19 +5530,16 @@ We choose to direct any exceptions that occur at this time to the cancellation f Actual argument lists have the following syntax: \begin{grammar} -{\bf arguments:}`(' (argumentList \gcomma{}?)? `)' - . + ::= `(' ( `,'?)? `)' -{\bf argumentList:}namedArgument (\gcomma{} namedArgument)*; - expressionList (\gcomma{} namedArgument)* - . + ::= (`,' )* + \alt (`,' )* -{\bf namedArgument:}label expression - . + ::=