15. Grammar summary
This grammar describes the complete syntax for language version 1.2. Language
version 1.1 treats catch, finally, primitive, throw, type, and try as
identifiers, and language version 1 also rejects the read-only array additions.
A selected language profile may reject otherwise recognized function, loop,
mutation, open-object, trailing-comma, or exception-handling constructs as
defined in Section 14.
expression-root
= expression end-of-file ;
program-root
= type-declaration* function-declaration* statement* end-of-file ;
type-declaration
= "type" identifier object-type-body ";" ;
function-declaration
= "func" identifier
"(" parameter-list? ")"
":" function-return-type
block ;
parameter-list
= parameter ("," parameter)* ;
parameter
= identifier ":" type ;
function-return-type
= type
| "void" ;
statement
= block
| variable-declaration ";"
| assignment ";"
| removal ";"
| call-expression ";"
| if-statement
| while-statement
| for-statement
| try-statement
| throw-statement ";"
| "break" integer-literal? ";"
| "continue" integer-literal? ";"
| return-statement ";"
| ";" ;
block
= "{" statement* "}" ;
variable-declaration
= "var" identifier "$"?
(":" type ("=" expression)?
| "=" expression) ;
assignment
= assignable "=" expression ;
assignable
= identifier
| property-access
| element-access ;
removal
= removable "~" ;
removable
= property-access
| element-access ;
if-statement
= "if" "(" expression ")" statement
("else" statement)? ;
while-statement
= "while" "(" expression ")" statement ;
for-statement
= "for" "(" for-initializer? ";"
expression? ";"
for-iterator? ")"
statement ;
for-initializer
= variable-declaration
| assignment
| call-expression ;
for-iterator
= assignment
| call-expression ;
return-statement
= "return" expression? ;
try-statement
= "try" block
(catch-clause finally-clause?
| finally-clause) ;
catch-clause
= "catch" ("(" identifier ")")? block ;
finally-clause
= "finally" block ;
throw-statement
= "throw" expression? ;
type
= primary-type nullable-suffix?
(array-suffix read-only-suffix? nullable-suffix?)* ;
primary-type
= "bool"
| "int"
| "float"
| "number"
| "primitive"
| "error"
| "string"
| "unknown"
| "object"
| named-type
| object-type-body ;
named-type
= source-type-name
| host-type-name ;
object-type-body
= closed-object-type
| open-object-type ;
closed-object-type
= "{" object-type-property-list? "}" ;
open-object-type
= "@{" object-type-property-list? "}" ;
object-type-property-list
= object-type-property ("," object-type-property)* ","? ;
object-type-property
= (identifier | string-literal) "$"? "?"? ":" type ;
array-suffix
= "[]" ;
read-only-suffix
= "$" ;
nullable-suffix
= "?" ;
array-literal
= "[" (expression ("," expression)* ","?)? "]" ;
read-only-array-literal
= "$[" (expression ("," expression)* ","?)? "]" ;
non-finite-float-literal
= ("+" | "-")? ("infty" | "nan") ;
closed-object-literal
= "{" property-initializer-list? "}" ;
open-object-literal
= "@{" property-initializer-list? "}" ;
property-initializer-list
= property-initializer ("," property-initializer)* ","? ;
property-initializer
= (identifier | string-literal)
"$"? "?"?
(":" type)?
("=" expression)? ;
Expression grammar is defined by the precedence table rather than expanded in this summary.
The property modifier order is fixed. Required properties and every property
without an explicit type require an initializer. Profiles selecting
ObjectLiteralSyntax.Legacy instead use
(identifier | string-literal) (":" | "?" ":") expression.