mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
go spec: be precise with the use of the informal ellipsis … and the Go token ...
Fixes #1867. R=r CC=golang-dev https://golang.org/cl/4538092
This commit is contained in:
parent
46f482a2fc
commit
3c7271f057
4 changed files with 32 additions and 26 deletions
|
@ -48,7 +48,7 @@ The syntax is specified using Extended Backus-Naur Form (EBNF):
|
|||
Production = production_name "=" [ Expression ] "." .
|
||||
Expression = Alternative { "|" Alternative } .
|
||||
Alternative = Term { Term } .
|
||||
Term = production_name | token [ "..." token ] | Group | Option | Repetition .
|
||||
Term = production_name | token [ "…" token ] | Group | Option | Repetition .
|
||||
Group = "(" Expression ")" .
|
||||
Option = "[" Expression "]" .
|
||||
Repetition = "{" Expression "}" .
|
||||
|
@ -72,8 +72,12 @@ double quotes <code>""</code> or back quotes <code>``</code>.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
The form <code>a ... b</code> represents the set of characters from
|
||||
<code>a</code> through <code>b</code> as alternatives.
|
||||
The form <code>a … b</code> represents the set of characters from
|
||||
<code>a</code> through <code>b</code> as alternatives. The horizontal
|
||||
ellipis … is also used elsewhere in the spec to informally denote various
|
||||
enumerations or code snippets that are not further specified. The character …
|
||||
(as opposed to the three characters <code>...</code>) is not a token of the Go
|
||||
language.
|
||||
</p>
|
||||
|
||||
<h2 id="Source_code_representation">Source code representation</h2>
|
||||
|
@ -122,9 +126,9 @@ The underscore character <code>_</code> (U+005F) is considered a letter.
|
|||
</p>
|
||||
<pre class="ebnf">
|
||||
letter = unicode_letter | "_" .
|
||||
decimal_digit = "0" ... "9" .
|
||||
octal_digit = "0" ... "7" .
|
||||
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
|
||||
decimal_digit = "0" … "9" .
|
||||
octal_digit = "0" … "7" .
|
||||
hex_digit = "0" … "9" | "A" … "F" | "a" … "f" .
|
||||
</pre>
|
||||
|
||||
<h2 id="Lexical_elements">Lexical elements</h2>
|
||||
|
@ -286,7 +290,7 @@ An optional prefix sets a non-decimal base: <code>0</code> for octal, <code>0x</
|
|||
</p>
|
||||
<pre class="ebnf">
|
||||
int_lit = decimal_lit | octal_lit | hex_lit .
|
||||
decimal_lit = ( "1" ... "9" ) { decimal_digit } .
|
||||
decimal_lit = ( "1" … "9" ) { decimal_digit } .
|
||||
octal_lit = "0" { octal_digit } .
|
||||
hex_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } .
|
||||
</pre>
|
||||
|
@ -1053,9 +1057,9 @@ have the method set
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
func (p T) Read(b Buffer) bool { return ... }
|
||||
func (p T) Write(b Buffer) bool { return ... }
|
||||
func (p T) Close() { ... }
|
||||
func (p T) Read(b Buffer) bool { return … }
|
||||
func (p T) Write(b Buffer) bool { return … }
|
||||
func (p T) Close() { … }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -1093,8 +1097,8 @@ If <code>S1</code> and <code>S2</code> also implement
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
func (p T) Lock() { ... }
|
||||
func (p T) Unlock() { ... }
|
||||
func (p T) Lock() { … }
|
||||
func (p T) Unlock() { … }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -2099,7 +2103,7 @@ element index plus one. A slice literal has the form
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
[]T{x1, x2, ... xn}
|
||||
[]T{x1, x2, … xn}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -2107,7 +2111,7 @@ and is a shortcut for a slice operation applied to an array literal:
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
[n]T{x1, x2, ... xn}[0 : n]
|
||||
[n]T{x1, x2, … xn}[0 : n]
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -2133,8 +2137,8 @@ parentheses.
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
if x == (T{a,b,c}[i]) { ... }
|
||||
if (x == T{a,b,c}[i]) { ... }
|
||||
if x == (T{a,b,c}[i]) { … }
|
||||
if (x == T{a,b,c}[i]) { … }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -2567,11 +2571,11 @@ Given an expression <code>f</code> of function type
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
f(a1, a2, ... an)
|
||||
f(a1, a2, … an)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
calls <code>f</code> with arguments <code>a1, a2, ... an</code>.
|
||||
calls <code>f</code> with arguments <code>a1, a2, … an</code>.
|
||||
Except for one special case, arguments must be single-valued expressions
|
||||
<a href="#Assignability">assignable</a> to the parameter types of
|
||||
<code>F</code> and are evaluated before the function is called.
|
||||
|
@ -2650,7 +2654,7 @@ arguments bound to the final parameter and may differ for each call site.
|
|||
Given the function and call
|
||||
</p>
|
||||
<pre>
|
||||
func Greeting(prefix string, who ... string)
|
||||
func Greeting(prefix string, who ...string)
|
||||
Greeting("hello:", "Joe", "Anna", "Eileen")
|
||||
</pre>
|
||||
|
||||
|
@ -4891,7 +4895,7 @@ package main
|
|||
|
||||
import "fmt"
|
||||
|
||||
// Send the sequence 2, 3, 4, ... to channel 'ch'.
|
||||
// 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'.
|
||||
|
@ -5042,7 +5046,7 @@ arguments and returns no value.
|
|||
</p>
|
||||
|
||||
<pre>
|
||||
func main() { ... }
|
||||
func main() { … }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -99,7 +99,8 @@ func (p *ebnfParser) parseTerm() bool {
|
|||
|
||||
case token.STRING:
|
||||
p.next()
|
||||
if p.tok == token.ELLIPSIS {
|
||||
const ellipsis = "…" // U+2026, the horizontal ellipsis character
|
||||
if p.tok == token.ILLEGAL && p.lit == ellipsis {
|
||||
p.next()
|
||||
p.expect(token.STRING)
|
||||
}
|
||||
|
@ -157,7 +158,7 @@ func (p *ebnfParser) parse(fset *token.FileSet, out io.Writer, src []byte) {
|
|||
p.out = out
|
||||
p.src = src
|
||||
p.file = fset.AddFile("", fset.Base(), len(src))
|
||||
p.scanner.Init(p.file, src, p, 0)
|
||||
p.scanner.Init(p.file, src, p, scanner.AllowIllegalChars)
|
||||
p.next() // initializes pos, tok, lit
|
||||
|
||||
// process source
|
||||
|
|
|
@ -22,7 +22,7 @@ var grammars = []string{
|
|||
|
||||
`Program = "a" | "b" "c" .`,
|
||||
|
||||
`Program = "a" ... "z" .`,
|
||||
`Program = "a" … "z" .`,
|
||||
|
||||
`Program = Song .
|
||||
Song = { Note } .
|
||||
|
|
|
@ -95,7 +95,8 @@ func (p *parser) parseTerm() (x Expression) {
|
|||
case token.STRING:
|
||||
tok := p.parseToken()
|
||||
x = tok
|
||||
if p.tok == token.ELLIPSIS {
|
||||
const ellipsis = "…" // U+2026, the horizontal ellipsis character
|
||||
if p.tok == token.ILLEGAL && p.lit == ellipsis {
|
||||
p.next()
|
||||
x = &Range{tok, p.parseToken()}
|
||||
}
|
||||
|
@ -177,7 +178,7 @@ func (p *parser) parse(fset *token.FileSet, filename string, src []byte) Grammar
|
|||
// initialize parser
|
||||
p.fset = fset
|
||||
p.ErrorVector.Reset()
|
||||
p.scanner.Init(fset.AddFile(filename, fset.Base(), len(src)), src, p, 0)
|
||||
p.scanner.Init(fset.AddFile(filename, fset.Base(), len(src)), src, p, scanner.AllowIllegalChars)
|
||||
p.next() // initializes pos, tok, lit
|
||||
|
||||
grammar := make(Grammar)
|
||||
|
|
Loading…
Reference in a new issue