github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/go/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/token" 12 "io" 13 "strconv" 14 "strings" 15 "text/scanner" 16 17 "llvm.org/llgo/third_party/gotools/go/exact" 18 "llvm.org/llgo/third_party/gotools/go/types" 19 ) 20 21 type parser struct { 22 scanner scanner.Scanner 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 // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) . 250 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] . 251 func (p *parser) parseConstValue() (val exact.Value, typ types.Type) { 252 switch p.tok { 253 case scanner.String: 254 str := p.parseString() 255 val = exact.MakeString(str) 256 typ = types.Typ[types.UntypedString] 257 return 258 259 case scanner.Ident: 260 b := false 261 switch p.lit { 262 case "false": 263 case "true": 264 b = true 265 266 default: 267 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 268 } 269 270 p.next() 271 val = exact.MakeBool(b) 272 typ = types.Typ[types.UntypedBool] 273 return 274 } 275 276 sign := "" 277 if p.tok == '-' { 278 p.next() 279 sign = "-" 280 } 281 282 switch p.tok { 283 case scanner.Int: 284 val = exact.MakeFromLiteral(sign+p.lit, token.INT) 285 if val == nil { 286 p.error("could not parse integer literal") 287 } 288 289 p.next() 290 if p.tok == '\'' { 291 p.next() 292 typ = types.Typ[types.UntypedRune] 293 } else { 294 typ = types.Typ[types.UntypedInt] 295 } 296 297 case scanner.Float: 298 re := sign + p.lit 299 p.next() 300 301 var im string 302 switch p.tok { 303 case '+': 304 p.next() 305 im = p.expect(scanner.Float) 306 307 case '-': 308 p.next() 309 im = "-" + p.expect(scanner.Float) 310 311 case scanner.Ident: 312 // re is in fact the imaginary component. Expect "i" below. 313 im = re 314 re = "0" 315 316 default: 317 val = exact.MakeFromLiteral(re, token.FLOAT) 318 if val == nil { 319 p.error("could not parse float literal") 320 } 321 typ = types.Typ[types.UntypedFloat] 322 return 323 } 324 325 p.expectKeyword("i") 326 reval := exact.MakeFromLiteral(re, token.FLOAT) 327 if reval == nil { 328 p.error("could not parse real component of complex literal") 329 } 330 imval := exact.MakeFromLiteral(im+"i", token.IMAG) 331 if imval == nil { 332 p.error("could not parse imag component of complex literal") 333 } 334 val = exact.BinaryOp(reval, token.ADD, imval) 335 typ = types.Typ[types.UntypedComplex] 336 337 default: 338 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 339 } 340 341 return 342 } 343 344 // Const = Name [Type] "=" ConstValue . 345 func (p *parser) parseConst(pkg *types.Package) *types.Const { 346 name := p.parseName() 347 var typ types.Type 348 if p.tok == '<' { 349 typ = p.parseType(pkg) 350 } 351 p.expect('=') 352 val, vtyp := p.parseConstValue() 353 if typ == nil { 354 typ = vtyp 355 } 356 return types.NewConst(token.NoPos, pkg, name, typ, val) 357 } 358 359 // TypeName = ExportedName . 360 func (p *parser) parseTypeName() *types.TypeName { 361 pkg, name := p.parseExportedName() 362 scope := pkg.Scope() 363 if obj := scope.Lookup(name); obj != nil { 364 return obj.(*types.TypeName) 365 } 366 obj := types.NewTypeName(token.NoPos, pkg, name, nil) 367 // a named type may be referred to before the underlying type 368 // is known - set it up 369 types.NewNamed(obj, nil, nil) 370 scope.Insert(obj) 371 return obj 372 } 373 374 // NamedType = TypeName Type { Method } . 375 // Method = "func" "(" Param ")" Name ParamList ResultList ";" . 376 func (p *parser) parseNamedType(n int) types.Type { 377 obj := p.parseTypeName() 378 379 pkg := obj.Pkg() 380 typ := obj.Type() 381 p.typeMap[n] = typ 382 383 nt, ok := typ.(*types.Named) 384 if !ok { 385 // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type. 386 pt := p.parseType(pkg) 387 if pt != typ { 388 p.error("unexpected underlying type for non-named TypeName") 389 } 390 return typ 391 } 392 393 underlying := p.parseType(pkg) 394 if nt.Underlying() == nil { 395 nt.SetUnderlying(underlying.Underlying()) 396 } 397 398 for p.tok == scanner.Ident { 399 // collect associated methods 400 p.expectKeyword("func") 401 p.expect('(') 402 receiver, _ := p.parseParam(pkg) 403 p.expect(')') 404 name := p.parseName() 405 params, isVariadic := p.parseParamList(pkg) 406 results := p.parseResultList(pkg) 407 p.expect(';') 408 409 sig := types.NewSignature(pkg.Scope(), receiver, params, results, isVariadic) 410 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 411 } 412 413 return nt 414 } 415 416 func (p *parser) parseInt() int64 { 417 lit := p.expect(scanner.Int) 418 n, err := strconv.ParseInt(lit, 10, 0) 419 if err != nil { 420 p.error(err) 421 } 422 return n 423 } 424 425 // ArrayOrSliceType = "[" [ int ] "]" Type . 426 func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type { 427 p.expect('[') 428 if p.tok == ']' { 429 p.next() 430 return types.NewSlice(p.parseType(pkg)) 431 } 432 433 n := p.parseInt() 434 p.expect(']') 435 return types.NewArray(p.parseType(pkg), n) 436 } 437 438 // MapType = "map" "[" Type "]" Type . 439 func (p *parser) parseMapType(pkg *types.Package) types.Type { 440 p.expectKeyword("map") 441 p.expect('[') 442 key := p.parseType(pkg) 443 p.expect(']') 444 elem := p.parseType(pkg) 445 return types.NewMap(key, elem) 446 } 447 448 // ChanType = "chan" ["<-" | "-<"] Type . 449 func (p *parser) parseChanType(pkg *types.Package) types.Type { 450 p.expectKeyword("chan") 451 dir := types.SendRecv 452 switch p.tok { 453 case '-': 454 p.next() 455 p.expect('<') 456 dir = types.SendOnly 457 458 case '<': 459 // don't consume '<' if it belongs to Type 460 if p.scanner.Peek() == '-' { 461 p.next() 462 p.expect('-') 463 dir = types.RecvOnly 464 } 465 } 466 467 return types.NewChan(dir, p.parseType(pkg)) 468 } 469 470 // StructType = "struct" "{" { Field } "}" . 471 func (p *parser) parseStructType(pkg *types.Package) types.Type { 472 p.expectKeyword("struct") 473 474 var fields []*types.Var 475 var tags []string 476 477 p.expect('{') 478 for p.tok != '}' && p.tok != scanner.EOF { 479 field, tag := p.parseField(pkg) 480 p.expect(';') 481 fields = append(fields, field) 482 tags = append(tags, tag) 483 } 484 p.expect('}') 485 486 return types.NewStruct(fields, tags) 487 } 488 489 // ParamList = "(" [ { Parameter "," } Parameter ] ")" . 490 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) { 491 var list []*types.Var 492 isVariadic := false 493 494 p.expect('(') 495 for p.tok != ')' && p.tok != scanner.EOF { 496 if len(list) > 0 { 497 p.expect(',') 498 } 499 par, variadic := p.parseParam(pkg) 500 list = append(list, par) 501 if variadic { 502 if isVariadic { 503 p.error("... not on final argument") 504 } 505 isVariadic = true 506 } 507 } 508 p.expect(')') 509 510 return types.NewTuple(list...), isVariadic 511 } 512 513 // ResultList = Type | ParamList . 514 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple { 515 switch p.tok { 516 case '<': 517 return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg))) 518 519 case '(': 520 params, _ := p.parseParamList(pkg) 521 return params 522 523 default: 524 return nil 525 } 526 } 527 528 // FunctionType = ParamList ResultList . 529 func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature { 530 params, isVariadic := p.parseParamList(pkg) 531 results := p.parseResultList(pkg) 532 return types.NewSignature(pkg.Scope(), nil, params, results, isVariadic) 533 } 534 535 // Func = Name FunctionType . 536 func (p *parser) parseFunc(pkg *types.Package) *types.Func { 537 name := p.parseName() 538 if strings.ContainsRune(name, '$') { 539 // This is a Type$equal or Type$hash function, which we don't want to parse, 540 // except for the types. 541 p.discardDirectiveWhileParsingTypes(pkg) 542 return nil 543 } 544 return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg)) 545 } 546 547 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" . 548 func (p *parser) parseInterfaceType(pkg *types.Package) types.Type { 549 p.expectKeyword("interface") 550 551 var methods []*types.Func 552 var typs []*types.Named 553 554 p.expect('{') 555 for p.tok != '}' && p.tok != scanner.EOF { 556 if p.tok == '?' { 557 p.next() 558 typs = append(typs, p.parseType(pkg).(*types.Named)) 559 } else { 560 method := p.parseFunc(pkg) 561 methods = append(methods, method) 562 } 563 p.expect(';') 564 } 565 p.expect('}') 566 567 return types.NewInterface(methods, typs) 568 } 569 570 // PointerType = "*" ("any" | Type) . 571 func (p *parser) parsePointerType(pkg *types.Package) types.Type { 572 p.expect('*') 573 if p.tok == scanner.Ident { 574 p.expectKeyword("any") 575 return types.Typ[types.UnsafePointer] 576 } 577 return types.NewPointer(p.parseType(pkg)) 578 } 579 580 // TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType . 581 func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type { 582 var t types.Type 583 switch p.tok { 584 case scanner.String: 585 t = p.parseNamedType(n) 586 587 case scanner.Ident: 588 switch p.lit { 589 case "map": 590 t = p.parseMapType(pkg) 591 592 case "chan": 593 t = p.parseChanType(pkg) 594 595 case "struct": 596 t = p.parseStructType(pkg) 597 598 case "interface": 599 t = p.parseInterfaceType(pkg) 600 } 601 602 case '*': 603 t = p.parsePointerType(pkg) 604 605 case '[': 606 t = p.parseArrayOrSliceType(pkg) 607 608 case '(': 609 t = p.parseFunctionType(pkg) 610 } 611 612 p.typeMap[n] = t 613 return t 614 } 615 616 const ( 617 // From gofrontend/go/export.h 618 // Note that these values are negative in the gofrontend and have been made positive 619 // in the gccgoimporter. 620 gccgoBuiltinINT8 = 1 621 gccgoBuiltinINT16 = 2 622 gccgoBuiltinINT32 = 3 623 gccgoBuiltinINT64 = 4 624 gccgoBuiltinUINT8 = 5 625 gccgoBuiltinUINT16 = 6 626 gccgoBuiltinUINT32 = 7 627 gccgoBuiltinUINT64 = 8 628 gccgoBuiltinFLOAT32 = 9 629 gccgoBuiltinFLOAT64 = 10 630 gccgoBuiltinINT = 11 631 gccgoBuiltinUINT = 12 632 gccgoBuiltinUINTPTR = 13 633 gccgoBuiltinBOOL = 15 634 gccgoBuiltinSTRING = 16 635 gccgoBuiltinCOMPLEX64 = 17 636 gccgoBuiltinCOMPLEX128 = 18 637 gccgoBuiltinERROR = 19 638 gccgoBuiltinBYTE = 20 639 gccgoBuiltinRUNE = 21 640 ) 641 642 func lookupBuiltinType(typ int) types.Type { 643 return [...]types.Type{ 644 gccgoBuiltinINT8: types.Typ[types.Int8], 645 gccgoBuiltinINT16: types.Typ[types.Int16], 646 gccgoBuiltinINT32: types.Typ[types.Int32], 647 gccgoBuiltinINT64: types.Typ[types.Int64], 648 gccgoBuiltinUINT8: types.Typ[types.Uint8], 649 gccgoBuiltinUINT16: types.Typ[types.Uint16], 650 gccgoBuiltinUINT32: types.Typ[types.Uint32], 651 gccgoBuiltinUINT64: types.Typ[types.Uint64], 652 gccgoBuiltinFLOAT32: types.Typ[types.Float32], 653 gccgoBuiltinFLOAT64: types.Typ[types.Float64], 654 gccgoBuiltinINT: types.Typ[types.Int], 655 gccgoBuiltinUINT: types.Typ[types.Uint], 656 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr], 657 gccgoBuiltinBOOL: types.Typ[types.Bool], 658 gccgoBuiltinSTRING: types.Typ[types.String], 659 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64], 660 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128], 661 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(), 662 gccgoBuiltinBYTE: types.Typ[types.Byte], 663 gccgoBuiltinRUNE: types.Typ[types.Rune], 664 }[typ] 665 } 666 667 // Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" . 668 func (p *parser) parseType(pkg *types.Package) (t types.Type) { 669 p.expect('<') 670 p.expectKeyword("type") 671 672 switch p.tok { 673 case scanner.Int: 674 n := p.parseInt() 675 676 if p.tok == '>' { 677 t = p.typeMap[int(n)] 678 } else { 679 t = p.parseTypeDefinition(pkg, int(n)) 680 } 681 682 case '-': 683 p.next() 684 n := p.parseInt() 685 t = lookupBuiltinType(int(n)) 686 687 default: 688 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit) 689 return nil 690 } 691 692 p.expect('>') 693 return 694 } 695 696 // PackageInit = unquotedString unquotedString int . 697 func (p *parser) parsePackageInit() PackageInit { 698 name := p.parseUnquotedString() 699 initfunc := p.parseUnquotedString() 700 priority := int(p.parseInt()) 701 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} 702 } 703 704 // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type. 705 func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) { 706 for { 707 switch p.tok { 708 case ';': 709 return 710 case '<': 711 p.parseType(p.pkg) 712 case scanner.EOF: 713 p.error("unexpected EOF") 714 default: 715 p.next() 716 } 717 } 718 } 719 720 // Create the package if we have parsed both the package path and package name. 721 func (p *parser) maybeCreatePackage() { 722 if p.pkgname != "" && p.pkgpath != "" { 723 p.pkg = p.getPkg(p.pkgpath, p.pkgname) 724 } 725 } 726 727 // InitDataDirective = "v1" ";" | 728 // "priority" int ";" | 729 // "init" { PackageInit } ";" | 730 // "checksum" unquotedString ";" . 731 func (p *parser) parseInitDataDirective() { 732 if p.tok != scanner.Ident { 733 // unexpected token kind; panic 734 p.expect(scanner.Ident) 735 } 736 737 switch p.lit { 738 case "v1": 739 p.next() 740 p.expect(';') 741 742 case "priority": 743 p.next() 744 p.initdata.Priority = int(p.parseInt()) 745 p.expect(';') 746 747 case "init": 748 p.next() 749 for p.tok != ';' && p.tok != scanner.EOF { 750 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit()) 751 } 752 p.expect(';') 753 754 case "checksum": 755 // Don't let the scanner try to parse the checksum as a number. 756 defer func(mode uint) { 757 p.scanner.Mode = mode 758 }(p.scanner.Mode) 759 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats 760 p.next() 761 p.parseUnquotedString() 762 p.expect(';') 763 764 default: 765 p.errorf("unexpected identifier: %q", p.lit) 766 } 767 } 768 769 // Directive = InitDataDirective | 770 // "package" unquotedString ";" | 771 // "pkgpath" unquotedString ";" | 772 // "import" unquotedString unquotedString string ";" | 773 // "func" Func ";" | 774 // "type" Type ";" | 775 // "var" Var ";" | 776 // "const" Const ";" . 777 func (p *parser) parseDirective() { 778 if p.tok != scanner.Ident { 779 // unexpected token kind; panic 780 p.expect(scanner.Ident) 781 } 782 783 switch p.lit { 784 case "v1", "priority", "init", "checksum": 785 p.parseInitDataDirective() 786 787 case "package": 788 p.next() 789 p.pkgname = p.parseUnquotedString() 790 p.maybeCreatePackage() 791 p.expect(';') 792 793 case "pkgpath": 794 p.next() 795 p.pkgpath = p.parseUnquotedString() 796 p.maybeCreatePackage() 797 p.expect(';') 798 799 case "import": 800 p.next() 801 pkgname := p.parseUnquotedString() 802 pkgpath := p.parseUnquotedString() 803 p.getPkg(pkgpath, pkgname) 804 p.parseString() 805 p.expect(';') 806 807 case "func": 808 p.next() 809 fun := p.parseFunc(p.pkg) 810 if fun != nil { 811 p.pkg.Scope().Insert(fun) 812 } 813 p.expect(';') 814 815 case "type": 816 p.next() 817 p.parseType(p.pkg) 818 p.expect(';') 819 820 case "var": 821 p.next() 822 v := p.parseVar(p.pkg) 823 p.pkg.Scope().Insert(v) 824 p.expect(';') 825 826 case "const": 827 p.next() 828 c := p.parseConst(p.pkg) 829 p.pkg.Scope().Insert(c) 830 p.expect(';') 831 832 default: 833 p.errorf("unexpected identifier: %q", p.lit) 834 } 835 } 836 837 // Package = { Directive } . 838 func (p *parser) parsePackage() *types.Package { 839 for p.tok != scanner.EOF { 840 p.parseDirective() 841 } 842 for _, typ := range p.typeMap { 843 if it, ok := typ.(*types.Interface); ok { 844 it.Complete() 845 } 846 } 847 p.pkg.MarkComplete() 848 return p.pkg 849 } 850 851 // InitData = { InitDataDirective } . 852 func (p *parser) parseInitData() { 853 for p.tok != scanner.EOF { 854 p.parseInitDataDirective() 855 } 856 }