func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
	parts := strings.Split(unquotedName, ".")
	if parts[0] == "" {
		parts = parts[1:]
	}
	switch len(parts) {
	case 0:
		p.errorf("malformed qualified name: %q", unquotedName)
	case 1:
		pkgpath = p.pkgpath
		name = parts[0]
	default:
		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
		name = parts[len(parts)-1]
	}
	return
}
qualifiedName = [ ["."] unquotedString "." ] unquotedString .

The above production uses greedy matching.
package gccgoimporter
import (
	"bytes"
	"errors"
	"fmt"
	"go/token"
	"io"
	"strconv"
	"strings"
	"text/scanner"
	"github.com/mailgun/godebug/Godeps/_workspace/src/golang.org/x/tools/go/exact"
	"github.com/mailgun/godebug/Godeps/_workspace/src/golang.org/x/tools/go/types"
)
type parser struct {
	scanner  scanner.Scanner
	tok      rune                       
	lit      string                     
	pkgpath  string                     
	pkgname  string                     
	pkg      *types.Package             
	imports  map[string]*types.Package  
	typeMap  map[int]types.Type         
	initdata InitData                   
}
func (p *parser) init(filename 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.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
	p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
	p.scanner.Filename = filename  
	p.next()
	p.imports = imports
	p.typeMap = make(map[int]types.Type)
}
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.Errorf(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) expectKeyword(keyword string) {
	lit := p.expect(scanner.Ident)
	if lit != keyword {
		p.errorf("expected keyword %s, got %q", keyword, lit)
	}
}
func (p *parser) parseString() string {
	str, err := strconv.Unquote(p.expect(scanner.String))
	if err != nil {
		p.error(err)
	}
	return str
}
func (p *parser) parseUnquotedString() string {
	if p.tok == scanner.EOF {
		p.error("unexpected EOF")
	}
	var buf bytes.Buffer
	buf.WriteString(p.scanner.TokenText())
	for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
		buf.WriteRune(ch)
		p.scanner.Next()
	}
	p.next()
	return buf.String()
}
func (p *parser) next() {
	p.tok = p.scanner.Scan()
	switch p.tok {
	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
		p.lit = p.scanner.TokenText()
	default:
		p.lit = ""
	}
}
func (p *parser) parseQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseString())
}
func (p *parser) parseUnquotedQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseUnquotedString())
}