From 130ac74010af410f8d162a530271ad5078557093 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 10 Dec 2009 16:43:01 -0800 Subject: [PATCH] Spec modified to reflect new semicolon rules. R=rsc, r, iant, ken2 CC=golang-dev https://golang.org/cl/166066 --- doc/go_spec.html | 515 +++++++++++++++++++++++++---------------------- 1 file changed, 273 insertions(+), 242 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 6c4862e668b..5aed74e00ae 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -126,12 +126,27 @@ hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .

Comments

-There are two forms of comments. The first starts at the character -sequence // and continues through the next newline. The -second starts at the character sequence /* and continues -through the character sequence */. Comments do not nest. +There are two forms of comments:

+
    +
  1. +Line comments start with the character sequence // +and continue through the next newline. A line comment acts like a newline. +
  2. +
  3. +General comments start with the character sequence /* +and continue through the character sequence */. A general +comment that spans multiple lines acts like a newline, otherwise it acts +like a space. +
  4. +
+ +

+Comments do not nest. +

+ +

Tokens

@@ -141,12 +156,52 @@ and delimiters, and literals. White space, 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.

+

Semicolons

+ +

+The formal grammar uses semicolons ";" as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +

+ +
    +
  1. +

    +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 +

    +
      +
    • an identifier or basic literal +
    • one of the keywords + break, continue, fallthrough, + or return +
    • +
    • one of the operators and delimiters + ++, --, ), ], + or } +
    • +
    +
  2. + +
  3. +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing ")" or "}". +
  4. +
+ +

+To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +

+ +

Identifiers

@@ -163,7 +218,11 @@ _x9 ThisVariableIsExported αβ + +

Some identifiers are predeclared. +

+

Keywords

@@ -359,12 +418,7 @@ the two bytes 0xc3 0xbf of the UTF-8 encoding of chara U+00FF.

-

-A sequence of string literals is concatenated to form a single string constant. -

-
-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."
 

@@ -712,11 +764,10 @@ be unique.

-StructType     = "struct" "{" [ FieldDeclList ] "}" .
-FieldDeclList  = FieldDecl { ";" FieldDecl } [ ";" ] .
+StructType     = "struct" "{" { FieldDecl ";" } "}" .
 FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
 AnonymousField = [ "*" ] TypeName .
-Tag            = StringLit .
+Tag            = string_lit .
 
@@ -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()
 }
 
@@ -744,11 +795,11 @@ a pointer type. The unqualified type name acts as the field name.
 // 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
 }
 
@@ -759,9 +810,9 @@ in a struct type:
 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
 }
 
@@ -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" } @@ -835,7 +886,7 @@ A function value may be nil. FunctionType = "func" Signature . Signature = Parameters [ Result ] . Result = Parameters | Type . -Parameters = "(" [ ParameterList ] ")" . +Parameters = "(" [ ParameterList [ "," ] ] ")" . ParameterList = ParameterDecl { "," ParameterDecl } . ParameterDecl = [ IdentifierList ] ( Type | "..." ) . @@ -878,8 +929,7 @@ that is any superset of the interface. Such a type is said to

-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
 
 // A simple File interface
 interface {
-	Read(b Buffer) bool;
-	Write(b Buffer) bool;
-	Close();
+	Read(b Buffer) bool
+	Write(b Buffer) bool
+	Close()
 }
 
@@ -935,8 +985,8 @@ to define an interface called Lock:
 type Lock interface {
-	Lock();
-	Unlock();
+	Lock()
+	Unlock()
 }
 
@@ -962,14 +1012,14 @@ in the interface.
 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()
 }
 
@@ -1144,12 +1194,12 @@ Given the declarations
 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
 )
 
@@ -1297,7 +1347,7 @@ brace brackets.

-Block = "{" StatementList "}" .
+Block = "{" { Statement ";" } "}" .
 

@@ -1459,8 +1509,7 @@ right.

-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:
 
 
 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
 )
 
@@ -1522,31 +1571,32 @@ const ( Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. It is reset to 0 whenever the reserved word const -appears in the source and increments with each semicolon. It can be used to construct a +appears in the source and increments with each +semicolon. It can be used to construct a set of related constants:

 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 << iota;  // a == 1 (iota has been reset)
-	b = 1 << iota;  // b == 2
-	c = 1 << iota;  // c == 4
+	a = 1 << iota  // a == 1 (iota has been reset)
+	b = 1 << iota  // b == 2
+	c = 1 << 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)
 

@@ -1556,10 +1606,10 @@ it is only incremented at a semicolon:

 const (
-	bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
-	bit1, mask1;                             // bit1 == 2, mask1 == 1
-	_, _;                                    // skips iota == 2
-	bit3, mask3;                             // bit3 == 8, mask3 == 7
+	bit0, mask0 = 1 << iota, 1 << iota - 1  // bit0 == 1, mask0 == 0
+	bit1, mask1                             // bit1 == 2, mask1 == 1
+	_, _                                    // skips iota == 2
+	bit3, mask3                             // bit3 == 8, mask3 == 7
 )
 
@@ -1580,8 +1630,7 @@ an existing type. The new type is

-TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
-TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
+TypeDecl     = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
 TypeSpec     = identifier Type .
 
@@ -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) }
@@ -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 }
@@ -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) } @@ -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.

-VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
-VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
+VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
 VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
 
@@ -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"

@@ -1721,11 +1769,11 @@ initializer expressions but no types:

-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
 

@@ -1738,8 +1786,8 @@ variable; it just assigns a new value to the original.

-field1, offset := nextField(str, 0);
-field2, offset := nextField(str, offset);  // redeclares offset
+field1, offset := nextField(str, 0)
+field2, offset := nextField(str, offset)  // redeclares offset
 

@@ -1768,9 +1816,9 @@ signature for a function implemented outside Go, such as an assembly routine.

 func min(x int, y int) int {
 	if x < y {
-		return x;
+		return x
 	}
-	return y;
+	return y
 }
 
 func flushICache(begin, end uintptr)  // implemented externally
@@ -1805,12 +1853,12 @@ Given type Point, the declarations
 
 
 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
 }
 
@@ -1856,7 +1904,7 @@ Operands denote the elementary values in an expression.
 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 .
 
@@ -1897,10 +1945,10 @@ a single expression or a key-value pair.

-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
 

-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
 

@@ -1983,7 +2031,7 @@ Taking the address of a composite literal (§Addres generates a unique pointer to an instance of the literal's value.

-var pointer *Point = &Point{y: 1000};
+var pointer *Point = &Point{y: 1000}
 

@@ -1996,9 +2044,9 @@ to the maximum element index plus one.

-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
 

@@ -2040,13 +2088,13 @@ Examples of valid array, slice, and map literals:

 // 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 [ "," ] ] ")" .
 
@@ -2200,26 +2248,26 @@ For example, given the declarations:
 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
 

@@ -2356,8 +2404,8 @@ After slicing the array a

-a := [5]int{1, 2, 3, 4, 5};
-s := a[1:4];
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
 

@@ -2463,7 +2511,7 @@ the method.

 math.Atan2(x, y)    // function call
-var pt *Point;
+var pt *Point
 pt.Scale(3.5)  // method call with receiver pt
 
@@ -2504,7 +2552,7 @@ for (&x).m():

-var p Point;
+var p Point
 p.Scale(3.5)
 
@@ -2540,7 +2588,7 @@ Given the function and call

 func Fprintf(f io.Writer, format string, args ...)
-Fprintf(os.Stdout, "%s %d", "hello", 23);
+Fprintf(os.Stdout, "%s %d", "hello", 23)
 

@@ -2610,12 +2658,12 @@ the left operand alone.

-var s uint = 33;
-var i = 1<<s;          // 1 has type int
-var j = int32(1<<s);   // 1 has type int32; j == 0
-var u = uint64(1<<s);  // 1 has type uint64; u == 1<<33
-var f = float(1<<s);   // illegal: 1 has type float, cannot shift
-var g = float(1<<33);  // legal; 1<<33 is a constant shift operation; g == 1<<33
+var s uint = 33
+var i = 1<<s          // 1 has type int
+var j = int32(1<<s)   // 1 has type int32; j == 0
+var u = uint64(1<<s)  // 1 has type uint64; u == 1<<33
+var f = float(1<<s)   // illegal: 1 has type float, cannot shift
+var g = float(1<<33)  // legal; 1<<33 is a constant shift operation; g == 1<<33
 

Operator precedence

@@ -2688,8 +2736,8 @@ or the += assignment operator:

-s := "hi" + string(c);
-s += " and good bye";
+s := "hi" + string(c)
+s += " and good bye"
 

@@ -2883,7 +2931,7 @@ These two examples are equivalent:

-ok := ch <- 3;
+ok := ch <- 3
 if ok { print("sent") } else { print("not sent") }
 
 if ch <- 3 { print("sent") } else { print("not sent") }
@@ -2968,11 +3016,11 @@ Consider a struct type T with two methods,
 
 
 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
 

@@ -3190,8 +3238,8 @@ by any predeclared type in the language. The following are legal declarations:

-const Huge = 1 << 100;
-const Four int8 = Huge >> 98;
+const Huge = 1 << 100
+const Four int8 = Huge >> 98
 

@@ -3277,20 +3325,8 @@ Statement = DeferStmt . SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl . - -StatementList = Statement { Separator Statement } . -Separator = [ ";" ] .

-

-Elements of a list of statements are separated by semicolons, -which may be omitted only if the previous statement: -

-
-

Empty statements

@@ -3302,11 +3338,6 @@ The empty statement does nothing. EmptyStmt = .
-

-A statement list can always be terminated with a semicolon, in effect -adding an empty statement. -

-

Labeled statements

@@ -3479,12 +3510,12 @@ executes before the expression is evaluated.

-if x := f(); x < y {
-	return x;
+if x := f(); x < y {
+	return x
 } else if x > z {
-	return z;
+	return z
 } else {
-	return y;
+	return y
 }
 
@@ -3530,7 +3561,7 @@ the expression true.
 ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
-ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
+ExprCaseClause = ExprSwitchCase ":" { Statement ";" } .
 ExprSwitchCase = "case" ExpressionList | "default" .
 
@@ -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 < 0: return -x default: return x } switch { -case x < y: f1(); -case x < z: f2(); -case x == 4: f3(); +case x < y: f1() +case x < z: f2() +case x == 4: f3() }
@@ -3581,7 +3612,7 @@ in the type assertion.
 TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
 TypeSwitchGuard = [ identifier ":=" ] Expression "." "(" "type" ")" .
-TypeCaseClause  = TypeSwitchCase ":" [ StatementList ] .
+TypeCaseClause  = TypeSwitchCase ":" { Statement ";" } .
 TypeSwitchCase  = "case" TypeList | "default" .
 TypeList        = Type { "," Type } .
 
@@ -3610,17 +3641,17 @@ the following type switch:
 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")
 }
 
@@ -3629,24 +3660,24 @@ could be rewritten:

-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{}
 	}
 }
 
@@ -3694,13 +3725,13 @@ an increment or decrement statement. The init statement may be a

-ForClause = InitStmt ";" [ Condition ] ";" PostStmt .
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
 InitStmt = SimpleStmt .
 PostStmt = SimpleStmt .
 
-for i := 0; i < 10; i++ {
+for i := 0; i < 10; i++ {
 	f(i)
 }
 
@@ -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 +semicolons are required unless there is only a condition. If the condition is absent, it is equivalent to true.

@@ -3776,8 +3808,8 @@ after execution their values will be those of the last iteration.

-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.
 
 
 SelectStmt = "select" "{" { CommClause } "}" .
-CommClause = CommCase ":" StatementList .
+CommClause = CommCase ":" { Statement ";" } .
 CommCase = "case" ( SendExpr | RecvExpr) | "default" .
 SendExpr =  Expression "<-" Expression .
 RecvExpr =  [ Expression ( "=" | ":=" ) ] "<-" Expression .
@@ -3870,15 +3902,15 @@ The receive case may declare a new variable using a
 

-var c, c1, c2 chan int;
-var i1, i2 int;
+var c, c1, c2 chan int
+var i1, i2 int
 select {
 case i1 = <-c1:
-	print("received ", i1, " from c1\n");
+	print("received ", i1, " from c1\n")
 case c2 <- 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.
 
 func complex_f3() (re float, im float) {
-	re = 7.0;
-	im = 4.0;
-	return;
+	re = 7.0
+	im = 4.0
+	return
 }
 
@@ -3978,7 +4010,7 @@ A "break" statement terminates execution of the innermost

-BreakStmt = "break" [ Label ].
+BreakStmt = "break" [ Label ] .
 

@@ -3989,7 +4021,7 @@ terminates

-L: for i < n {
+L: for i < n {
 	switch i {
 		case 5: break L
 	}
@@ -4004,7 +4036,7 @@ innermost "for" loop at its post statement (§For stat
 

-ContinueStmt = "continue" [ Label ].
+ContinueStmt = "continue" [ Label ] .
 

@@ -4032,8 +4064,8 @@ instance, this example:

-goto L;  // BAD
-v := 3;
+goto L  // BAD
+v := 3
 L:
 
@@ -4081,12 +4113,12 @@ but after the return values, if any, have been evaluated.

-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 <= 3; i++ {
-	defer fmt.Print(i);
+	defer fmt.Print(i)
 }
 
@@ -4218,10 +4250,10 @@ buffered channels:

-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
 
@@ -4246,10 +4278,10 @@ Examples:

-var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7};
-var s = make([]int, 6);
-n1 := copy(s, &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, &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}
 
@@ -4293,7 +4325,7 @@ types, variables, and constants.

-SourceFile       = PackageClause { ImportDecl [ ";" ] } { TopLevelDecl [ ";" ] } .
+SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
 

Package clause

@@ -4333,10 +4365,9 @@ that specifies the package to be imported.

-ImportDecl       = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
-ImportSpecList   = ImportSpec { ";" ImportSpec } [ ";" ] .
+ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
 ImportSpec       = [ "." | PackageName ] ImportPath .
-ImportPath       = StringLit .
+ImportPath       = string_lit .
 

@@ -4402,7 +4433,7 @@ import "fmt" // Send the sequence 2, 3, 4, ... to channel 'ch'. func generate(ch chan<- int) { for i := 2; ; i++ { - ch <- i; // Send 'i' to channel 'ch'. + ch <- i // Send 'i' to channel 'ch'. } } @@ -4411,26 +4442,26 @@ func generate(ch chan<- int) { func filter(src <-chan int, dst chan<- int, prime int) { for i := range src { // Loop over values received from 'src'. if i%prime != 0 { - dst <- i; // Send 'i' to channel 'dst'. + dst <- 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 := <-ch; - fmt.Print(prime, "\n"); - ch1 := make(chan int); - go filter(ch, ch1, prime); - ch = ch1; + prime := <-ch + fmt.Print(prime, "\n") + ch1 := make(chan int) + go filter(ch, ch1, prime) + ch = ch1 } } func main() { - sieve(); + sieve() }

@@ -4453,8 +4484,8 @@ These two simple declarations are equivalent:

-var i int;
-var i int = 0;
+var i int
+var i int = 0
 

@@ -4462,8 +4493,8 @@ After

-type T struct { i int; f float; next *T };
-t := new(T);
+type T struct { i int; f float; next *T }
+t := new(T)