func (p *parser) parseField() (*types.Var, string) {
	pkg, name := p.parseName(true)
	typ := p.parseType()
	anonymous := false
	if name == "" {
		switch typ := deref(typ).(type) {
		case *types.Basic:  
			pkg = nil
			name = typ.Name()
		case *types.Named:
			obj := typ.Obj()
			pkg = obj.Pkg()  
			name = obj.Name()
		default:
			p.errorf("anonymous field expected")
		}
		anonymous = true
	}
	tag := ""
	if p.tok == scanner.String {
		s := p.expect(scanner.String)
		var err error
		tag, err = strconv.Unquote(s)
		if err != nil {
			p.errorf("invalid struct tag %s: %s", s, err)
		}
	}
	return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
}
Field = Name Type [ string_lit ] .
package gcimporter
import (
	"bufio"
	"errors"
	"fmt"
	"go/build"
	"go/token"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"text/scanner"
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
)
const debug = false
func init() {
	types.DefaultImport = Import
}
var pkgExts = [...]string{".a", ".5", ".6", ".8"}
func FindPkg(path, srcDir string) (filename, id string) {
	if len(path) == 0 {
		return
	}
	id = path
	var noext string
	switch {
	default:
		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
		if bp.PkgObj == "" {
			return
		}
		noext = strings.TrimSuffix(bp.PkgObj, ".a")
	case build.IsLocalImport(path):
		noext = filepath.Join(srcDir, path)
		id = noext
	case filepath.IsAbs(path):
		noext = path
	}
	for _, ext := range pkgExts {
		filename = noext + ext
		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
			return
		}
	}
	filename = ""  
	return
}
func ImportData(imports map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
	defer func() {
		switch r := recover().(type) {
		case nil:
		case importError:
			err = r
		default:
			panic(r)  
		}
	}()
	var p parser
	p.init(filename, id, data, imports)
	pkg = p.parseExport()
	return
}
func Import(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	if path == "unsafe" {
		return types.Unsafe, nil
	}
	srcDir := "."
	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return
		}
	}
	filename, id := FindPkg(path, srcDir)
	if filename == "" {
		err = fmt.Errorf("can't find import: %s", id)
		return
	}
	if pkg = imports[id]; pkg != nil && pkg.Complete() {
		return
	}
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer func() {
		f.Close()
		if err != nil {
			err = fmt.Errorf("reading export data: %s: %v", filename, err)
		}
	}()
	buf := bufio.NewReader(f)
	if err = FindExportData(buf); err != nil {
		return
	}
	pkg, err = ImportData(imports, filename, id, buf)
	return
}
type parser struct {
	scanner scanner.Scanner
	tok     rune                       
	lit     string                     
	id      string                     
	imports map[string]*types.Package  
}
func (p *parser) init(filename, id string, src io.Reader, imports map[string]*types.Package) {
	p.scanner.Init(src)
	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
	p.scanner.Whitespace = 1<<'\t' | 1<<' '
	p.scanner.Filename = filename  
	p.next()
	p.id = id
	p.imports = imports
	if debug {
		for _, pkg := range imports {
			if pkg.Name() == "" {
				fmt.Printf("no package name for %s\n", pkg.Path())
			}
		}
	}
}
func (p *parser) next() {
	p.tok = p.scanner.Scan()
	switch p.tok {
	case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
		p.lit = p.scanner.TokenText()
	default:
		p.lit = ""
	}
	if debug {
		fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
	}
}
func declTypeName(pkg *types.Package, name string) *types.TypeName {
	scope := pkg.Scope()
	if obj := scope.Lookup(name); obj != nil {
		return obj.(*types.TypeName)
	}
	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
	types.NewNamed(obj, nil, nil)
	scope.Insert(obj)
	return obj
}
type importError struct {
	pos scanner.Position
	err error
}
func (e importError) Error() string {
	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
}
func (p *parser) error(err interface{}) {
	if s, ok := err.(string); ok {
		err = errors.New(s)
	}
	panic(importError{p.scanner.Pos(), err.(error)})
}
func (p *parser) errorf(format string, args ...interface{}) {
	p.error(fmt.Sprintf(format, args...))
}
func (p *parser) expect(tok rune) string {
	lit := p.lit
	if p.tok != tok {
		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
	}
	p.next()
	return lit
}
func (p *parser) expectSpecial(tok string) {
	sep := 'x'  
	i := 0
	for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
		sep = p.scanner.Peek()  
		p.next()
		i++
	}
	if i < len(tok) {
		p.errorf("expected %q, got %q", tok, tok[0:i])
	}
}
func (p *parser) expectKeyword(keyword string) {
	lit := p.expect(scanner.Ident)
	if lit != keyword {
		p.errorf("expected keyword %s, got %q", keyword, lit)
	}
}
func (p *parser) parsePackageId() string {
	id, err := strconv.Unquote(p.expect(scanner.String))
	if err != nil {
		p.error(err)
	}
	if id == "" {
		id = p.id
	}
	return id
}
func (p *parser) parsePackageName() string {
	return p.expect(scanner.Ident)
}
func (p *parser) parseDotIdent() string {
	ident := ""
	if p.tok != scanner.Int {
		sep := 'x'  
		for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
			ident += p.lit
			sep = p.scanner.Peek()  
			p.next()
		}
	}
	if ident == "" {
		p.expect(scanner.Ident)  
	}
	return ident
}
func (p *parser) parseQualifiedName() (id, name string) {
	p.expect('@')
	id = p.parsePackageId()
	p.expect('.')
	if p.tok == '?' {
		p.next()
	} else {
		name = p.parseDotIdent()
	}
	return
}
func (p *parser) getPkg(id, name string) *types.Package {
	if id == "unsafe" {
		return types.Unsafe
	}
	pkg := p.imports[id]
	if pkg == nil && name != "" {
		pkg = types.NewPackage(id, name, types.NewScope(nil))
		p.imports[id] = pkg
	}
	return pkg
}
func (p *parser) parseExportedName() (pkg *types.Package, name string) {
	id, name := p.parseQualifiedName()
	pkg = p.getPkg(id, "")
	if pkg == nil {
		p.errorf("%s package not found", id)
	}
	return
}
func (p *parser) parseBasicType() types.Type {
	id := p.expect(scanner.Ident)
	obj := types.Universe.Lookup(id)
	if obj, ok := obj.(*types.TypeName); ok {
		return obj.Type()
	}
	p.errorf("not a basic type: %s", id)
	return nil
}
func (p *parser) parseArrayType() types.Type {
	lit := p.expect(scanner.Int)
	p.expect(']')
	elem := p.parseType()
	n, err := strconv.ParseInt(lit, 10, 64)
	if err != nil {
		p.error(err)
	}
	return types.NewArray(elem, n)
}
func (p *parser) parseMapType() types.Type {
	p.expectKeyword("map")
	p.expect('[')
	key := p.parseType()
	p.expect(']')
	elem := p.parseType()
	return types.NewMap(key, elem)
}
func (p *parser) parseName(materializePkg bool) (pkg *types.Package, name string) {
	switch p.tok {
	case scanner.Ident:
		pkg = p.imports[p.id]
		name = p.lit
		p.next()
	case '?':
		pkg = p.imports[p.id]
		p.next()
	case '@':
		var id string
		id, name = p.parseQualifiedName()
		if materializePkg {
			pkg = p.getPkg(id, "")
			if pkg == nil {
				pkg = types.NewPackage(id, "", nil)
			}
		}
	default:
		p.error("name expected")
	}
	return
}
func deref(typ types.Type) types.Type {
	if p, _ := typ.(*types.Pointer); p != nil {
		return p.Elem()
	}
	return typ
}