github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/go/internal/gccgoimporter/parser.go (about) 1 // Copyright 2013 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 package gccgoimporter 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "go/constant" 12 "go/token" 13 "go/types" 14 "io" 15 "strconv" 16 "strings" 17 "text/scanner" 18 ) 19 20 type parser struct { 21 scanner scanner.Scanner 22 version string // format version 23 tok rune // current token 24 lit string // literal string; only valid for Ident, Int, String tokens 25 pkgpath string // package path of imported package 26 pkgname string // name of imported package 27 pkg *types.Package // reference to imported package 28 imports map[string]*types.Package // package path -> package object 29 typeMap map[int]types.Type // type number -> type 30 initdata InitData // package init priority data 31 } 32 33 func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) { 34 p.scanner.Init(src) 35 p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } 36 p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments 37 p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' ' 38 p.scanner.Filename = filename // for good error messages 39 p.next() 40 p.imports = imports 41 p.typeMap = make(map[int]types.Type) 42 } 43 44 type importError struct { 45 pos scanner.Position 46 err error 47 } 48 49 func (e importError) Error() string { 50 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) 51 } 52 53 func (p *parser) error(err interface{}) { 54 if s, ok := err.(string); ok { 55 err = errors.New(s) 56 } 57 // panic with a runtime.Error if err is not an error 58 panic(importError{p.scanner.Pos(), err.(error)}) 59 } 60 61 func (p *parser) errorf(format string, args ...interface{}) { 62 p.error(fmt.Errorf(format, args...)) 63 } 64 65 func (p *parser) expect(tok rune) string { 66 lit := p.lit 67 if p.tok != tok { 68 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) 69 } 70 p.next() 71 return lit 72 } 73 74 func (p *parser) expectKeyword(keyword string) { 75 lit := p.expect(scanner.Ident) 76 if lit != keyword { 77 p.errorf("expected keyword %s, got %q", keyword, lit) 78 } 79 } 80 81 func (p *parser) parseString() string { 82 str, err := strconv.Unquote(p.expect(scanner.String)) 83 if err != nil { 84 p.error(err) 85 } 86 return str 87 } 88 89 // unquotedString = { unquotedStringChar } . 90 // unquotedStringChar = <neither a whitespace nor a ';' char> . 91 func (p *parser) parseUnquotedString() string { 92 if p.tok == scanner.EOF { 93 p.error("unexpected EOF") 94 } 95 var buf bytes.Buffer 96 buf.WriteString(p.scanner.TokenText()) 97 // This loop needs to examine each character before deciding whether to consume it. If we see a semicolon, 98 // we need to let it be consumed by p.next(). 99 for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() { 100 buf.WriteRune(ch) 101 p.scanner.Next() 102 } 103 p.next() 104 return buf.String() 105 } 106 107 func (p *parser) next() { 108 p.tok = p.scanner.Scan() 109 switch p.tok { 110 case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท': 111 p.lit = p.scanner.TokenText() 112 default: 113 p.lit = "" 114 } 115 } 116 117 func (p *parser) parseQualifiedName() (path, name string) { 118 return p.parseQualifiedNameStr(p.parseString()) 119 } 120 121 func (p *parser) parseUnquotedQualifiedName() (path, name string) { 122 return p.parseQualifiedNameStr(p.parseUnquotedString()) 123 } 124 125 // qualifiedName = [ ["."] unquotedString "." ] unquotedString . 126 // 127 // The above production uses greedy matching. 128 func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) { 129 parts := strings.Split(unquotedName, ".") 130 if parts[0] == "" { 131 parts = parts[1:] 132 } 133 134 switch len(parts) { 135 case 0: 136 p.errorf("malformed qualified name: %q", unquotedName) 137 case 1: 138 // unqualified name 139 pkgpath = p.pkgpath 140 name = parts[0] 141 default: 142 // qualified name, which may contain periods 143 pkgpath = strings.Join(parts[0:len(parts)-1], ".") 144 name = parts[len(parts)-1] 145 } 146 147 return 148 } 149 150 // getPkg returns the package for a given path. If the package is 151 // not found but we have a package name, create the package and 152 // add it to the p.imports map. 153 // 154 func (p *parser) getPkg(pkgpath, name string) *types.Package { 155 // package unsafe is not in the imports map - handle explicitly 156 if pkgpath == "unsafe" { 157 return types.Unsafe 158 } 159 pkg := p.imports[pkgpath] 160 if pkg == nil && name != "" { 161 pkg = types.NewPackage(pkgpath, name) 162 p.imports[pkgpath] = pkg 163 } 164 return pkg 165 } 166 167 // parseExportedName is like parseQualifiedName, but 168 // the package path is resolved to an imported *types.Package. 169 // 170 // ExportedName = string [string] . 171 func (p *parser) parseExportedName() (pkg *types.Package, name string) { 172 path, name := p.parseQualifiedName() 173 var pkgname string 174 if p.tok == scanner.String { 175 pkgname = p.parseString() 176 } 177 pkg = p.getPkg(path, pkgname) 178 if pkg == nil { 179 p.errorf("package %s (path = %q) not found", name, path) 180 } 181 return 182 } 183 184 // Name = QualifiedName | "?" . 185 func (p *parser) parseName() string { 186 if p.tok == '?' { 187 // Anonymous. 188 p.next() 189 return "" 190 } 191 // The package path is redundant for us. Don't try to parse it. 192 _, name := p.parseUnquotedQualifiedName() 193 return name 194 } 195 196 func deref(typ types.Type) types.Type { 197 if p, _ := typ.(*types.Pointer); p != nil { 198 typ = p.Elem() 199 } 200 return typ 201 } 202 203 // Field = Name Type [string] . 204 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) { 205 name := p.parseName() 206 typ := p.parseType(pkg) 207 anon := false 208 if name == "" { 209 anon = true 210 switch typ := deref(typ).(type) { 211 case *types.Basic: 212 name = typ.Name() 213 case *types.Named: 214 name = typ.Obj().Name() 215 default: 216 p.error("anonymous field expected") 217 } 218 } 219 field = types.NewField(token.NoPos, pkg, name, typ, anon) 220 if p.tok == scanner.String { 221 tag = p.parseString() 222 } 223 return 224 } 225 226 // Param = Name ["..."] Type . 227 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) { 228 name := p.parseName() 229 if p.tok == '.' { 230 p.next() 231 p.expect('.') 232 p.expect('.') 233 isVariadic = true 234 } 235 typ := p.parseType(pkg) 236 if isVariadic { 237 typ = types.NewSlice(typ) 238 } 239 param = types.NewParam(token.NoPos, pkg, name, typ) 240 return 241 } 242 243 // Var = Name Type . 244 func (p *parser) parseVar(pkg *types.Package) *types.Var { 245 name := p.parseName() 246 return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg)) 247 } 248 249 // Conversion = "convert" "(" Type "," ConstValue ")" . 250 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) { 251 p.expectKeyword("convert") 252 p.expect('(') 253 typ = p.parseType(pkg) 254 p.expect(',') 255 val, _ = p.parseConstValue(pkg) 256 p.expect(')') 257 return 258 } 259 260 // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion . 261 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] . 262 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) { 263 switch p.tok { 264 case scanner.String: 265 str := p.parseString() 266 val = constant.MakeString(str) 267 typ = types.Typ[types.UntypedString] 268 return 269 270 case scanner.Ident: 271 b := false 272 switch p.lit { 273 case "false": 274 case "true": 275 b = true 276 277 case "convert": 278 return p.parseConversion(pkg) 279 280 default: 281 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 282 } 283 284 p.next() 285 val = constant.MakeBool(b) 286 typ = types.Typ[types.UntypedBool] 287 return 288 } 289 290 sign := "" 291 if p.tok == '-' { 292 p.next() 293 sign = "-" 294 } 295 296 switch p.tok { 297 case scanner.Int: 298 val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0) 299 if val == nil { 300 p.error("could not parse integer literal") 301 } 302 303 p.next() 304 if p.tok == '\'' { 305 p.next() 306 typ = types.Typ[types.UntypedRune] 307 } else { 308 typ = types.Typ[types.UntypedInt] 309 } 310 311 case scanner.Float: 312 re := sign + p.lit 313 p.next() 314 315 var im string 316 switch p.tok { 317 case '+': 318 p.next() 319 im = p.expect(scanner.Float) 320 321 case '-': 322 p.next() 323 im = "-" + p.expect(scanner.Float) 324 325 case scanner.Ident: 326 // re is in fact the imaginary component. Expect "i" below. 327 im = re 328 re = "0" 329 330 default: 331 val = constant.MakeFromLiteral(re, token.FLOAT, 0) 332 if val == nil { 333 p.error("could not parse float literal") 334 } 335 typ = types.Typ[types.UntypedFloat] 336 return 337 } 338 339 p.expectKeyword("i") 340 reval := constant.MakeFromLiteral(re, token.FLOAT, 0) 341 if reval == nil { 342 p.error("could not parse real component of complex literal") 343 } 344 imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0) 345 if imval == nil { 346 p.error("could not parse imag component of complex literal") 347 } 348 val = constant.BinaryOp(reval, token.ADD, imval) 349 typ = types.Typ[types.UntypedComplex] 350 351 default: 352 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 353 } 354 355 return 356 } 357 358 // Const = Name [Type] "=" ConstValue . 359 func (p *parser) parseConst(pkg *types.Package) *types.Const { 360 name := p.parseName() 361 var typ types.Type 362 if p.tok == '<' { 363 typ = p.parseType(pkg) 364 } 365 p.expect('=') 366 val, vtyp := p.parseConstValue(pkg) 367 if typ == nil { 368 typ = vtyp 369 } 370 return types.NewConst(token.NoPos, pkg, name, typ, val) 371 } 372 373 // TypeName = ExportedName . 374 func (p *parser) parseTypeName() *types.TypeName { 375 pkg, name := p.parseExportedName() 376 scope := pkg.Scope() 377 if obj := scope.Lookup(name); obj != nil { 378 return obj.(*types.TypeName) 379 } 380 obj := types.NewTypeName(token.NoPos, pkg, name, nil) 381 // a named type may be referred to before the underlying type 382 // is known - set it up 383 types.NewNamed(obj, nil, nil) 384 scope.Insert(obj) 385 return obj 386 } 387 388 // NamedType = TypeName Type { Method } . 389 // Method = "func" "(" Param ")" Name ParamList ResultList ";" . 390 func (p *parser) parseNamedType(n int) types.Type { 391 obj := p.parseTypeName() 392 393 pkg := obj.Pkg() 394 typ := obj.Type() 395 p.typeMap[n] = typ 396 397 nt, ok := typ.(*types.Named) 398 if !ok { 399 // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type. 400 pt := p.parseType(pkg) 401 if pt != typ { 402 p.error("unexpected underlying type for non-named TypeName") 403 } 404 return typ 405 } 406 407 underlying := p.parseType(pkg) 408 if nt.Underlying() == nil { 409 nt.SetUnderlying(underlying.Underlying()) 410 } 411 412 for p.tok == scanner.Ident { 413 // collect associated methods 414 p.expectKeyword("func") 415 p.expect('(') 416 receiver, _ := p.parseParam(pkg) 417 p.expect(')') 418 name := p.parseName() 419 params, isVariadic := p.parseParamList(pkg) 420 results := p.parseResultList(pkg) 421 p.expect(';') 422 423 sig := types.NewSignature(receiver, params, results, isVariadic) 424 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 425 } 426 427 return nt 428 } 429 430 func (p *parser) parseInt() int64 { 431 lit := p.expect(scanner.Int) 432 n, err := strconv.ParseInt(lit, 10, 0) 433 if err != nil { 434 p.error(err) 435 } 436 return n 437 } 438 439 // ArrayOrSliceType = "[" [ int ] "]" Type . 440 func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type { 441 p.expect('[') 442 if p.tok == ']' { 443 p.next() 444 return types.NewSlice(p.parseType(pkg)) 445 } 446 447 n := p.parseInt() 448 p.expect(']') 449 return types.NewArray(p.parseType(pkg), n) 450 } 451 452 // MapType = "map" "[" Type "]" Type . 453 func (p *parser) parseMapType(pkg *types.Package) types.Type { 454 p.expectKeyword("map") 455 p.expect('[') 456 key := p.parseType(pkg) 457 p.expect(']') 458 elem := p.parseType(pkg) 459 return types.NewMap(key, elem) 460 } 461 462 // ChanType = "chan" ["<-" | "-<"] Type . 463 func (p *parser) parseChanType(pkg *types.Package) types.Type { 464 p.expectKeyword("chan") 465 dir := types.SendRecv 466 switch p.tok { 467 case '-': 468 p.next() 469 p.expect('<') 470 dir = types.SendOnly 471 472 case '<': 473 // don't consume '<' if it belongs to Type 474 if p.scanner.Peek() == '-' { 475 p.next() 476 p.expect('-') 477 dir = types.RecvOnly 478 } 479 } 480 481 return types.NewChan(dir, p.parseType(pkg)) 482 } 483 484 // StructType = "struct" "{" { Field } "}" . 485 func (p *parser) parseStructType(pkg *types.Package) types.Type { 486 p.expectKeyword("struct") 487 488 var fields []*types.Var 489 var tags []string 490 491 p.expect('{') 492 for p.tok != '}' && p.tok != scanner.EOF { 493 field, tag := p.parseField(pkg) 494 p.expect(';') 495 fields = append(fields, field) 496 tags = append(tags, tag) 497 } 498 p.expect('}') 499 500 return types.NewStruct(fields, tags) 501 } 502 503 // ParamList = "(" [ { Parameter "," } Parameter ] ")" . 504 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) { 505 var list []*types.Var 506 isVariadic := false 507 508 p.expect('(') 509 for p.tok != ')' && p.tok != scanner.EOF { 510 if len(list) > 0 { 511 p.expect(',') 512 } 513 par, variadic := p.parseParam(pkg) 514 list = append(list, par) 515 if variadic { 516 if isVariadic { 517 p.error("... not on final argument") 518 } 519 isVariadic = true 520 } 521 } 522 p.expect(')') 523 524 return types.NewTuple(list...), isVariadic 525 } 526 527 // ResultList = Type | ParamList . 528 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple { 529 switch p.tok { 530 case '<': 531 return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg))) 532 533 case '(': 534 params, _ := p.parseParamList(pkg) 535 return params 536 537 default: 538 return nil 539 } 540 } 541 542 // FunctionType = ParamList ResultList . 543 func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature { 544 params, isVariadic := p.parseParamList(pkg) 545 results := p.parseResultList(pkg) 546 return types.NewSignature(nil, params, results, isVariadic) 547 } 548 549 // Func = Name FunctionType . 550 func (p *parser) parseFunc(pkg *types.Package) *types.Func { 551 name := p.parseName() 552 if strings.ContainsRune(name, '$') { 553 // This is a Type$equal or Type$hash function, which we don't want to parse, 554 // except for the types. 555 p.discardDirectiveWhileParsingTypes(pkg) 556 return nil 557 } 558 return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg)) 559 } 560 561 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" . 562 func (p *parser) parseInterfaceType(pkg *types.Package) types.Type { 563 p.expectKeyword("interface") 564 565 var methods []*types.Func 566 var typs []*types.Named 567 568 p.expect('{') 569 for p.tok != '}' && p.tok != scanner.EOF { 570 if p.tok == '?' { 571 p.next() 572 typs = append(typs, p.parseType(pkg).(*types.Named)) 573 } else { 574 method := p.parseFunc(pkg) 575 methods = append(methods, method) 576 } 577 p.expect(';') 578 } 579 p.expect('}') 580 581 return types.NewInterface(methods, typs) 582 } 583 584 // PointerType = "*" ("any" | Type) . 585 func (p *parser) parsePointerType(pkg *types.Package) types.Type { 586 p.expect('*') 587 if p.tok == scanner.Ident { 588 p.expectKeyword("any") 589 return types.Typ[types.UnsafePointer] 590 } 591 return types.NewPointer(p.parseType(pkg)) 592 } 593 594 // TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType . 595 func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type { 596 var t types.Type 597 switch p.tok { 598 case scanner.String: 599 t = p.parseNamedType(n) 600 601 case scanner.Ident: 602 switch p.lit { 603 case "map": 604 t = p.parseMapType(pkg) 605 606 case "chan": 607 t = p.parseChanType(pkg) 608 609 case "struct": 610 t = p.parseStructType(pkg) 611 612 case "interface": 613 t = p.parseInterfaceType(pkg) 614 } 615 616 case '*': 617 t = p.parsePointerType(pkg) 618 619 case '[': 620 t = p.parseArrayOrSliceType(pkg) 621 622 case '(': 623 t = p.parseFunctionType(pkg) 624 } 625 626 p.typeMap[n] = t 627 return t 628 } 629 630 const ( 631 // From gofrontend/go/export.h 632 // Note that these values are negative in the gofrontend and have been made positive 633 // in the gccgoimporter. 634 gccgoBuiltinINT8 = 1 635 gccgoBuiltinINT16 = 2 636 gccgoBuiltinINT32 = 3 637 gccgoBuiltinINT64 = 4 638 gccgoBuiltinUINT8 = 5 639 gccgoBuiltinUINT16 = 6 640 gccgoBuiltinUINT32 = 7 641 gccgoBuiltinUINT64 = 8 642 gccgoBuiltinFLOAT32 = 9 643 gccgoBuiltinFLOAT64 = 10 644 gccgoBuiltinINT = 11 645 gccgoBuiltinUINT = 12 646 gccgoBuiltinUINTPTR = 13 647 gccgoBuiltinBOOL = 15 648 gccgoBuiltinSTRING = 16 649 gccgoBuiltinCOMPLEX64 = 17 650 gccgoBuiltinCOMPLEX128 = 18 651 gccgoBuiltinERROR = 19 652 gccgoBuiltinBYTE = 20 653 gccgoBuiltinRUNE = 21 654 ) 655 656 func lookupBuiltinType(typ int) types.Type { 657 return [...]types.Type{ 658 gccgoBuiltinINT8: types.Typ[types.Int8], 659 gccgoBuiltinINT16: types.Typ[types.Int16], 660 gccgoBuiltinINT32: types.Typ[types.Int32], 661 gccgoBuiltinINT64: types.Typ[types.Int64], 662 gccgoBuiltinUINT8: types.Typ[types.Uint8], 663 gccgoBuiltinUINT16: types.Typ[types.Uint16], 664 gccgoBuiltinUINT32: types.Typ[types.Uint32], 665 gccgoBuiltinUINT64: types.Typ[types.Uint64], 666 gccgoBuiltinFLOAT32: types.Typ[types.Float32], 667 gccgoBuiltinFLOAT64: types.Typ[types.Float64], 668 gccgoBuiltinINT: types.Typ[types.Int], 669 gccgoBuiltinUINT: types.Typ[types.Uint], 670 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr], 671 gccgoBuiltinBOOL: types.Typ[types.Bool], 672 gccgoBuiltinSTRING: types.Typ[types.String], 673 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64], 674 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128], 675 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(), 676 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(), 677 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(), 678 }[typ] 679 } 680 681 // Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" . 682 func (p *parser) parseType(pkg *types.Package) (t types.Type) { 683 p.expect('<') 684 p.expectKeyword("type") 685 686 switch p.tok { 687 case scanner.Int: 688 n := p.parseInt() 689 690 if p.tok == '>' { 691 t = p.typeMap[int(n)] 692 } else { 693 t = p.parseTypeDefinition(pkg, int(n)) 694 } 695 696 case '-': 697 p.next() 698 n := p.parseInt() 699 t = lookupBuiltinType(int(n)) 700 701 default: 702 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit) 703 return nil 704 } 705 706 p.expect('>') 707 return 708 } 709 710 // PackageInit = unquotedString unquotedString int . 711 func (p *parser) parsePackageInit() PackageInit { 712 name := p.parseUnquotedString() 713 initfunc := p.parseUnquotedString() 714 priority := -1 715 if p.version == "v1" { 716 priority = int(p.parseInt()) 717 } 718 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} 719 } 720 721 // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type. 722 func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) { 723 for { 724 switch p.tok { 725 case ';': 726 return 727 case '<': 728 p.parseType(p.pkg) 729 case scanner.EOF: 730 p.error("unexpected EOF") 731 default: 732 p.next() 733 } 734 } 735 } 736 737 // Create the package if we have parsed both the package path and package name. 738 func (p *parser) maybeCreatePackage() { 739 if p.pkgname != "" && p.pkgpath != "" { 740 p.pkg = p.getPkg(p.pkgpath, p.pkgname) 741 } 742 } 743 744 // InitDataDirective = ( "v1" | "v2" ) ";" | 745 // "priority" int ";" | 746 // "init" { PackageInit } ";" | 747 // "checksum" unquotedString ";" . 748 func (p *parser) parseInitDataDirective() { 749 if p.tok != scanner.Ident { 750 // unexpected token kind; panic 751 p.expect(scanner.Ident) 752 } 753 754 switch p.lit { 755 case "v1", "v2": 756 p.version = p.lit 757 p.next() 758 p.expect(';') 759 760 case "priority": 761 p.next() 762 p.initdata.Priority = int(p.parseInt()) 763 p.expect(';') 764 765 case "init": 766 p.next() 767 for p.tok != ';' && p.tok != scanner.EOF { 768 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit()) 769 } 770 p.expect(';') 771 772 case "init_graph": 773 p.next() 774 // The graph data is thrown away for now. 775 for p.tok != ';' && p.tok != scanner.EOF { 776 p.parseInt() 777 p.parseInt() 778 } 779 p.expect(';') 780 781 case "checksum": 782 // Don't let the scanner try to parse the checksum as a number. 783 defer func(mode uint) { 784 p.scanner.Mode = mode 785 }(p.scanner.Mode) 786 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats 787 p.next() 788 p.parseUnquotedString() 789 p.expect(';') 790 791 default: 792 p.errorf("unexpected identifier: %q", p.lit) 793 } 794 } 795 796 // Directive = InitDataDirective | 797 // "package" unquotedString [ unquotedString ] [ unquotedString ] ";" | 798 // "pkgpath" unquotedString ";" | 799 // "prefix" unquotedString ";" | 800 // "import" unquotedString unquotedString string ";" | 801 // "func" Func ";" | 802 // "type" Type ";" | 803 // "var" Var ";" | 804 // "const" Const ";" . 805 func (p *parser) parseDirective() { 806 if p.tok != scanner.Ident { 807 // unexpected token kind; panic 808 p.expect(scanner.Ident) 809 } 810 811 switch p.lit { 812 case "v1", "v2", "priority", "init", "init_graph", "checksum": 813 p.parseInitDataDirective() 814 815 case "package": 816 p.next() 817 p.pkgname = p.parseUnquotedString() 818 p.maybeCreatePackage() 819 if p.version == "v2" && p.tok != ';' { 820 p.parseUnquotedString() 821 p.parseUnquotedString() 822 } 823 p.expect(';') 824 825 case "pkgpath": 826 p.next() 827 p.pkgpath = p.parseUnquotedString() 828 p.maybeCreatePackage() 829 p.expect(';') 830 831 case "prefix": 832 p.next() 833 p.pkgpath = p.parseUnquotedString() 834 p.expect(';') 835 836 case "import": 837 p.next() 838 pkgname := p.parseUnquotedString() 839 pkgpath := p.parseUnquotedString() 840 p.getPkg(pkgpath, pkgname) 841 p.parseString() 842 p.expect(';') 843 844 case "func": 845 p.next() 846 fun := p.parseFunc(p.pkg) 847 if fun != nil { 848 p.pkg.Scope().Insert(fun) 849 } 850 p.expect(';') 851 852 case "type": 853 p.next() 854 p.parseType(p.pkg) 855 p.expect(';') 856 857 case "var": 858 p.next() 859 v := p.parseVar(p.pkg) 860 p.pkg.Scope().Insert(v) 861 p.expect(';') 862 863 case "const": 864 p.next() 865 c := p.parseConst(p.pkg) 866 p.pkg.Scope().Insert(c) 867 p.expect(';') 868 869 default: 870 p.errorf("unexpected identifier: %q", p.lit) 871 } 872 } 873 874 // Package = { Directive } . 875 func (p *parser) parsePackage() *types.Package { 876 for p.tok != scanner.EOF { 877 p.parseDirective() 878 } 879 for _, typ := range p.typeMap { 880 if it, ok := typ.(*types.Interface); ok { 881 it.Complete() 882 } 883 } 884 p.pkg.MarkComplete() 885 return p.pkg 886 } 887 888 // InitData = { InitDataDirective } . 889 func (p *parser) parseInitData() { 890 for p.tok != scanner.EOF { 891 p.parseInitDataDirective() 892 } 893 }