LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file contains the mechanism to "linkify" html source | 5 // This file contains the mechanism to "linkify" html source |
6 // text containing EBNF sections (as found in go_spec.html). | 6 // text containing EBNF sections (as found in go_spec.html). |
7 // The result is the input source text with the EBNF sections | 7 // The result is the input source text with the EBNF sections |
8 // modified such that identifiers are linked to the respective | 8 // modified such that identifiers are linked to the respective |
9 // definitions. | 9 // definitions. |
10 | 10 |
11 package main | 11 package main |
12 | 12 |
13 import ( | 13 import ( |
14 "bytes" | 14 "bytes" |
15 "fmt" | 15 "fmt" |
16 "go/scanner" | 16 "go/scanner" |
17 "go/token" | 17 "go/token" |
18 "io" | 18 "io" |
19 ) | 19 ) |
20 | 20 |
21 | 21 |
22 type ebnfParser struct { | 22 type ebnfParser struct { |
23 out io.Writer // parser output | 23 out io.Writer // parser output |
24 src []byte // parser source | 24 src []byte // parser source |
25 file *token.File // for position information | 25 file *token.File // for position information |
26 scanner scanner.Scanner | 26 scanner scanner.Scanner |
27 prev int // offset of previous token | 27 prev int // offset of previous token |
28 pos token.Pos // token position | 28 pos token.Pos // token position |
29 tok token.Token // one token look-ahead | 29 tok token.Token // one token look-ahead |
30 » lit []byte // token literal | 30 » lit string // token literal |
31 } | 31 } |
32 | 32 |
33 | 33 |
34 func (p *ebnfParser) flush() { | 34 func (p *ebnfParser) flush() { |
35 offs := p.file.Offset(p.pos) | 35 offs := p.file.Offset(p.pos) |
36 p.out.Write(p.src[p.prev:offs]) | 36 p.out.Write(p.src[p.prev:offs]) |
37 p.prev = offs | 37 p.prev = offs |
38 } | 38 } |
39 | 39 |
40 | 40 |
(...skipping 15 matching lines...) Expand all Loading... |
56 } | 56 } |
57 | 57 |
58 | 58 |
59 func (p *ebnfParser) errorExpected(pos token.Pos, msg string) { | 59 func (p *ebnfParser) errorExpected(pos token.Pos, msg string) { |
60 msg = "expected " + msg | 60 msg = "expected " + msg |
61 if pos == p.pos { | 61 if pos == p.pos { |
62 // the error happened at the current position; | 62 // the error happened at the current position; |
63 // make the error message more specific | 63 // make the error message more specific |
64 msg += ", found '" + p.tok.String() + "'" | 64 msg += ", found '" + p.tok.String() + "'" |
65 if p.tok.IsLiteral() { | 65 if p.tok.IsLiteral() { |
66 » » » msg += " " + string(p.lit) | 66 » » » msg += " " + p.lit |
67 } | 67 } |
68 } | 68 } |
69 p.Error(p.file.Position(pos), msg) | 69 p.Error(p.file.Position(pos), msg) |
70 } | 70 } |
71 | 71 |
72 | 72 |
73 func (p *ebnfParser) expect(tok token.Token) token.Pos { | 73 func (p *ebnfParser) expect(tok token.Token) token.Pos { |
74 pos := p.pos | 74 pos := p.pos |
75 if p.tok != tok { | 75 if p.tok != tok { |
76 p.errorExpected(pos, "'"+tok.String()+"'") | 76 p.errorExpected(pos, "'"+tok.String()+"'") |
77 } | 77 } |
78 p.next() // make progress in any case | 78 p.next() // make progress in any case |
79 return pos | 79 return pos |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 func (p *ebnfParser) parseIdentifier(def bool) { | 83 func (p *ebnfParser) parseIdentifier(def bool) { |
84 » name := string(p.lit) | 84 » name := p.lit |
85 p.expect(token.IDENT) | 85 p.expect(token.IDENT) |
86 if def { | 86 if def { |
87 fmt.Fprintf(p.out, `<a id="%s">%s</a>`, name, name) | 87 fmt.Fprintf(p.out, `<a id="%s">%s</a>`, name, name) |
88 } else { | 88 } else { |
89 fmt.Fprintf(p.out, `<a href="#%s" class="noline">%s</a>`, name,
name) | 89 fmt.Fprintf(p.out, `<a href="#%s" class="noline">%s</a>`, name,
name) |
90 } | 90 } |
91 p.prev += len(name) // skip identifier when calling flush | 91 p.prev += len(name) // skip identifier when calling flush |
92 } | 92 } |
93 | 93 |
94 | 94 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // write text before EBNF | 197 // write text before EBNF |
198 out.Write(src[0:i]) | 198 out.Write(src[0:i]) |
199 // parse and write EBNF | 199 // parse and write EBNF |
200 var p ebnfParser | 200 var p ebnfParser |
201 p.parse(fset, out, src[i:j]) | 201 p.parse(fset, out, src[i:j]) |
202 | 202 |
203 // advance | 203 // advance |
204 src = src[j:n] | 204 src = src[j:n] |
205 } | 205 } |
206 } | 206 } |
LEFT | RIGHT |