Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star)_;
<aname="rest-of-block-comment-after-star"></a>
```abnf
rest-of-block-comment-after-star = "/"
/ "*" rest-of-block-comment-after-star
/ not-star-or-slash rest-of-block-comment
```
Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_;
Go to: _[simple-character-escape](#user-content-simple-character-escape), [unicode-character-escape](#user-content-unicode-character-escape), [not-single-quote-or-backslash](#user-content-not-single-quote-or-backslash), [ascii-character-escape](#user-content-ascii-character-escape)_;
<aname="single-quote-escape"></a>
```abnf
single-quote-escape = "\" single-quote ; \'
```
Go to: _[single-quote](#user-content-single-quote)_;
<aname="double-quote-escape"></a>
```abnf
double-quote-escape = "\" double-quote ; \"
```
Go to: _[double-quote](#user-content-double-quote)_;
<aname="backslash-escape"></a>
```abnf
backslash-escape = "\\"
```
<aname="line-feed-escape"></a>
```abnf
line-feed-escape = %s"\n"
```
<aname="carriage-return-escape"></a>
```abnf
carriage-return-escape = %s"\r"
```
<aname="horizontal-tab-escape"></a>
```abnf
horizontal-tab-escape = %s"\t"
```
<aname="null-character-escape"></a>
```abnf
null-character-escape = "\0"
```
<aname="simple-character-escape"></a>
```abnf
simple-character-escape = single-quote-escape
/ double-quote-escape
/ backslash-escape
/ line-feed-escape
/ carriage-return-escape
/ horizontal-tab-escape
/ null-character-escape
```
Go to: _[carriage-return-escape](#user-content-carriage-return-escape), [single-quote-escape](#user-content-single-quote-escape), [backslash-escape](#user-content-backslash-escape), [line-feed-escape](#user-content-line-feed-escape), [horizontal-tab-escape](#user-content-horizontal-tab-escape), [null-character-escape](#user-content-null-character-escape), [double-quote-escape](#user-content-double-quote-escape)_;
Go to: _[not-double-quote-or-backslash](#user-content-not-double-quote-or-backslash), [simple-character-escape](#user-content-simple-character-escape), [unicode-character-escape](#user-content-unicode-character-escape), [ascii-character-escape](#user-content-ascii-character-escape)_;
The ones above are all the atomic literals
(in the sense that they are tokens, without whitespace allowed in them),
as defined by the following rule.
<aname="atomic-literal"></a>
```abnf
atomic-literal = untyped-literal
/ unsigned-literal
/ signed-literal
/ field-literal
/ product-group-literal
/ boolean-literal
/ address-literal
/ character-literal
/ string-literal
```
Go to: _[string-literal](#user-content-string-literal), [product-group-literal](#user-content-product-group-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [character-literal](#user-content-character-literal), [signed-literal](#user-content-signed-literal)_;
After defining the (mostly) alphanumeric tokens above,
it remains to define tokens for non-alphanumeric symbols such as `+` and `(`.
Different programming languages used different terminologies for these,
e.g. operators, separators, punctuators, etc.
Here we use `symbol`, for all of them.
We also include a token consisting of
a closing parenthesis `)` immediately followed by `group`:
as defined in the syntactic grammar,
this is the final part of an affine group literal;
even though it includes letters,
it seems appropriate to still consider it a symbol,
particularly since it starts with a proper symbol.
Everything defined above, other than comments and whitespace,
is a token, as defined by the following rule.
<aname="token"></a>
```abnf
token = keyword
/ identifier
/ atomic-literal
/ package-name
/ annotation-name
/ symbol
```
Go to: _[atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [symbol](#user-content-symbol), [package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [keyword](#user-content-keyword)_;
--------
Syntactic Grammar
-----------------
The processing defined by the lexical grammar above
turns the initial sequence of characters
into a sequence of tokens, comments, and whitespaces.
The purpose of comments and whitespaces, from a syntactic point of view,
is just to separate tokens:
they are discarded, leaving a sequence of tokens.
The syntactic grammar describes how to turn
a sequence of tokens into concrete syntax trees.
There are unsigned and signed integer types, for five sizes.
Go to: _[address-type](#user-content-address-type), [boolean-type](#user-content-boolean-type), [character-type](#user-content-character-type), [arithmetic-type](#user-content-arithmetic-type)_;
Circuit types are denoted by identifiers and the keyword `Self`.
The latter is only allowed inside a circuit definition,
to denote the circuit being defined.
<aname="self-type"></a>
```abnf
self-type = %s"Self"
```
<aname="circuit-type"></a>
```abnf
circuit-type = identifier / self-type
```
Go to: _[identifier](#user-content-identifier), [self-type](#user-content-self-type)_;
A tuple type consists of zero, two, or more component types.
<aname="tuple-type"></a>
```abnf
tuple-type = "(" [ type 1*( "," type ) ] ")"
```
Go to: _[type](#user-content-type)_;
An array type consists of an element type
and an indication of dimensions.
There is either a single dimension,
or a tuple of one or more dimensions.
<aname="array-type"></a>
```abnf
array-type = "[" type ";" array-dimensions "]"
```
Go to: _[array-dimensions](#user-content-array-dimensions), [type](#user-content-type)_;
<aname="array-dimensions"></a>
```abnf
array-dimensions = natural
/ "(" natural *( "," natural ) ")"
```
Go to: _[natural](#user-content-natural)_;
Circuit, tuple, and array types form the aggregate types,
i.e. types whose values contain (sub-)values
(with the corner-case exception of the empty tuple value).
Go to: _[affine-group-literal](#user-content-affine-group-literal), [product-group-literal](#user-content-product-group-literal)_;
As often done in grammatical language syntax specifications,
we define rules for different kinds of expressions,
which also defines the relative precedence
of operators and other expression constructs,
and the (left or right) associativity of binary operators.
The primary expressions are self-contained in a way,
i.e. they have clear delimitations:
Some consist of single tokens,
while others have explicit endings.
Primary expressions also include parenthesized expressions,
i.e. any expression may be turned into a primary one
by putting parentheses around it.
<aname="primary-expression"></a>
```abnf
primary-expression = identifier
/ %s"self"
/ %s"input"
/ literal
/ "(" expression ")"
/ tuple-expression
/ array-expression
/ circuit-expression
```
Go to: _[tuple-expression](#user-content-tuple-expression), [literal](#user-content-literal), [expression](#user-content-expression), [circuit-expression](#user-content-circuit-expression), [identifier](#user-content-identifier), [array-expression](#user-content-array-expression)_;
Tuple expressions construct tuples.
Each consists of zero, two, or more component expressions.
Go to: _[circuit-type](#user-content-circuit-type), [postfix-expression](#user-content-postfix-expression), [primary-expression](#user-content-primary-expression), [identifier](#user-content-identifier), [function-arguments](#user-content-function-arguments), [natural](#user-content-natural), [expression](#user-content-expression)_;
Unary operators have the highest operator precedence.
They apply to postfix expressions,
and recursively to unary expressions.
<aname="unary-expression"></a>
```abnf
unary-expression = postfix-expression
/ "!" unary-expression
/ "-" unary-expression
```
Go to: _[unary-expression](#user-content-unary-expression), [postfix-expression](#user-content-postfix-expression)_;
Next in the operator precedence is exponentiation,
following mathematical practice.
The current rule below makes exponentiation right-associative,
i.e. `a ** b ** c` must be parsed as `a ** (b ** c)`.
<aname="exponential-expression"></a>
```abnf
exponential-expression = unary-expression
/ unary-expression "**" exponential-expression
```
Go to: _[unary-expression](#user-content-unary-expression), [exponential-expression](#user-content-exponential-expression)_;
Next in precedence come multiplication and division, both left-associative.
Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conjunctive-expression](#user-content-conjunctive-expression)_;
Finally we have conditional expressions.
<aname="conditional-expression"></a>
```abnf
conditional-expression = disjunctive-expression
/ conditional-expression
"?" expression
":" conditional-expression
```
Go to: _[expression](#user-content-expression), [conditional-expression](#user-content-conditional-expression), [disjunctive-expression](#user-content-disjunctive-expression)_;
Those above are all the expressions.
Recall that conditional expressions
may be disjunctive expressions,
which may be conjunctive expressions,
and so on all the way to primary expressions.
<aname="expression"></a>
```abnf
expression = conditional-expression
```
Go to: _[conditional-expression](#user-content-conditional-expression)_;
There are various kinds of statements, including blocks.
Blocks are possibly empty sequences of statements surrounded by curly braces.
<aname="statement"></a>
```abnf
statement = expression-statement
/ return-statement
/ variable-declaration
/ constant-declaration
/ conditional-statement
/ loop-statement
/ assignment-statement
/ console-statement
/ block
```
Go to: _[assignment-statement](#user-content-assignment-statement), [expression-statement](#user-content-expression-statement), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration), [return-statement](#user-content-return-statement)_;
<aname="block"></a>
```abnf
block = "{" *statement "}"
```
An expression (that must return the empty tuple, as semantically required)
can be turned into a statement by appending a semicolon.
<aname="expression-statement"></a>
```abnf
expression-statement = expression ";"
```
Go to: _[expression](#user-content-expression)_;
A return statement always takes an expression, and ends with a semicolon.
<aname="return-statement"></a>
```abnf
return-statement = %s"return" expression ";"
```
Go to: _[expression](#user-content-expression)_;
There are variable declarations and constant declarations,
which only differ in the starting keyword.
These declarations are also statements.
The names of the variables or constants are
either a single one or a tuple of two or more;
in all cases, there is just one optional type
and just one initializing expression.
<aname="variable-declaration"></a>
```abnf
variable-declaration = %s"let" identifier-or-identifiers [ ":" type ]
"=" expression ";"
```
Go to: _[expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type)_;
<aname="constant-declaration"></a>
```abnf
constant-declaration = %s"const" identifier-or-identifiers [ ":" type ]
"=" expression ";"
```
Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_;
<aname="identifier-or-identifiers"></a>
```abnf
identifier-or-identifiers = identifier
/ "(" identifier 1*( "," identifier ) ")"
```
Go to: _[identifier](#user-content-identifier)_;
A conditional statement always starts with a condition and a block
(which together form a branch).
It may stop there, or it may continue with an alternative block,
or possibly with another conditional statement, forming a chain.
Note that blocks are required in all branches, not merely statements.
<aname="branch"></a>
```abnf
branch = %s"if" expression block
```
Go to: _[expression](#user-content-expression), [block](#user-content-block)_;
<aname="conditional-statement"></a>
```abnf
conditional-statement = branch
/ branch %s"else" block
/ branch %s"else" conditional-statement
```
Go to: _[branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_;
A loop statement implicitly defines a loop variable
that goes from a starting value (inclusive) to an ending value (exclusive).
Go to: _[type](#user-content-type), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [block](#user-content-block)_;
<aname="function-parameters"></a>
```abnf
function-parameters = self-parameter
/ self-parameter "," function-inputs
/ function-inputs
```
Go to: _[self-parameter](#user-content-self-parameter), [function-inputs](#user-content-function-inputs)_;
Go to: _[package-name](#user-content-package-name), [identifier](#user-content-identifier), [package-path](#user-content-package-path)_;
Finally, we define a file as a sequence of zero or more declarations.
We allow constant declarations at the top level, for global constants.
Currently variable declarations are disallowed at the top level.
<aname="declaration"></a>
```abnf
declaration = import-declaration
/ function-declaration
/ circuit-declaration
/ constant-declaration
```
Go to: _[circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration)_;
<aname="file"></a>
```abnf
file = *declaration
```
--------
Format Note
-----------
The ABNF standard requires grammars
to consist of lines terminated by `<CR><LF>`
(i.e. carriage return followed by line feed, DOS/Windows-style),
as explained in the background on ABNF earlier in this file.
This file's lines are therefore terminated by `<CR><LF>`.
To avoid losing this requirement across systems,
this file is marked as `text eol=crlf` in `.gitattributes`:
this means that the file is textual, enabling visual diffs,
but its lines will always be terminated by `<CR><LF>` on any system.
Note that this `<CR><LF>` requirement only applies
to the grammar files themselves.
It does not apply to the lines of the languages described by the grammar.
ABNF grammars may describe any kind of languages,
with any kind of line terminators,
or even without line terminators at all (e.g. for "binary" languages).