diff options
Diffstat (limited to 'src/cmd/godoc/spec.go')
-rw-r--r-- | src/cmd/godoc/spec.go | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/src/cmd/godoc/spec.go b/src/cmd/godoc/spec.go deleted file mode 100644 index 444e36e08..000000000 --- a/src/cmd/godoc/spec.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains the mechanism to "linkify" html source -// text containing EBNF sections (as found in go_spec.html). -// The result is the input source text with the EBNF sections -// modified such that identifiers are linked to the respective -// definitions. - -package main - -import ( - "bytes" - "fmt" - "go/scanner" - "go/token" - "io" -) - - -type ebnfParser struct { - out io.Writer // parser output - src []byte // parser source - file *token.File // for position information - scanner scanner.Scanner - prev int // offset of previous token - pos token.Pos // token position - tok token.Token // one token look-ahead - lit string // token literal -} - - -func (p *ebnfParser) flush() { - offs := p.file.Offset(p.pos) - p.out.Write(p.src[p.prev:offs]) - p.prev = offs -} - - -func (p *ebnfParser) next() { - if p.pos.IsValid() { - p.flush() - } - p.pos, p.tok, p.lit = p.scanner.Scan() - if p.tok.IsKeyword() { - // TODO Should keyword mapping always happen outside scanner? - // Or should there be a flag to scanner to enable keyword mapping? - p.tok = token.IDENT - } -} - - -func (p *ebnfParser) Error(pos token.Position, msg string) { - fmt.Fprintf(p.out, `<span class="alert">error: %s</span>`, msg) -} - - -func (p *ebnfParser) errorExpected(pos token.Pos, msg string) { - msg = "expected " + msg - if pos == p.pos { - // the error happened at the current position; - // make the error message more specific - msg += ", found '" + p.tok.String() + "'" - if p.tok.IsLiteral() { - msg += " " + p.lit - } - } - p.Error(p.file.Position(pos), msg) -} - - -func (p *ebnfParser) expect(tok token.Token) token.Pos { - pos := p.pos - if p.tok != tok { - p.errorExpected(pos, "'"+tok.String()+"'") - } - p.next() // make progress in any case - return pos -} - - -func (p *ebnfParser) parseIdentifier(def bool) { - name := p.lit - p.expect(token.IDENT) - if def { - fmt.Fprintf(p.out, `<a id="%s">%s</a>`, name, name) - } else { - fmt.Fprintf(p.out, `<a href="#%s" class="noline">%s</a>`, name, name) - } - p.prev += len(name) // skip identifier when calling flush -} - - -func (p *ebnfParser) parseTerm() bool { - switch p.tok { - case token.IDENT: - p.parseIdentifier(false) - - case token.STRING: - p.next() - const ellipsis = "…" // U+2026, the horizontal ellipsis character - if p.tok == token.ILLEGAL && p.lit == ellipsis { - p.next() - p.expect(token.STRING) - } - - case token.LPAREN: - p.next() - p.parseExpression() - p.expect(token.RPAREN) - - case token.LBRACK: - p.next() - p.parseExpression() - p.expect(token.RBRACK) - - case token.LBRACE: - p.next() - p.parseExpression() - p.expect(token.RBRACE) - - default: - return false - } - - return true -} - - -func (p *ebnfParser) parseSequence() { - if !p.parseTerm() { - p.errorExpected(p.pos, "term") - } - for p.parseTerm() { - } -} - - -func (p *ebnfParser) parseExpression() { - for { - p.parseSequence() - if p.tok != token.OR { - break - } - p.next() - } -} - - -func (p *ebnfParser) parseProduction() { - p.parseIdentifier(true) - p.expect(token.ASSIGN) - if p.tok != token.PERIOD { - p.parseExpression() - } - p.expect(token.PERIOD) -} - - -func (p *ebnfParser) parse(fset *token.FileSet, out io.Writer, src []byte) { - // initialize ebnfParser - p.out = out - p.src = src - p.file = fset.AddFile("", fset.Base(), len(src)) - p.scanner.Init(p.file, src, p, scanner.AllowIllegalChars) - p.next() // initializes pos, tok, lit - - // process source - for p.tok != token.EOF { - p.parseProduction() - } - p.flush() -} - - -// Markers around EBNF sections -var ( - openTag = []byte(`<pre class="ebnf">`) - closeTag = []byte(`</pre>`) -) - - -func linkify(out io.Writer, src []byte) { - fset := token.NewFileSet() - for len(src) > 0 { - n := len(src) - - // i: beginning of EBNF text (or end of source) - i := bytes.Index(src, openTag) - if i < 0 { - i = n - len(openTag) - } - i += len(openTag) - - // j: end of EBNF text (or end of source) - j := bytes.Index(src[i:n], closeTag) // close marker - if j < 0 { - j = n - i - } - j += i - - // write text before EBNF - out.Write(src[0:i]) - // parse and write EBNF - var p ebnfParser - p.parse(fset, out, src[i:j]) - - // advance - src = src[j:n] - } -} |