]> Cypherpunks repositories - gostls13.git/commitdiff
Spec modified to reflect new semicolon rules.
authorRobert Griesemer <gri@golang.org>
Fri, 11 Dec 2009 00:43:01 +0000 (16:43 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 11 Dec 2009 00:43:01 +0000 (16:43 -0800)
R=rsc, r, iant, ken2
CC=golang-dev
https://golang.org/cl/166066

doc/go_spec.html

index 6c4862e668bf6ce1634aea3bf8d23043bed3aa75..5aed74e00aeb26bd6f858346ce7e32679b36e21b 100644 (file)
@@ -126,12 +126,27 @@ hex_digit     = "0" ... "9" | "A" ... "F" | "a" ... "f" .
 <h3 id="Comments">Comments</h3>
 
 <p>
-There are two forms of comments.  The first starts at the character
-sequence <code>//</code> and continues through the next newline.  The
-second starts at the character sequence <code>/*</code> and continues
-through the character sequence <code>*/</code>.  Comments do not nest.
+There are two forms of comments:
 </p>
 
+<ol>
+<li>
+<i>Line comments</i> start with the character sequence <code>//</code>
+and continue through the next newline. A line comment acts like a newline.
+</li>
+<li>
+<i>General comments</i> start with the character sequence <code>/*</code>
+and continue through the character sequence <code>*/</code>. A general
+comment that spans multiple lines acts like a newline, otherwise it acts
+like a space.
+</li>
+</ol>
+
+<p>
+Comments do not nest.
+</p>
+
+
 <h3 id="Tokens">Tokens</h3>
 
 <p>
@@ -141,12 +156,52 @@ and delimiters, and literals.  <i>White space</i>, formed from
 spaces (U+0020), horizontal tabs (U+0009),
 carriage returns (U+000D), and newlines (U+000A),
 is ignored except as it separates tokens
-that would otherwise combine into a single token.  Comments
-behave as white space.  While breaking the input into tokens,
+that would otherwise combine into a single token.
+While breaking the input into tokens,
 the next token is the longest sequence of characters that form a
 valid token.
 </p>
 
+<h3 id="Semicolons">Semicolons</h3>
+
+<p>
+The formal grammar uses semicolons <code>";"</code> as terminators in
+a number of productions. Go programs may omit most of these semicolons
+using the following two rules:
+</p>
+
+<ol>
+<li>
+<p>
+When the input is broken into tokens, a semicolon is automatically inserted
+into the token stream at the end of a non-blank line if the line's final
+token is
+</p>
+<ul>
+       <li>an identifier or basic literal
+       <li>one of the keywords
+           <code>break</code>, <code>continue</code>, <code>fallthrough</code>,
+           or <code>return</code>
+       </li>
+       <li>one of the operators and delimiters
+           <code>++</code>, <code>--</code>, <code>)</code>, <code>]</code>,
+           or <code>}</code>
+       </li>
+</ul>
+</li>
+
+<li>
+To allow complex statements to occupy a single line, a semicolon
+may be omitted before a closing <code>")"</code> or <code>"}"</code>.
+</li>
+</ol>
+
+<p>
+To reflect idiomatic use, code examples in this document elide semicolons
+using these rules.
+</p>
+
+
 <h3 id="Identifiers">Identifiers</h3>
 
 <p>
@@ -163,7 +218,11 @@ _x9
 ThisVariableIsExported
 αβ
 </pre>
+
+<p>
 Some identifiers are <a href="#Predeclared_identifiers">predeclared</a>.
+</p>
+
 
 <h3 id="Keywords">Keywords</h3>
 
@@ -359,12 +418,7 @@ the two bytes <code>0xc3</code> <code>0xbf</code> of the UTF-8 encoding of chara
 U+00FF.
 </p>
 
-<p>
-A sequence of string literals is concatenated to form a single string constant.
-</p>
-
 <pre class="ebnf">
-StringLit              = string_lit { string_lit } .
 string_lit             = raw_string_lit | interpreted_string_lit .
 raw_string_lit         = "`" { unicode_char } "`" .
 interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
@@ -380,8 +434,6 @@ interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
 "日本語"
 "\u65e5本\U00008a9e"
 "\xff\u00FF"
-"Alea iacta est."
-"Alea " /* The die */ `iacta est` /* is cast */ "."  // same as "Alea iacta est."
 </pre>
 
 <p>
@@ -712,11 +764,10 @@ be unique.
 </p>
 
 <pre class="ebnf">
-StructType     = "struct" "{" [ FieldDeclList ] "}" .
-FieldDeclList  = FieldDecl { ";" FieldDecl } [ ";" ] .
+StructType     = "struct" "{" { FieldDecl ";" } "}" .
 FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
 AnonymousField = [ "*" ] TypeName .
-Tag            = StringLit .
+Tag            = string_lit .
 </pre>
 
 <pre>
@@ -725,11 +776,11 @@ struct {}
 
 // A struct with 6 fields.
 struct {
-       x, y int;
-       u float;
-       _ float;  // padding
-       A *[]int;
-       F func();
+       x, y int
+       u float
+       _ float  // padding
+       A *[]int
+       F func()
 }
 </pre>
 
@@ -744,11 +795,11 @@ a pointer type. The unqualified type name acts as the field name.
 <pre>
 // A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
 struct {
-       T1;        // field name is T1
-       *T2;       // field name is T2
-       P.T3;      // field name is T3
-       *P.T4;     // field name is T4
-       x, y int;  // field names are x and y
+       T1        // field name is T1
+       *T2       // field name is T2
+       P.T3      // field name is T3
+       *P.T4     // field name is T4
+       x, y int  // field names are x and y
 }
 </pre>
 
@@ -759,9 +810,9 @@ in a struct type:
 
 <pre>
 struct {
-       T;         // conflicts with anonymous field *T and *P.T
-       *T;        // conflicts with anonymous field T and *P.T
-       *P.T;      // conflicts with anonymous field T and *T
+       T         // conflicts with anonymous field *T and *P.T
+       *T        // conflicts with anonymous field T and *P.T
+       *P.T      // conflicts with anonymous field T and *T
 }
 </pre>
 
@@ -799,9 +850,9 @@ but are otherwise ignored.
 // A struct corresponding to the TimeStamp protocol buffer.
 // The tag strings define the protocol buffer field numbers.
 struct {
-       microsec  uint64 "field 1";
-       serverIP6 uint64 "field 2";
-       process   string "field 3";
+       microsec  uint64 "field 1"
+       serverIP6 uint64 "field 2"
+       process   string "field 3"
 }
 </pre>
 
@@ -835,7 +886,7 @@ A function value may be <code>nil</code>.
 FunctionType   = "func" Signature .
 Signature      = Parameters [ Result ] .
 Result         = Parameters | Type .
-Parameters     = "(" [ ParameterList ] ")" .
+Parameters     = "(" [ ParameterList [ "," ] ] ")" .
 ParameterList  = ParameterDecl { "," ParameterDecl } .
 ParameterDecl  = [ IdentifierList ] ( Type | "..." ) .
 </pre>
@@ -878,8 +929,7 @@ that is any superset of the interface. Such a type is said to
 </p>
 
 <pre class="ebnf">
-InterfaceType      = "interface" "{" [ MethodSpecList ] "}" .
-MethodSpecList     = MethodSpec { ";" MethodSpec } [ ";" ] .
+InterfaceType      = "interface" "{" { MethodSpec ";" } "}" .
 MethodSpec         = MethodName Signature | InterfaceTypeName .
 MethodName         = identifier .
 InterfaceTypeName  = TypeName .
@@ -892,9 +942,9 @@ As with all method sets, in an interface type, each method must have a unique na
 <pre>
 // A simple File interface
 interface {
-       Read(b Buffer) bool;
-       Write(b Buffer) bool;
-       Close();
+       Read(b Buffer) bool
+       Write(b Buffer) bool
+       Close()
 }
 </pre>
 
@@ -935,8 +985,8 @@ to define an interface called <code>Lock</code>:
 
 <pre>
 type Lock interface {
-       Lock();
-       Unlock();
+       Lock()
+       Unlock()
 }
 </pre>
 
@@ -962,14 +1012,14 @@ in the interface.
 
 <pre>
 type ReadWrite interface {
-       Read(b Buffer) bool;
-       Write(b Buffer) bool;
+       Read(b Buffer) bool
+       Write(b Buffer) bool
 }
 
 type File interface {
-       ReadWrite;  // same as enumerating the methods in ReadWrite
-       Lock;       // same as enumerating the methods in Lock
-       Close();
+       ReadWrite  // same as enumerating the methods in ReadWrite
+       Lock       // same as enumerating the methods in Lock
+       Close()
 }
 </pre>
 
@@ -1144,12 +1194,12 @@ Given the declarations
 
 <pre>
 type (
-       T0 []string;
-       T1 []string;
-       T2 struct { a, b int };
-       T3 struct { a, c int };
-       T4 func (int, float) *T0;
-       T5 func (x int, y float) *[]string;
+       T0 []string
+       T1 []string
+       T2 struct { a, b int }
+       T3 struct { a, c int }
+       T4 func (int, float) *T0
+       T5 func (x int, y float) *[]string
 )
 </pre>
 
@@ -1297,7 +1347,7 @@ brace brackets.
 </p>
 
 <pre class="ebnf">
-Block = "{" StatementList "}" .
+Block = "{" { Statement ";" } "}" .
 </pre>
 
 <p>
@@ -1459,8 +1509,7 @@ right.
 </p>
 
 <pre class="ebnf">
-ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
-ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
+ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
 ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
 
 IdentifierList = identifier { "," identifier } .
@@ -1483,8 +1532,8 @@ constant, even if the literal's fractional part is zero.
 const Pi float64 = 3.14159265358979323846
 const zero = 0.0             // untyped floating-point constant
 const (
-       size int64 = 1024;
-       eof = -1;            // untyped integer constant
+       size int64 = 1024
+       eof = -1             // untyped integer constant
 )
 const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", untyped integer and string constants
 const u, v float = 0, 3      // u = 0.0, v = 3.0
@@ -1504,14 +1553,14 @@ this mechanism permits light-weight declaration of sequential values:
 
 <pre>
 const (
-       Sunday = iota;
-       Monday;
-       Tuesday;
-       Wednesday;
-       Thursday;
-       Friday;
-       Partyday;
-       numberOfDays;  // this constant is not exported
+       Sunday = iota
+       Monday
+       Tuesday
+       Wednesday
+       Thursday
+       Friday
+       Partyday
+       numberOfDays  // this constant is not exported
 )
 </pre>
 
@@ -1522,31 +1571,32 @@ const (
 Within a constant declaration, the predeclared identifier
 <code>iota</code> represents successive untyped integer <a href="#Constants">
 constants</a>. It is reset to 0 whenever the reserved word <code>const</code>
-appears in the source and increments with each semicolon. It can be used to construct a
+appears in the source and increments with each
+<a href="#Semicolons">semicolon</a>. It can be used to construct a
 set of related constants:
 </p>
 
 <pre>
 const (  // iota is reset to 0
-       c0 = iota;  // c0 == 0
-       c1 = iota;  // c1 == 1
-       c2 = iota   // c2 == 2
+       c0 = iota  // c0 == 0
+       c1 = iota  // c1 == 1
+       c2 = iota  // c2 == 2
 )
 
 const (
-       a = 1 &lt;&lt; iota;  // a == 1 (iota has been reset)
-       b = 1 &lt;&lt; iota;  // b == 2
-       c = 1 &lt;&lt; iota;  // c == 4
+       a = 1 &lt;&lt; iota  // a == 1 (iota has been reset)
+       b = 1 &lt;&lt; iota  // b == 2
+       c = 1 &lt;&lt; iota  // c == 4
 )
 
 const (
-       u       = iota * 42;  // u == 0     (untyped integer constant)
-       v float = iota * 42;  // v == 42.0  (float constant)
-       w       = iota * 42;  // w == 84    (untyped integer constant)
+       u       = iota * 42  // u == 0     (untyped integer constant)
+       v float = iota * 42  // v == 42.0  (float constant)
+       w       = iota * 42  // w == 84    (untyped integer constant)
 )
 
-const x = iota;  // x == 0 (iota has been reset)
-const y = iota;  // y == 0 (iota has been reset)
+const x = iota  // x == 0 (iota has been reset)
+const y = iota  // y == 0 (iota has been reset)
 </pre>
 
 <p>
@@ -1556,10 +1606,10 @@ it is only incremented at a semicolon:
 
 <pre>
 const (
-       bit0, mask0 = 1 &lt;&lt; iota, 1 &lt;&lt; iota - 1;  // bit0 == 1, mask0 == 0
-       bit1, mask1;                             // bit1 == 2, mask1 == 1
-       _, _;                                    // skips iota == 2
-       bit3, mask3;                             // bit3 == 8, mask3 == 7
+       bit0, mask0 = 1 &lt;&lt; iota, 1 &lt;&lt; iota - 1  // bit0 == 1, mask0 == 0
+       bit1, mask1                             // bit1 == 2, mask1 == 1
+       _, _                                    // skips iota == 2
+       bit3, mask3                             // bit3 == 8, mask3 == 7
 )
 </pre>
 
@@ -1580,8 +1630,7 @@ an existing type.  The new type is
 </p>
 
 <pre class="ebnf">
-TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
-TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
+TypeDecl     = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
 TypeSpec     = identifier Type .
 </pre>
 
@@ -1589,19 +1638,19 @@ TypeSpec     = identifier Type .
 type IntArray [16]int
 
 type (
-       Point struct { x, y float };
+       Point struct { x, y float }
        Polar Point
 )
 
 type TreeNode struct {
-       left, right *TreeNode;
-       value *Comparable;
+       left, right *TreeNode
+       value *Comparable
 }
 
 type Cipher interface {
-       BlockSize() int;
-       Encrypt(src, dst []byte);
-       Decrypt(src, dst []byte);
+       BlockSize() int
+       Encrypt(src, dst []byte)
+       Decrypt(src, dst []byte)
 }
 </pre>
 
@@ -1623,7 +1672,7 @@ type NewMutex Mutex
 // PrintableMutex's method set contains the methods
 // Lock and Unlock bound to its anonymous field Mutex.
 type PrintableMutex struct {
-       Mutex;
+       Mutex
 }
 </pre>
 
@@ -1636,14 +1685,14 @@ type and attach methods to it:
 type TimeZone int
 
 const (
-       EST TimeZone = -(5 + iota);
-       CST;
-       MST;
-       PST;
+       EST TimeZone = -(5 + iota)
+       CST
+       MST
+       PST
 )
 
 func (tz TimeZone) String() string {
-       return fmt.Sprintf("GMT+%dh", tz);
+       return fmt.Sprintf("GMT+%dh", tz)
 }
 </pre>
 
@@ -1655,8 +1704,7 @@ A variable declaration creates a variable, binds an identifier to it and
 gives it a type and optionally an initial value.
 </p>
 <pre class="ebnf">
-VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
-VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
+VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
 VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
 </pre>
 
@@ -1666,11 +1714,11 @@ var U, V, W float
 var k = 0
 var x, y float = -1, -2
 var (
-       i int;
+       i int
        u, v, s = 2.0, 3.0, "bar"
 )
 var re, im = complexSqrt(-1)
-var _, found = entries[name];  // map lookup; only interested in "found"
+var _, found = entries[name]  // map lookup; only interested in "found"
 </pre>
 
 <p>
@@ -1721,11 +1769,11 @@ initializer expressions but no types:
 </pre>
 
 <pre>
-i, j := 0, 10;
-f := func() int { return 7; }
-ch := make(chan int);
-r, w := os.Pipe(fd);  // os.Pipe() returns two values
-_, y, _ := coord(p);  // coord() returns three values; only interested in y coordinate
+i, j := 0, 10
+f := func() int { return 7 }
+ch := make(chan int)
+r, w := os.Pipe(fd)  // os.Pipe() returns two values
+_, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate
 </pre>
 
 <p>
@@ -1738,8 +1786,8 @@ variable; it just assigns a new value to the original.
 </p>
 
 <pre>
-field1, offset := nextField(str, 0);
-field2, offset := nextField(str, offset);  // redeclares offset
+field1, offset := nextField(str, 0)
+field2, offset := nextField(str, offset)  // redeclares offset
 </pre>
 
 <p>
@@ -1768,9 +1816,9 @@ signature for a function implemented outside Go, such as an assembly routine.
 <pre>
 func min(x int, y int) int {
        if x &lt; y {
-               return x;
+               return x
        }
-       return y;
+       return y
 }
 
 func flushICache(begin, end uintptr)  // implemented externally
@@ -1805,12 +1853,12 @@ Given type <code>Point</code>, the declarations
 
 <pre>
 func (p *Point) Length() float {
-       return Math.sqrt(p.x * p.x + p.y * p.y);
+       return Math.sqrt(p.x * p.x + p.y * p.y)
 }
 
 func (p *Point) Scale(factor float) {
-       p.x = p.x * factor;
-       p.y = p.y * factor;
+       p.x = p.x * factor
+       p.y = p.y * factor
 }
 </pre>
 
@@ -1856,7 +1904,7 @@ Operands denote the elementary values in an expression.
 <pre class="ebnf">
 Operand    = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" .
 Literal    = BasicLit | CompositeLit | FunctionLit .
-BasicLit   = int_lit | float_lit | char_lit | StringLit .
+BasicLit   = int_lit | float_lit | char_lit | string_lit .
 </pre>
 
 
@@ -1897,10 +1945,10 @@ a single expression or a key-value pair.
 </p>
 
 <pre class="ebnf">
-CompositeLit  = LiteralType "{" [ ElementList ] "}" .
+CompositeLit  = LiteralType "{" [ ElementList [ "," ] ] "}" .
 LiteralType   = StructType | ArrayType | "[" "..." "]" ElementType |
                 SliceType | MapType | TypeName | "(" LiteralType ")" .
-ElementList   = Element { "," Element } [ "," ] .
+ElementList   = Element { "," Element } .
 Element       = [ Key ":" ] Value .
 Key           = FieldName | ElementIndex .
 FieldName     = identifier .
@@ -1959,8 +2007,8 @@ one may write
 </p>
 
 <pre>
-origin := Point{};                            // zero value for Point
-line := Line{origin, Point{y: -4, z: 12.3}};  // zero value for line.q.x
+origin := Point{}                            // zero value for Point
+line := Line{origin, Point{y: -4, z: 12.3}}  // zero value for line.q.x
 </pre>
 
 <p>
@@ -1983,7 +2031,7 @@ Taking the address of a composite literal (§<a href="#Address_operators">Addres
 generates a unique pointer to an instance of the literal's value.
 </p>
 <pre>
-var pointer *Point = &amp;Point{y: 1000};
+var pointer *Point = &amp;Point{y: 1000}
 </pre>
 
 <p>
@@ -1996,9 +2044,9 @@ to the maximum element index plus one.
 </p>
 
 <pre>
-buffer := [10]string{};               // len(buffer) == 10
-intSet := [6]int{1, 2, 3, 5};         // len(intSet) == 6
-days := [...]string{"Sat", "Sun"};    // len(days) == 2
+buffer := [10]string{}               // len(buffer) == 10
+intSet := [6]int{1, 2, 3, 5}         // len(intSet) == 6
+days := [...]string{"Sat", "Sun"}    // len(days) == 2
 </pre>
 
 <p>
@@ -2040,13 +2088,13 @@ Examples of valid array, slice, and map literals:
 
 <pre>
 // list of prime numbers
-primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991};
+primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991}
 
 // vowels[ch] is true if ch is a vowel
-vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true};
+vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
 
-// the array [10]float{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1};
-filter := [10]float{-1, 4: -0.1, -0.1, 9: -1};
+// the array [10]float{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
+filter := [10]float{-1, 4: -0.1, -0.1, 9: -1}
 
 // frequencies in Hz for equal-tempered scale (A4 = 440Hz)
 noteFrequency := map[string]float{
@@ -2109,7 +2157,7 @@ Selector       = "." identifier .
 Index          = "[" Expression "]" .
 Slice          = "[" Expression ":" [ Expression ] "]" .
 TypeAssertion  = "." "(" Type ")" .
-Call           = "(" [ ExpressionList ] ")" .
+Call           = "(" [ ExpressionList [ "," ] ] ")" .
 </pre>
 
 
@@ -2200,26 +2248,26 @@ For example, given the declarations:
 
 <pre>
 type T0 struct {
-       x int;
+       x int
 }
 
 func (recv *T0) M0()
 
 type T1 struct {
-       y int;
+       y int
 }
 
 func (recv T1) M1()
 
 type T2 struct {
-       z int;
-       T1;
-       *T0;
+       z int
+       T1
+       *T0
 }
 
 func (recv *T2) M2()
 
-var p *T2;  // with p != nil and p.T1 != nil
+var p *T2  // with p != nil and p.T1 != nil
 </pre>
 
 <p>
@@ -2356,8 +2404,8 @@ After slicing the array <code>a</code>
 </p>
 
 <pre>
-a := [5]int{1, 2, 3, 4, 5};
-s := a[1:4];
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
 </pre>
 
 <p>
@@ -2463,7 +2511,7 @@ the method.
 
 <pre>
 math.Atan2(x, y)    // function call
-var pt *Point;
+var pt *Point
 pt.Scale(3.5)  // method call with receiver pt
 </pre>
 
@@ -2504,7 +2552,7 @@ for <code>(&amp;x).m()</code>:
 </p>
 
 <pre>
-var p Point;
+var p Point
 p.Scale(3.5)
 </pre>
 
@@ -2540,7 +2588,7 @@ Given the function and call
 </p>
 <pre>
 func Fprintf(f io.Writer, format string, args ...)
-Fprintf(os.Stdout, "%s %d", "hello", 23);
+Fprintf(os.Stdout, "%s %d", "hello", 23)
 </pre>
 
 <p>
@@ -2610,12 +2658,12 @@ the left operand alone.
 </p>
 
 <pre>
-var s uint = 33;
-var i = 1&lt;&lt;s;          // 1 has type int
-var j = int32(1&lt;&lt;s);   // 1 has type int32; j == 0
-var u = uint64(1&lt;&lt;s);  // 1 has type uint64; u == 1&lt;&lt;33
-var f = float(1&lt;&lt;s);   // illegal: 1 has type float, cannot shift
-var g = float(1&lt;&lt;33);  // legal; 1&lt;&lt;33 is a constant shift operation; g == 1&lt;&lt;33
+var s uint = 33
+var i = 1&lt;&lt;s          // 1 has type int
+var j = int32(1&lt;&lt;s)   // 1 has type int32; j == 0
+var u = uint64(1&lt;&lt;s)  // 1 has type uint64; u == 1&lt;&lt;33
+var f = float(1&lt;&lt;s)   // illegal: 1 has type float, cannot shift
+var g = float(1&lt;&lt;33)  // legal; 1&lt;&lt;33 is a constant shift operation; g == 1&lt;&lt;33
 </pre>
 
 <h3 id="Operator_precedence">Operator precedence</h3>
@@ -2688,8 +2736,8 @@ or the <code>+=</code> assignment operator:
 </p>
 
 <pre>
-s := "hi" + string(c);
-s += " and good bye";
+s := "hi" + string(c)
+s += " and good bye"
 </pre>
 
 <p>
@@ -2883,7 +2931,7 @@ These two examples are equivalent:
 </p>
 
 <pre>
-ok := ch &lt;- 3;
+ok := ch &lt;- 3
 if ok { print("sent") } else { print("not sent") }
 
 if ch &lt;- 3 { print("sent") } else { print("not sent") }
@@ -2968,11 +3016,11 @@ Consider a struct type <code>T</code> with two methods,
 
 <pre>
 type T struct {
-       a int;
+       a int
 }
 func (tv  T) Mv(a int)   int   { return 0 }  // value receiver
 func (tp *T) Mp(f float) float { return 1 }  // pointer receiver
-var t T;
+var t T
 </pre>
 
 <p>
@@ -3190,8 +3238,8 @@ by any predeclared type in the language. The following are legal declarations:
 </p>
 
 <pre>
-const Huge = 1 &lt;&lt; 100;
-const Four int8 = Huge &gt;&gt; 98;
+const Huge = 1 &lt;&lt; 100
+const Four int8 = Huge &gt;&gt; 98
 </pre>
 
 <p>
@@ -3277,20 +3325,8 @@ Statement =
        DeferStmt .
 
 SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl .
-
-StatementList = Statement { Separator Statement } .
-Separator     = [ ";" ] .
 </pre>
 
-<p>
-Elements of a list of statements are separated by semicolons,
-which may be omitted only if the previous statement:
-</p>
-<ul>
-       <li>ends with the closing parenthesis ")" of a list of <a href="#Declarations_and_scope">declarations</a>; or</li>
-       <li>ends with a closing brace "}" that is not part of an expression.
-</ul>
-
 
 <h3 id="Empty_statements">Empty statements</h3>
 
@@ -3302,11 +3338,6 @@ The empty statement does nothing.
 EmptyStmt = .
 </pre>
 
-<p>
-A statement list can always be terminated with a semicolon, in effect
-adding an empty statement.
-</p>
-
 
 <h3 id="Labeled_statements">Labeled statements</h3>
 
@@ -3479,12 +3510,12 @@ executes before the expression is evaluated.
 </p>
 
 <pre>
-if x := f(); x < y {
-       return x;
+if x := f(); x &lt; y {
+       return x
 } else if x > z {
-       return z;
+       return z
 } else {
-       return y;
+       return y
 }
 </pre>
 
@@ -3530,7 +3561,7 @@ the expression <code>true</code>.
 
 <pre class="ebnf">
 ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
-ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
+ExprCaseClause = ExprSwitchCase ":" { Statement ";" } .
 ExprSwitchCase = "case" ExpressionList | "default" .
 </pre>
 
@@ -3555,15 +3586,15 @@ case 0, 1, 2, 3: s1()
 case 4, 5, 6, 7: s2()
 }
 
-switch x := f(); {  // missing switch expression means "true"
+switch x := f() {  // missing switch expression means "true"
 case x &lt; 0: return -x
 default: return x
 }
 
 switch {
-case x &lt; y: f1();
-case x &lt; z: f2();
-case x == 4: f3();
+case x &lt; y: f1()
+case x &lt; z: f2()
+case x == 4: f3()
 }
 </pre>
 
@@ -3581,7 +3612,7 @@ in the type assertion.
 <pre class="ebnf">
 TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
 TypeSwitchGuard = [ identifier ":=" ] Expression "." "(" "type" ")" .
-TypeCaseClause  = TypeSwitchCase ":" [ StatementList ] .
+TypeCaseClause  = TypeSwitchCase ":" { Statement ";" } .
 TypeSwitchCase  = "case" TypeList | "default" .
 TypeList        = Type { "," Type } .
 </pre>
@@ -3610,17 +3641,17 @@ the following type switch:
 <pre>
 switch i := x.(type) {
 case nil:
-       printString("x is nil");
+       printString("x is nil")
 case int:
-       printInt(i);  // i is an int
+       printInt(i)  // i is an int
 case float:
-       printFloat(i);  // i is a float
+       printFloat(i)  // i is a float
 case func(int) float:
-       printFunction(i);  // i is a function
+       printFunction(i)  // i is a function
 case bool, string:
-       printString("type is bool or string");  // i is an interface{}
+       printString("type is bool or string")  // i is an interface{}
 default:
-       printString("don't know the type");
+       printString("don't know the type")
 }
 </pre>
 
@@ -3629,24 +3660,24 @@ could be rewritten:
 </p>
 
 <pre>
-v := x;  // x is evaluated exactly once
+v := x  // x is evaluated exactly once
 if v == nil {
-       printString("x is nil");
+       printString("x is nil")
 } else if i, is_int := v.(int); is_int {
-       printInt(i);  // i is an int
+       printInt(i)  // i is an int
 } else if i, is_float := v.(float); is_float {
-       printFloat(i);  // i is a float
+       printFloat(i)  // i is a float
 } else if i, is_func := v.(func(int) float); is_func {
-       printFunction(i);  // i is a function
+       printFunction(i)  // i is a function
 } else {
-       i1, is_bool := v.(bool);
-       i2, is_string := v.(string);
+       i1, is_bool := v.(bool)
+       i2, is_string := v.(string)
        if is_bool || is_string {
-               i := v;
-               printString("type is bool or string");  // i is an interface{}
+               i := v
+               printString("type is bool or string")  // i is an interface{}
        } else {
-               i := v;
-               printString("don't know the type");  // i is an interface{}
+               i := v
+               printString("don't know the type")  // i is an interface{}
        }
 }
 </pre>
@@ -3694,13 +3725,13 @@ an increment or decrement statement. The init statement may be a
 </p>
 
 <pre class="ebnf">
-ForClause = InitStmt ";" [ Condition ] ";" PostStmt .
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
 InitStmt = SimpleStmt .
 PostStmt = SimpleStmt .
 </pre>
 
 <pre>
-for i := 0; i < 10; i++ {
+for i := 0; i &lt; 10; i++ {
        f(i)
 }
 </pre>
@@ -3710,7 +3741,8 @@ If non-empty, the init statement is executed once before evaluating the
 condition for the first iteration;
 the post statement is executed after each execution of the block (and
 only if the block was executed).
-Any element of the ForClause may be empty but the semicolons are
+Any element of the ForClause may be empty but the
+<a href="#Semicolons">semicolons</a> are
 required unless there is only a condition.
 If the condition is absent, it is equivalent to <code>true</code>.
 </p>
@@ -3776,8 +3808,8 @@ after execution their values will be those of the last iteration.
 </p>
 
 <pre>
-var a [10]string;
-m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6};
+var a [10]string
+m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
 
 for i, s := range a {
        // type of i is int
@@ -3786,8 +3818,8 @@ for i, s := range a {
        g(i, s)
 }
 
-var key string;
-var val interface {};  // value type of m is assignment compatible with val
+var key string
+var val interface {}  // value type of m is assignment compatible with val
 for key, val = range m {
        h(key, val)
 }
@@ -3835,7 +3867,7 @@ cases all referring to communication operations.
 
 <pre class="ebnf">
 SelectStmt = "select" "{" { CommClause } "}" .
-CommClause = CommCase ":" StatementList .
+CommClause = CommCase ":" { Statement ";" } .
 CommCase = "case" ( SendExpr | RecvExpr) | "default" .
 SendExpr =  Expression "&lt;-" Expression .
 RecvExpr =  [ Expression ( "=" | ":=" ) ] "&lt;-" Expression .
@@ -3870,15 +3902,15 @@ The receive case may declare a new variable using a
 </p>
 
 <pre>
-var c, c1, c2 chan int;
-var i1, i2 int;
+var c, c1, c2 chan int
+var i1, i2 int
 select {
 case i1 = &lt;-c1:
-       print("received ", i1, " from c1\n");
+       print("received ", i1, " from c1\n")
 case c2 &lt;- i2:
-       print("sent ", i2, " to c2\n");
+       print("sent ", i2, " to c2\n")
 default:
-       print("no communication\n");
+       print("no communication\n")
 }
 
 for {  // send random sequence of bits to c
@@ -3952,9 +3984,9 @@ func complex_f2() (re float, im float) {
                The "return" statement returns the values of these variables.
 <pre>
 func complex_f3() (re float, im float) {
-       re = 7.0;
-       im = 4.0;
-       return;
+       re = 7.0
+       im = 4.0
+       return
 }
 </pre>
        </li>
@@ -3978,7 +4010,7 @@ A "break" statement terminates execution of the innermost
 </p>
 
 <pre class="ebnf">
-BreakStmt = "break" [ Label ].
+BreakStmt = "break" [ Label ] .
 </pre>
 
 <p>
@@ -3989,7 +4021,7 @@ terminates
 </p>
 
 <pre>
-L: for i < n {
+L: for i &lt; n {
        switch i {
                case 5: break L
        }
@@ -4004,7 +4036,7 @@ innermost "for" loop at its post statement (§<a href="#For_statements">For stat
 </p>
 
 <pre class="ebnf">
-ContinueStmt = "continue" [ Label ].
+ContinueStmt = "continue" [ Label ] .
 </pre>
 
 <p>
@@ -4032,8 +4064,8 @@ instance, this example:
 </p>
 
 <pre>
-goto L;  // BAD
-v := 3;
+goto L  // BAD
+v := 3
 L:
 </pre>
 
@@ -4081,12 +4113,12 @@ but after the return values, if any, have been evaluated.
 </p>
 
 <pre>
-lock(l);
-defer unlock(l);  // unlocking happens before surrounding function returns
+lock(l)
+defer unlock(l)  // unlocking happens before surrounding function returns
 
 // prints 3 2 1 0 before surrounding function returns
 for i := 0; i &lt;= 3; i++ {
-       defer fmt.Print(i);
+       defer fmt.Print(i)
 }
 </pre>
 
@@ -4218,10 +4250,10 @@ buffered channels:
 </p>
 
 <pre>
-s := make([]int, 10, 100);        // slice with len(s) == 10, cap(s) == 100
-s := make([]int, 10);             // slice with len(s) == cap(s) == 10
-c := make(chan int, 10);          // channel with a buffer size of 10
-m := make(map[string] int, 100);  // map with initial space for 100 elements
+s := make([]int, 10, 100)        // slice with len(s) == 10, cap(s) == 100
+s := make([]int, 10)             // slice with len(s) == cap(s) == 10
+c := make(chan int, 10)          // channel with a buffer size of 10
+m := make(map[string] int, 100)  // map with initial space for 100 elements
 </pre>
 
 
@@ -4246,10 +4278,10 @@ Examples:
 </p>
 
 <pre>
-var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7};
-var s = make([]int, 6);
-n1 := copy(s, &amp;a);     // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-n2 := copy(s, s[2:]);  // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+n1 := copy(s, &amp;a)     // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:])  // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
 </pre>
 
 
@@ -4293,7 +4325,7 @@ types, variables, and constants.
 </p>
 
 <pre class="ebnf">
-SourceFile       = PackageClause { ImportDecl [ ";" ] } { TopLevelDecl [ ";" ] } .
+SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
 </pre>
 
 <h3 id="Package_clause">Package clause</h3>
@@ -4333,10 +4365,9 @@ that specifies the package to be imported.
 </p>
 
 <pre class="ebnf">
-ImportDecl       = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
-ImportSpecList   = ImportSpec { ";" ImportSpec } [ ";" ] .
+ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
 ImportSpec       = [ "." | PackageName ] ImportPath .
-ImportPath       = StringLit .
+ImportPath       = string_lit .
 </pre>
 
 <p>
@@ -4402,7 +4433,7 @@ import "fmt"
 // Send the sequence 2, 3, 4, ... to channel 'ch'.
 func generate(ch chan&lt;- int) {
        for i := 2; ; i++ {
-               ch &lt;- i;     // Send 'i' to channel 'ch'.
+               ch &lt;- i  // Send 'i' to channel 'ch'.
        }
 }
 
@@ -4411,26 +4442,26 @@ func generate(ch chan&lt;- int) {
 func filter(src &lt;-chan int, dst chan&lt;- int, prime int) {
        for i := range src {    // Loop over values received from 'src'.
                if i%prime != 0 {
-                       dst &lt;- i;    // Send 'i' to channel 'dst'.
+                       dst &lt;- i  // Send 'i' to channel 'dst'.
                }
        }
 }
 
 // The prime sieve: Daisy-chain filter processes together.
 func sieve() {
-       ch := make(chan int)  // Create a new channel.
-       go generate(ch)       // Start generate() as a subprocess.
+       ch := make(chan int)  // Create a new channel.
+       go generate(ch)       // Start generate() as a subprocess.
        for {
-               prime := &lt;-ch;
-               fmt.Print(prime, "\n");
-               ch1 := make(chan int);
-               go filter(ch, ch1, prime);
-               ch = ch1;
+               prime := &lt;-ch
+               fmt.Print(prime, "\n")
+               ch1 := make(chan int)
+               go filter(ch, ch1, prime)
+               ch = ch1
        }
 }
 
 func main() {
-       sieve();
+       sieve()
 }
 </pre>
 
@@ -4453,8 +4484,8 @@ These two simple declarations are equivalent:
 </p>
 
 <pre>
-var i int;
-var i int = 0;
+var i int
+var i int = 0
 </pre>
 
 <p>
@@ -4462,8 +4493,8 @@ After
 </p>
 
 <pre>
-type T struct { i int; f float; next *T };
-t := new(T);
+type T struct { i int; f float; next *T }
+t := new(T)
 </pre>
 
 <p>