OSDN Git Service

e744a63a96ec965bcd7294a3b1ac5c50e0b1cda4
[pf3gnuchains/gcc-fork.git] / libgo / go / exp / types / gcimporter.go
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file implements an ast.Importer for gc generated object files.
6 // TODO(gri) Eventually move this into a separate package outside types.
7
8 package types
9
10 import (
11         "big"
12         "fmt"
13         "go/ast"
14         "go/token"
15         "io"
16         "os"
17         "path/filepath"
18         "runtime"
19         "scanner"
20         "strconv"
21 )
22
23 const trace = false // set to true for debugging
24
25 var (
26         pkgRoot = filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH)
27         pkgExts = [...]string{".a", ".5", ".6", ".8"}
28 )
29
30 // findPkg returns the filename and package id for an import path.
31 // If no file was found, an empty filename is returned.
32 func findPkg(path string) (filename, id string) {
33         if len(path) == 0 {
34                 return
35         }
36
37         id = path
38         var noext string
39         switch path[0] {
40         default:
41                 // "x" -> "$GOROOT/pkg/$GOOS_$GOARCH/x.ext", "x"
42                 noext = filepath.Join(pkgRoot, path)
43
44         case '.':
45                 // "./x" -> "/this/directory/x.ext", "/this/directory/x"
46                 cwd, err := os.Getwd()
47                 if err != nil {
48                         return
49                 }
50                 noext = filepath.Join(cwd, path)
51                 id = noext
52
53         case '/':
54                 // "/x" -> "/x.ext", "/x"
55                 noext = path
56         }
57
58         // try extensions
59         for _, ext := range pkgExts {
60                 filename = noext + ext
61                 if f, err := os.Stat(filename); err == nil && f.IsRegular() {
62                         return
63                 }
64         }
65
66         filename = "" // not found
67         return
68 }
69
70 // gcParser parses the exports inside a gc compiler-produced
71 // object/archive file and populates its scope with the results.
72 type gcParser struct {
73         scanner scanner.Scanner
74         tok     int                    // current token
75         lit     string                 // literal string; only valid for Ident, Int, String tokens
76         id      string                 // package id of imported package
77         imports map[string]*ast.Object // package id -> package object
78 }
79
80 func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]*ast.Object) {
81         p.scanner.Init(src)
82         p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
83         p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
84         p.scanner.Whitespace = 1<<'\t' | 1<<' '
85         p.scanner.Filename = filename // for good error messages
86         p.next()
87         p.id = id
88         p.imports = imports
89 }
90
91 func (p *gcParser) next() {
92         p.tok = p.scanner.Scan()
93         switch p.tok {
94         case scanner.Ident, scanner.Int, scanner.String:
95                 p.lit = p.scanner.TokenText()
96         default:
97                 p.lit = ""
98         }
99         if trace {
100                 fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
101         }
102 }
103
104 // GcImporter implements the ast.Importer signature.
105 func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, err os.Error) {
106         if path == "unsafe" {
107                 return Unsafe, nil
108         }
109
110         defer func() {
111                 if r := recover(); r != nil {
112                         err = r.(importError) // will re-panic if r is not an importError
113                         if trace {
114                                 panic(err) // force a stack trace
115                         }
116                 }
117         }()
118
119         filename, id := findPkg(path)
120         if filename == "" {
121                 err = os.NewError("can't find import: " + id)
122                 return
123         }
124
125         if pkg = imports[id]; pkg != nil {
126                 return // package was imported before
127         }
128
129         buf, err := ExportData(filename)
130         if err != nil {
131                 return
132         }
133         defer buf.Close()
134
135         if trace {
136                 fmt.Printf("importing %s (%s)\n", id, filename)
137         }
138
139         var p gcParser
140         p.init(filename, id, buf, imports)
141         pkg = p.parseExport()
142         return
143 }
144
145 // Declare inserts a named object of the given kind in scope.
146 func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object {
147         // a type may have been declared before - if it exists
148         // already in the respective package scope, return that
149         // type
150         if kind == ast.Typ {
151                 if obj := scope.Lookup(name); obj != nil {
152                         assert(obj.Kind == ast.Typ)
153                         return obj
154                 }
155         }
156
157         // any other object must be a newly declared object -
158         // create it and insert it into the package scope
159         obj := ast.NewObj(kind, name)
160         if scope.Insert(obj) != nil {
161                 p.errorf("already declared: %v %s", kind, obj.Name)
162         }
163
164         // a new type object is a named type and may be referred
165         // to before the underlying type is known - set it up
166         if kind == ast.Typ {
167                 obj.Type = &Name{Obj: obj}
168         }
169
170         return obj
171 }
172
173 // ----------------------------------------------------------------------------
174 // Error handling
175
176 // Internal errors are boxed as importErrors.
177 type importError struct {
178         pos scanner.Position
179         err os.Error
180 }
181
182 func (e importError) String() string {
183         return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
184 }
185
186 func (p *gcParser) error(err interface{}) {
187         if s, ok := err.(string); ok {
188                 err = os.NewError(s)
189         }
190         // panic with a runtime.Error if err is not an os.Error
191         panic(importError{p.scanner.Pos(), err.(os.Error)})
192 }
193
194 func (p *gcParser) errorf(format string, args ...interface{}) {
195         p.error(fmt.Sprintf(format, args...))
196 }
197
198 func (p *gcParser) expect(tok int) string {
199         lit := p.lit
200         if p.tok != tok {
201                 p.errorf("expected %q, got %q (%q)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
202         }
203         p.next()
204         return lit
205 }
206
207 func (p *gcParser) expectSpecial(tok string) {
208         sep := 'x' // not white space
209         i := 0
210         for i < len(tok) && p.tok == int(tok[i]) && sep > ' ' {
211                 sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
212                 p.next()
213                 i++
214         }
215         if i < len(tok) {
216                 p.errorf("expected %q, got %q", tok, tok[0:i])
217         }
218 }
219
220 func (p *gcParser) expectKeyword(keyword string) {
221         lit := p.expect(scanner.Ident)
222         if lit != keyword {
223                 p.errorf("expected keyword %s, got %q", keyword, lit)
224         }
225 }
226
227 // ----------------------------------------------------------------------------
228 // Import declarations
229
230 // ImportPath = string_lit .
231 //
232 func (p *gcParser) parsePkgId() *ast.Object {
233         id, err := strconv.Unquote(p.expect(scanner.String))
234         if err != nil {
235                 p.error(err)
236         }
237
238         switch id {
239         case "":
240                 // id == "" stands for the imported package id
241                 // (only known at time of package installation)
242                 id = p.id
243         case "unsafe":
244                 // package unsafe is not in the imports map - handle explicitly
245                 return Unsafe
246         }
247
248         pkg := p.imports[id]
249         if pkg == nil {
250                 scope = ast.NewScope(nil)
251                 pkg = ast.NewObj(ast.Pkg, "")
252                 pkg.Data = scope
253                 p.imports[id] = pkg
254         }
255
256         return pkg
257 }
258
259 // dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
260 func (p *gcParser) parseDotIdent() string {
261         ident := ""
262         if p.tok != scanner.Int {
263                 sep := 'x' // not white space
264                 for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
265                         ident += p.lit
266                         sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
267                         p.next()
268                 }
269         }
270         if ident == "" {
271                 p.expect(scanner.Ident) // use expect() for error handling
272         }
273         return ident
274 }
275
276 // ExportedName = "@" ImportPath "." dotIdentifier .
277 //
278 func (p *gcParser) parseExportedName() (*ast.Object, string) {
279         p.expect('@')
280         pkg := p.parsePkgId()
281         p.expect('.')
282         name := p.parseDotIdent()
283         return pkg, name
284 }
285
286 // ----------------------------------------------------------------------------
287 // Types
288
289 // BasicType = identifier .
290 //
291 func (p *gcParser) parseBasicType() Type {
292         id := p.expect(scanner.Ident)
293         obj := Universe.Lookup(id)
294         if obj == nil || obj.Kind != ast.Typ {
295                 p.errorf("not a basic type: %s", id)
296         }
297         return obj.Type.(Type)
298 }
299
300 // ArrayType = "[" int_lit "]" Type .
301 //
302 func (p *gcParser) parseArrayType() Type {
303         // "[" already consumed and lookahead known not to be "]"
304         lit := p.expect(scanner.Int)
305         p.expect(']')
306         elt := p.parseType()
307         n, err := strconv.Atoui64(lit)
308         if err != nil {
309                 p.error(err)
310         }
311         return &Array{Len: n, Elt: elt}
312 }
313
314 // MapType = "map" "[" Type "]" Type .
315 //
316 func (p *gcParser) parseMapType() Type {
317         p.expectKeyword("map")
318         p.expect('[')
319         key := p.parseType()
320         p.expect(']')
321         elt := p.parseType()
322         return &Map{Key: key, Elt: elt}
323 }
324
325 // Name = identifier | "?" .
326 //
327 func (p *gcParser) parseName() (name string) {
328         switch p.tok {
329         case scanner.Ident:
330                 name = p.lit
331                 p.next()
332         case '?':
333                 // anonymous
334                 p.next()
335         default:
336                 p.error("name expected")
337         }
338         return
339 }
340
341 // Field = Name Type [ string_lit ] .
342 //
343 func (p *gcParser) parseField() (fld *ast.Object, tag string) {
344         name := p.parseName()
345         ftyp := p.parseType()
346         if name == "" {
347                 // anonymous field - ftyp must be T or *T and T must be a type name
348                 if _, ok := Deref(ftyp).(*Name); !ok {
349                         p.errorf("anonymous field expected")
350                 }
351         }
352         if p.tok == scanner.String {
353                 tag = p.expect(scanner.String)
354         }
355         fld = ast.NewObj(ast.Var, name)
356         fld.Type = ftyp
357         return
358 }
359
360 // StructType = "struct" "{" [ FieldList ] "}" .
361 // FieldList  = Field { ";" Field } .
362 //
363 func (p *gcParser) parseStructType() Type {
364         var fields []*ast.Object
365         var tags []string
366
367         parseField := func() {
368                 fld, tag := p.parseField()
369                 fields = append(fields, fld)
370                 tags = append(tags, tag)
371         }
372
373         p.expectKeyword("struct")
374         p.expect('{')
375         if p.tok != '}' {
376                 parseField()
377                 for p.tok == ';' {
378                         p.next()
379                         parseField()
380                 }
381         }
382         p.expect('}')
383
384         return &Struct{Fields: fields, Tags: tags}
385 }
386
387 // Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
388 //
389 func (p *gcParser) parseParameter() (par *ast.Object, isVariadic bool) {
390         name := p.parseName()
391         if name == "" {
392                 name = "_" // cannot access unnamed identifiers
393         }
394         if p.tok == '.' {
395                 p.expectSpecial("...")
396                 isVariadic = true
397         }
398         ptyp := p.parseType()
399         // ignore argument tag
400         if p.tok == scanner.String {
401                 p.expect(scanner.String)
402         }
403         par = ast.NewObj(ast.Var, name)
404         par.Type = ptyp
405         return
406 }
407
408 // Parameters    = "(" [ ParameterList ] ")" .
409 // ParameterList = { Parameter "," } Parameter .
410 //
411 func (p *gcParser) parseParameters() (list []*ast.Object, isVariadic bool) {
412         parseParameter := func() {
413                 par, variadic := p.parseParameter()
414                 list = append(list, par)
415                 if variadic {
416                         if isVariadic {
417                                 p.error("... not on final argument")
418                         }
419                         isVariadic = true
420                 }
421         }
422
423         p.expect('(')
424         if p.tok != ')' {
425                 parseParameter()
426                 for p.tok == ',' {
427                         p.next()
428                         parseParameter()
429                 }
430         }
431         p.expect(')')
432
433         return
434 }
435
436 // Signature = Parameters [ Result ] .
437 // Result    = Type | Parameters .
438 //
439 func (p *gcParser) parseSignature() *Func {
440         params, isVariadic := p.parseParameters()
441
442         // optional result type
443         var results []*ast.Object
444         switch p.tok {
445         case scanner.Ident, '[', '*', '<', '@':
446                 // single, unnamed result
447                 result := ast.NewObj(ast.Var, "_")
448                 result.Type = p.parseType()
449                 results = []*ast.Object{result}
450         case '(':
451                 // named or multiple result(s)
452                 var variadic bool
453                 results, variadic = p.parseParameters()
454                 if variadic {
455                         p.error("... not permitted on result type")
456                 }
457         }
458
459         return &Func{Params: params, Results: results, IsVariadic: isVariadic}
460 }
461
462 // MethodSpec = ( identifier | ExportedName )  Signature .
463 //
464 func (p *gcParser) parseMethodSpec() *ast.Object {
465         if p.tok == scanner.Ident {
466                 p.expect(scanner.Ident)
467         } else {
468                 p.parseExportedName()
469         }
470         p.parseSignature()
471
472         // TODO(gri) compute method object
473         return ast.NewObj(ast.Fun, "_")
474 }
475
476 // InterfaceType = "interface" "{" [ MethodList ] "}" .
477 // MethodList    = MethodSpec { ";" MethodSpec } .
478 //
479 func (p *gcParser) parseInterfaceType() Type {
480         var methods ObjList
481
482         parseMethod := func() {
483                 meth := p.parseMethodSpec()
484                 methods = append(methods, meth)
485         }
486
487         p.expectKeyword("interface")
488         p.expect('{')
489         if p.tok != '}' {
490                 parseMethod()
491                 for p.tok == ';' {
492                         p.next()
493                         parseMethod()
494                 }
495         }
496         p.expect('}')
497
498         methods.Sort()
499         return &Interface{Methods: methods}
500 }
501
502 // ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
503 //
504 func (p *gcParser) parseChanType() Type {
505         dir := ast.SEND | ast.RECV
506         if p.tok == scanner.Ident {
507                 p.expectKeyword("chan")
508                 if p.tok == '<' {
509                         p.expectSpecial("<-")
510                         dir = ast.SEND
511                 }
512         } else {
513                 p.expectSpecial("<-")
514                 p.expectKeyword("chan")
515                 dir = ast.RECV
516         }
517         elt := p.parseType()
518         return &Chan{Dir: dir, Elt: elt}
519 }
520
521 // Type =
522 //      BasicType | TypeName | ArrayType | SliceType | StructType |
523 //      PointerType | FuncType | InterfaceType | MapType | ChanType |
524 //      "(" Type ")" .
525 // BasicType = ident .
526 // TypeName = ExportedName .
527 // SliceType = "[" "]" Type .
528 // PointerType = "*" Type .
529 // FuncType = "func" Signature .
530 //
531 func (p *gcParser) parseType() Type {
532         switch p.tok {
533         case scanner.Ident:
534                 switch p.lit {
535                 default:
536                         return p.parseBasicType()
537                 case "struct":
538                         return p.parseStructType()
539                 case "func":
540                         // FuncType
541                         p.next()
542                         return p.parseSignature()
543                 case "interface":
544                         return p.parseInterfaceType()
545                 case "map":
546                         return p.parseMapType()
547                 case "chan":
548                         return p.parseChanType()
549                 }
550         case '@':
551                 // TypeName
552                 pkg, name := p.parseExportedName()
553                 return p.declare(pkg.Data.(*ast.Scope), ast.Typ, name).Type.(Type)
554         case '[':
555                 p.next() // look ahead
556                 if p.tok == ']' {
557                         // SliceType
558                         p.next()
559                         return &Slice{Elt: p.parseType()}
560                 }
561                 return p.parseArrayType()
562         case '*':
563                 // PointerType
564                 p.next()
565                 return &Pointer{Base: p.parseType()}
566         case '<':
567                 return p.parseChanType()
568         case '(':
569                 // "(" Type ")"
570                 p.next()
571                 typ := p.parseType()
572                 p.expect(')')
573                 return typ
574         }
575         p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
576         return nil
577 }
578
579 // ----------------------------------------------------------------------------
580 // Declarations
581
582 // ImportDecl = "import" identifier string_lit .
583 //
584 func (p *gcParser) parseImportDecl() {
585         p.expectKeyword("import")
586         // The identifier has no semantic meaning in the import data.
587         // It exists so that error messages can print the real package
588         // name: binary.ByteOrder instead of "encoding/binary".ByteOrder.
589         name := p.expect(scanner.Ident)
590         pkg := p.parsePkgId()
591         assert(pkg.Name == "" || pkg.Name == name)
592         pkg.Name = name
593 }
594
595 // int_lit = [ "+" | "-" ] { "0" ... "9" } .
596 //
597 func (p *gcParser) parseInt() (sign, val string) {
598         switch p.tok {
599         case '-':
600                 p.next()
601                 sign = "-"
602         case '+':
603                 p.next()
604         }
605         val = p.expect(scanner.Int)
606         return
607 }
608
609 // number = int_lit [ "p" int_lit ] .
610 //
611 func (p *gcParser) parseNumber() Const {
612         // mantissa
613         sign, val := p.parseInt()
614         mant, ok := new(big.Int).SetString(sign+val, 10)
615         assert(ok)
616
617         if p.lit == "p" {
618                 // exponent (base 2)
619                 p.next()
620                 sign, val = p.parseInt()
621                 exp, err := strconv.Atoui(val)
622                 if err != nil {
623                         p.error(err)
624                 }
625                 if sign == "-" {
626                         denom := big.NewInt(1)
627                         denom.Lsh(denom, exp)
628                         return Const{new(big.Rat).SetFrac(mant, denom)}
629                 }
630                 if exp > 0 {
631                         mant.Lsh(mant, exp)
632                 }
633                 return Const{new(big.Rat).SetInt(mant)}
634         }
635
636         return Const{mant}
637 }
638
639 // ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
640 // Literal     = bool_lit | int_lit | float_lit | complex_lit | string_lit .
641 // bool_lit    = "true" | "false" .
642 // complex_lit = "(" float_lit "+" float_lit ")" .
643 // string_lit  = `"` { unicode_char } `"` .
644 //
645 func (p *gcParser) parseConstDecl() {
646         p.expectKeyword("const")
647         pkg, name := p.parseExportedName()
648         obj := p.declare(pkg.Data.(*ast.Scope), ast.Con, name)
649         var x Const
650         var typ Type
651         if p.tok != '=' {
652                 obj.Type = p.parseType()
653         }
654         p.expect('=')
655         switch p.tok {
656         case scanner.Ident:
657                 // bool_lit
658                 if p.lit != "true" && p.lit != "false" {
659                         p.error("expected true or false")
660                 }
661                 x = Const{p.lit == "true"}
662                 typ = Bool.Underlying
663                 p.next()
664         case '-', scanner.Int:
665                 // int_lit
666                 x = p.parseNumber()
667                 typ = Int.Underlying
668                 if _, ok := x.val.(*big.Rat); ok {
669                         typ = Float64.Underlying
670                 }
671         case '(':
672                 // complex_lit
673                 p.next()
674                 re := p.parseNumber()
675                 p.expect('+')
676                 im := p.parseNumber()
677                 p.expect(')')
678                 x = Const{cmplx{re.val.(*big.Rat), im.val.(*big.Rat)}}
679                 typ = Complex128.Underlying
680         case scanner.String:
681                 // string_lit
682                 x = MakeConst(token.STRING, p.lit)
683                 p.next()
684                 typ = String.Underlying
685         default:
686                 p.error("expected literal")
687         }
688         if obj.Type == nil {
689                 obj.Type = typ
690         }
691         obj.Data = x
692 }
693
694 // TypeDecl = "type" ExportedName Type .
695 //
696 func (p *gcParser) parseTypeDecl() {
697         p.expectKeyword("type")
698         pkg, name := p.parseExportedName()
699         obj := p.declare(pkg.Data.(*ast.Scope), ast.Typ, name)
700
701         // The type object may have been imported before and thus already
702         // have a type associated with it. We still need to parse the type
703         // structure, but throw it away if the object already has a type.
704         // This ensures that all imports refer to the same type object for
705         // a given type declaration.
706         typ := p.parseType()
707
708         if name := obj.Type.(*Name); name.Underlying == nil {
709                 assert(Underlying(typ) == typ)
710                 name.Underlying = typ
711         }
712 }
713
714 // VarDecl = "var" ExportedName Type .
715 //
716 func (p *gcParser) parseVarDecl() {
717         p.expectKeyword("var")
718         pkg, name := p.parseExportedName()
719         obj := p.declare(pkg.Data.(*ast.Scope), ast.Var, name)
720         obj.Type = p.parseType()
721 }
722
723 // FuncBody = "{" ... "}" .
724 // 
725 func (p *gcParser) parseFuncBody() {
726         p.expect('{')
727         for i := 1; i > 0; p.next() {
728                 switch p.tok {
729                 case '{':
730                         i++
731                 case '}':
732                         i--
733                 }
734         }
735 }
736
737 // FuncDecl = "func" ExportedName Signature [ FuncBody ] .
738 //
739 func (p *gcParser) parseFuncDecl() {
740         // "func" already consumed
741         pkg, name := p.parseExportedName()
742         obj := p.declare(pkg.Data.(*ast.Scope), ast.Fun, name)
743         obj.Type = p.parseSignature()
744         if p.tok == '{' {
745                 p.parseFuncBody()
746         }
747 }
748
749 // MethodDecl = "func" Receiver identifier Signature .
750 // Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ].
751 //
752 func (p *gcParser) parseMethodDecl() {
753         // "func" already consumed
754         p.expect('(')
755         p.parseParameter() // receiver
756         p.expect(')')
757         p.expect(scanner.Ident)
758         p.parseSignature()
759         if p.tok == '{' {
760                 p.parseFuncBody()
761         }
762 }
763
764 // Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
765 //
766 func (p *gcParser) parseDecl() {
767         switch p.lit {
768         case "import":
769                 p.parseImportDecl()
770         case "const":
771                 p.parseConstDecl()
772         case "type":
773                 p.parseTypeDecl()
774         case "var":
775                 p.parseVarDecl()
776         case "func":
777                 p.next() // look ahead
778                 if p.tok == '(' {
779                         p.parseMethodDecl()
780                 } else {
781                         p.parseFuncDecl()
782                 }
783         }
784         p.expect('\n')
785 }
786
787 // ----------------------------------------------------------------------------
788 // Export
789
790 // Export        = "PackageClause { Decl } "$$" .
791 // PackageClause = "package" identifier [ "safe" ] "\n" .
792 //
793 func (p *gcParser) parseExport() *ast.Object {
794         p.expectKeyword("package")
795         name := p.expect(scanner.Ident)
796         if p.tok != '\n' {
797                 // A package is safe if it was compiled with the -u flag,
798                 // which disables the unsafe package.
799                 // TODO(gri) remember "safe" package
800                 p.expectKeyword("safe")
801         }
802         p.expect('\n')
803
804         assert(p.imports[p.id] == nil)
805         pkg := ast.NewObj(ast.Pkg, name)
806         pkg.Data = ast.NewScope(nil)
807         p.imports[p.id] = pkg
808
809         for p.tok != '$' && p.tok != scanner.EOF {
810                 p.parseDecl()
811         }
812
813         if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
814                 // don't call next()/expect() since reading past the
815                 // export data may cause scanner errors (e.g. NUL chars)
816                 p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
817         }
818
819         if n := p.scanner.ErrorCount; n != 0 {
820                 p.errorf("expected no scanner errors, got %d", n)
821         }
822
823         return pkg
824 }