diff --git a/docs/grammar/README.md b/docs/grammar/README.md
index 02f9182ae6..a279cfa58e 100644
--- a/docs/grammar/README.md
+++ b/docs/grammar/README.md
@@ -622,10 +622,9 @@ Go to: _[decimal-digit](#user-content-decimal-digit)_;
An identifier is a non-empty sequence of
letters, (decimal) digits, and underscores,
starting with a letter.
-It must not be a keyword: this is an extra-grammatical requirement.
-It must also not be or start with `aleo1`,
-because that is used for address literals:
-this is another extra-grammatical requirement.
+It must not be a keyword or a boolean literal,
+and it must not be or start with `aleo1`;
+these are extra-grammatical requirements, indicated in the comment.
```abnf
@@ -1515,9 +1514,20 @@ 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.
+The test expression must not be, or start with, a circuit construction.
+This is an extra-grammatical requirement, indicated in the comment.
+Without this restriction, for example `if c {} {}` would be ambiguous:
+it could be either a single conditional statement with test `c {}`,
+or a conditional statement with test `c`
+followed by an empty block statement.
+(Type analysis can disambiguate this,
+but it happens after parsing,
+and we want unambiguous parsing.)
+
```abnf
branch = %s"if" expression block
+ ; but expression is not circuit-construction...
```
Go to: _[block](#user-content-block), [expression](#user-content-expression)_;
@@ -1537,11 +1547,23 @@ A loop statement implicitly defines a loop variable
that goes from a starting value (inclusive) to an ending value (exclusive).
The body is a block.
+The second expression must not be, or start with, a circuit construction.
+This is an extra-grammatical requirement, indicated in the comment.
+Without this restriction,
+for example `for i in 0 .. c {} {}` would be ambiguous:
+it could be either a single loop statement with ending bound is `c {}`,
+or a loop statement with ending bound `c`
+followed by an empty block statement.
+(Type analysis can disambiguate this,
+but it happens after parsing,
+and we want unambiguous parsing.)
+
```abnf
loop-statement = %s"for" identifier ":" type
%s"in" expression ".." [ "=" ] expression
block
+ ; but second expression is not circuit-construction...
```
Go to: _[block](#user-content-block), [expression](#user-content-expression), [identifier](#user-content-identifier), [type](#user-content-type)_;
diff --git a/docs/grammar/abnf-grammar.txt b/docs/grammar/abnf-grammar.txt
index b2acfeea6b..6777c5c01b 100644
--- a/docs/grammar/abnf-grammar.txt
+++ b/docs/grammar/abnf-grammar.txt
@@ -444,10 +444,9 @@ hexadecimal-digit = decimal-digit / "a" / "b" / "c" / "d" / "e" / "f"
; An identifier is a non-empty sequence of
; letters, (decimal) digits, and underscores,
; starting with a letter.
-; It must not be a keyword: this is an extra-grammatical requirement.
-; It must also not be or start with `aleo1`,
-; because that is used for address literals:
-; this is another extra-grammatical requirement.
+; It must not be a keyword or a boolean literal,
+; and it must not be or start with `aleo1`;
+; these are extra-grammatical requirements, indicated in the comment.
identifier = letter *( letter / decimal-digit / "_" )
; but not a keyword or a boolean literal or aleo1...
@@ -924,7 +923,18 @@ identifier-or-identifiers = identifier
; or possibly with another conditional statement, forming a chain.
; Note that blocks are required in all branches, not merely statements.
+; The test expression must not be, or start with, a circuit construction.
+; This is an extra-grammatical requirement, indicated in the comment.
+; Without this restriction, for example `if c {} {}` would be ambiguous:
+; it could be either a single conditional statement with test `c {}`,
+; or a conditional statement with test `c`
+; followed by an empty block statement.
+; (Type analysis can disambiguate this,
+; but it happens after parsing,
+; and we want unambiguous parsing.)
+
branch = %s"if" expression block
+ ; but expression is not circuit-construction...
conditional-statement = branch
/ branch %s"else" block
@@ -934,9 +944,21 @@ conditional-statement = branch
; that goes from a starting value (inclusive) to an ending value (exclusive).
; The body is a block.
+; The second expression must not be, or start with, a circuit construction.
+; This is an extra-grammatical requirement, indicated in the comment.
+; Without this restriction,
+; for example `for i in 0 .. c {} {}` would be ambiguous:
+; it could be either a single loop statement with ending bound is `c {}`,
+; or a loop statement with ending bound `c`
+; followed by an empty block statement.
+; (Type analysis can disambiguate this,
+; but it happens after parsing,
+; and we want unambiguous parsing.)
+
loop-statement = %s"for" identifier ":" type
%s"in" expression ".." [ "=" ] expression
block
+ ; but second expression is not circuit-construction...
; An assignment statement is straightforward.
; Based on the operator, the assignment may be simple (i.e. `=`)