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  }