func readIdentifier(r *kmgGoReader.Reader) []byte { buf := &bytes.Buffer{} if r.IsEof() { panic(r.GetFileLineInfo() + " unexcept EOF") } b := r.ReadRune() if b == '_' || unicode.IsLetter(b) { buf.WriteRune(b) } else { r.UnreadRune() return nil } for { if r.IsEof() { return buf.Bytes() } b := r.ReadRune() if b == '_' || unicode.IsLetter(b) || unicode.IsDigit(b) { buf.WriteRune(b) } else { r.UnreadRune() return buf.Bytes() // 不是Identifier的东西留个调用者处理 } } }
// 此处已经读过了 / func handleSlashInGoChar(r *kmgGoReader.Reader, buf *bytes.Buffer) { if r.IsEof() { panic(r.GetFileLineInfo() + " unexcept EOF") } b := r.ReadByte() switch b { case '0', '1', '2', '3', '4', '5', '6', '7': r.UnreadByte() octal := r.MustReadWithSize(3) b64, err := strconv.ParseUint(string(octal), 8, 8) if err != nil { panic(r.GetFileLineInfo() + " " + err.Error()) } buf.WriteByte(byte(b64)) case 'x': octal := r.MustReadWithSize(2) b64, err := strconv.ParseUint(string(octal), 16, 8) if err != nil { panic(r.GetFileLineInfo() + " " + err.Error()) } buf.WriteByte(byte(b64)) case 'u': octal := r.MustReadWithSize(4) b64, err := strconv.ParseUint(string(octal), 16, 16) if err != nil { panic(r.GetFileLineInfo() + " " + err.Error()) } buf.WriteRune(rune(b64)) case 'U': octal := r.MustReadWithSize(8) b64, err := strconv.ParseUint(string(octal), 16, 32) if err != nil { panic(r.GetFileLineInfo() + " " + err.Error()) } buf.WriteRune(rune(b64)) case 'a': buf.WriteByte('\a') case 'b': buf.WriteByte('\b') case 'f': buf.WriteByte('\f') case 'n': buf.WriteByte('\n') case 'r': buf.WriteByte('\r') case 't': buf.WriteByte('\t') case 'v': buf.WriteByte('\v') case '\\': buf.WriteByte('\\') case '\'': buf.WriteByte('\'') case '"': buf.WriteByte('"') default: panic(r.GetFileLineInfo() + " unexcept byte " + strconv.Itoa(int(b))) } }
// 正确跳过该部分. func (gofile *File) readGoVar(r *kmgGoReader.Reader) { r.MustReadMatch([]byte("var")) r.ReadAllSpace() b := r.ReadByte() if b == '(' { readMatchSmallParantheses(r) return } r.UnreadByte() readIdentifier(r) r.ReadAllSpace() b = r.ReadByte() if b == '=' { r.ReadAllSpace() } for { if b == '"' || b == '`' { r.UnreadByte() MustReadGoString(r) } if b == '\'' { r.UnreadByte() mustReadGoChar(r) } if b == '\n' { return } if b == '{' { //里面可以字面写东西. readMatchBigParantheses(r) //TODO 正确跳过该部分 /* 简单解决下列情况 var UnreadRuneErrorTests = []struct { name string f func(*Reader) }{ {"Read", func(r *Reader) { r.Read([]byte{0}) }}, {"ReadByte", func(r *Reader) { r.ReadByte() }}, {"UnreadRune", func(r *Reader) { r.UnreadRune() }}, {"Seek", func(r *Reader) { r.Seek(0, 1) }}, {"WriteTo", func(r *Reader) { r.WriteTo(&Buffer{}) }}, } */ } if b == '(' { //里面可以调用函数 readMatchSmallParantheses(r) } if r.IsEof() { return } b = r.ReadByte() } }
// 读取一个import语法里面的数据,此处从import关键词开始 func (gofile *File) readImport(r *kmgGoReader.Reader) { r.MustReadMatch([]byte("import")) r.ReadAllSpace() if r.IsEof() { panic(r.GetFileLineInfo() + " unexcept EOF ") } b := r.ReadByte() if b == '(' { for { r.ReadAllSpace() b := r.ReadByte() if b == ')' { return } else { r.UnreadByte() gofile.readImportSpec(r) } } } else { r.UnreadByte() gofile.readImportSpec(r) } }
func readMatchChar(r *kmgGoReader.Reader, starter byte, ender byte) []byte { startPos := r.Pos() level := 1 for { if r.IsEof() { panic(r.GetFileLineInfo() + " unexcept EOF") } b := r.ReadByte() if b == '"' || b == '`' { r.UnreadByte() MustReadGoString(r) } else if b == '\'' { r.UnreadByte() mustReadGoChar(r) } else if b == starter { level++ } else if b == ender { level-- if level == 0 { return r.BufToCurrent(startPos) } } } }
// 可以读这两种 "abc" `abc` ,返回这个东西实际存放的信息. func MustReadGoString(r *kmgGoReader.Reader) (output []byte) { b := r.ReadByte() if b == '"' { buf := &bytes.Buffer{} for { if r.IsEof() { panic(r.GetFileLineInfo() + " unexcept EOF " + buf.String()) } b := r.ReadByte() switch b { case '"': return buf.Bytes() case '\\': handleSlashInGoChar(r, buf) default: buf.WriteByte(b) } } } else if b == '`' { return r.ReadUntilByte('`') } else { panic(fmt.Errorf("%s unexcept byte %d '%s'", r.GetFileLineInfo(), b, string(rune(b)))) } }