一个退役中校教你如何用go语言写一个基于B+树的json数据库(进阶篇)之json字符串解析为BsTr结构(一)

代码地址:https://gitee.com/lineofsight/resob

一、json字符串的解析

(一)json字符串的格式

1.对象式json字符串

s := "{\"put\":{\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"

注:s字符串就是一个典型的对象型json字符串,以大括号开头。

2.数组型json字符串

s = "{\"put\":[\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}},{\"key\":\"1234560\",\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}]}"

   注:s字符串中[\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}},{\"key\":\"1234560\",\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}]就是个数组型json字符串,其实上面的对象型json字符串也包含数组型字符串。

   (二)json字符串的token定义

const (
	JsonObjStart     = 0x0001     // {
	JsonObjEnd       = 0x0002     // }
	JsonArrStart     = 0x0004     //[
	JsonArrEnd       = 0x0008     //]
	JsonNULL         = 0x0010     //value: null
	JsonNum          = 0x0020     //value: number(int float complex)
	JsonStr          = 0x0040     //value: string
	JsonField        = 0x0080     //obj field
	JsonColon        = 0x0100     //:
	JsonComma        = 0x0200     //,
	JsonTrue         = 0x0400     //value:true
	JsonFalse        = 0x0800     //value:false
	JsonBraceBegin   = 0x1000     //{
	JsonBraceEnd     = 0x2000     //}
	JsonSameType     = 0x4000     //arr, not used
	JsonEOF          = 0x8000     //EOF
	JsonStrField     = 0x10000    //string field type
	JsonObjField     = 0x20000    //object field type
	JsonArrField     = 0x40000    //array field type
	JsonAnyField     = 0x80000    //unknown field type
	JsonNumField     = 0x100000   //number field type
	JsonBoolField    = 0x200000   //bool field type
	JsonArrStr       = 0x400000   //string value in array
	JsonArrNum       = 0x800000   //number value in array
	JsonArrTrue      = 0x1000000  //true value in array
	JsonArrFalse     = 0x2000000  //false value in array
	JsonArrNULL      = 0x4000000  //null value in array
	JsonBracketBegin = 0x8000000  //[
	JsonBracketEnd   = 0x10000000 //]
)

(三)json字符串的token结构体定义

type JsonToken struct {
	jtt    JsonTokenType //token type
	parent *JsonToken    //parent
	equity []*JsonToken  //while has child, it demonstrate equivalent of the token; else, no equity, the jttstr demonstrate it
	child  []*JsonToken  // child
	jttstr string        //representative str of a token
	level  int           //depth
	route  []int         //when is json-arr, the route needed. the token type route of each items in a arr item
}

(四)json字符串的解析结构体定义

type JsonParser struct {
	r   *strings.Reader //string reader
	jts []*JsonToken    //slice of JsonToken pointers
}

(五)json字符串token分解

func (jr *JsonParser) Tokening() error {
	var token *JsonToken
	var e error
	token, e = jr.StartGetAJsonToken()
	if e != nil {
		return e
	}
	jr.jts = append(jr.jts, token)
	if token.jtt == JsonEOF {
		return ErrGramma
	}
	for {
		token, e = jr.GetAJsonToken()
		if e != nil {
			return e
		}
		jr.jts = append(jr.jts, token)
		if token.jtt == JsonEOF {
			jr.jts[0].equity = jr.jts
			//nonsense
			jr.jts[len(jr.jts)-1].equity = append(jr.jts[len(jr.jts)-1].equity, jr.jts[0])
			return nil
		}
	}
}

// StartGetAJsonToken start the process of tokening
func (jr *JsonParser) StartGetAJsonToken() (*JsonToken, error) {
	var b byte
	var e error
	// loop read a byte from a json string, ignore blank space
	for {
		b, e = jr.r.ReadByte()
		if e == io.EOF {
			// EOF, return a JsonEOF token
			return &JsonToken{JsonEOF, nil, nil, nil, "", -1, nil}, nil
		} else if e != nil {
			return nil, e
		}
		if b != ' ' {
			switch b {
			case '{':
				// first character is '{', return a JsonBraceBegin token
				return &JsonToken{JsonBraceBegin, nil, nil, nil, string(b), 0, nil}, nil
			case '[':
				//first character is '[', return a JsonBracketBegin token
				return &JsonToken{JsonBracketBegin, nil, nil, nil, string(b), 0, nil}, nil
			default:
				// if first character is not '{' or '[', return simple error
				return nil, ErrGramma
			}
		}
	}
}

func (jr *JsonParser) GetAJsonToken() (*JsonToken, error) {
	var b byte
	var e error
	// loop read a  byte from a json string, ignore blank space
	for {
		b, e = jr.r.ReadByte()
		if e == io.EOF {
			// EOF, return a JsonEOF token
			return &JsonToken{JsonEOF, nil, nil, nil, "", -1, nil}, nil
		} else if e != nil {
			return nil, e
		}
		if b != ' ' {
			break
		}
	}
	switch b {
	case '{': //case '{', return a JsonObjStart token
		return &JsonToken{JsonObjStart, nil, nil, nil, string(b), -1, nil}, nil
	case '}':
		_, e = jr.r.ReadByte()
		if e == io.EOF {
			// if EOF, and pos 0 is '{', return a JsonBraceEnd token, else return error
			if jr.jts[0].jtt == JsonBraceBegin {
				return &JsonToken{JsonBraceEnd, nil, nil, nil, string(b), 0, nil}, nil
			} else {
				return nil, ErrGramma
			}
		} else if e != nil {
			return nil, e
		} else {
			// rollback a byte, return to correct pos
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			//return a JsonObjEnd token
			return &JsonToken{JsonObjEnd, nil, nil, nil, string(b), -1, nil}, nil
		}
	case '[': //case '[', return a JsonArrStart token
		return &JsonToken{JsonArrStart, nil, nil, nil, string(b), -1, nil}, nil
	case ']': // as case '}'
		_, e = jr.r.ReadByte()
		if e == io.EOF {
			if jr.jts[0].jtt == JsonBracketBegin {
				return &JsonToken{JsonBracketEnd, nil, nil, nil, string(b), 0, nil}, nil
			} else {
				return nil, ErrGramma
			}
		} else if e != nil {
			return nil, e
		} else {
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			return &JsonToken{JsonArrEnd, nil, nil, nil, string(b), -1, nil}, nil
		}
	case ',': //return a JsonComma token
		return &JsonToken{JsonComma, nil, nil, nil, string(b), -1, nil}, nil
	case ':': //return a JsonColon token
		return &JsonToken{JsonColon, nil, nil, nil, string(b), -1, nil}, nil
	case 'n': //process null value without ""
		return jr.GetNull()
	case 't': //process true value without ""
		return jr.GetTrue()
	case 'f': //process false value without ""
		return jr.GetFalse()
	case '"': //process string value with ""
		return jr.GetString()
	case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': //process numm value without ""
		return jr.GetNumber(b)
	}
	return nil, ErrGramma
}

// GetNull
func (jr *JsonParser) GetNull() (*JsonToken, error) {
	var b byte
	var e error
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'u' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'l' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'l' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	return &JsonToken{JsonNULL, nil, nil, nil, "null", -1, nil}, nil
}

// GetTrue
func (jr *JsonParser) GetTrue() (*JsonToken, error) {
	var b byte
	var e error
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'r' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'u' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'e' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	return &JsonToken{JsonTrue, nil, nil, nil, "true", -1, nil}, nil
}

// GetFalse
func (jr *JsonParser) GetFalse() (*JsonToken, error) {
	var b byte
	var e error
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'a' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'l' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 's' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	b, e = jr.r.ReadByte()
	if e == io.EOF || b != 'e' {
		return nil, ErrGramma
	} else if e != nil {
		return nil, e
	}
	return &JsonToken{JsonFalse, nil, nil, nil, "false", -1, nil}, nil
}

// GetNumber
func (jr *JsonParser) GetNumber(bread byte) (*JsonToken, error) {
	var b, bn byte
	var bs []byte
	var e error
	bs = append(bs, bread)
	for {
		b, e = jr.r.ReadByte()
		if e == io.EOF {
			return nil, ErrGramma
		} else if e != nil {
			return nil, e
		}
		switch b {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			bs = append(bs, b)
		case ',', '}', ']':
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			bss := string(bs)
			if !IsNumber(bss) {
				return nil, ErrGramma
			}
			return &JsonToken{JsonNum, nil, nil, nil, string(bs), -1, nil}, nil
		case '.':
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			bn, e = jr.r.ReadByte()
			if e != nil {
				return nil, e
			}
			if bn == '-' {
				return nil, ErrGramma
			}
			//.
			bn, e = jr.r.ReadByte()
			if e != nil {
				return nil, e
			}
			//.next
			bn, e = jr.r.ReadByte()
			if e != nil {
				return nil, e
			}
			if bn == ',' || bn == '}' || bn == ']' {
				return nil, ErrGramma
			}
			bs = append(bs, b)
			bs = append(bs, bn)
		default:
			return nil, ErrGramma
		}
	}
}

// GetString donot permit string value with “
func (jr *JsonParser) GetString() (*JsonToken, error) {
	var b, bn byte
	var e error
	var bs []byte
	for {
		b, e = jr.r.ReadByte()
		if e == io.EOF {
			return &JsonToken{JsonEOF, nil, nil, nil, "", -1, nil}, nil
		} else if e != nil {
			return nil, e
		}
		switch b {
		case '\\': //process \
			bn, e = jr.r.ReadByte()
			if e == io.EOF {
				return nil, ErrGramma
			} else if e != nil {
				return nil, e
			}
			// donot support '/f' '/b' '/\'
			switch bn {
			case 'u': //process utf-8 string
				for i := 0; i < 4; i++ {
					bn, e = jr.r.ReadByte()
					if e == io.EOF {
						return nil, ErrGramma
					} else if e != nil {
						return nil, e
					}
					if (bn >= '0' && bn <= '9') || (bn >= 'a' && bn <= 'f') || (bn >= 'A' && bn <= 'F') {
						bs = append(bs, bn)
					} else {
						return nil, ErrGramma
					}
				}
			case '\\':
				bs = append(bs, bn)
			}
		case '\r', '\n': //donot permit \r \n
			return nil, ErrGramma
		case '\t': //permit
			bs = append(bs, b)
		case '"': // end of a string
			bn, e = jr.r.ReadByte() // read next byte
			if e == io.EOF {        // if EOF, error
				return nil, ErrGramma
			} else if e != nil {
				return nil, e
			}
			//rollback a byte
			e = jr.r.UnreadByte()
			if e != nil {
				return nil, e
			}
			if bn == ':' { // field str
				switch bs[0] {
				//JsonFiled do not permit start with '+' '-' or number
				case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
					return nil, ErrGramma
				default:
					return &JsonToken{JsonField, nil, nil, nil, string(bs), -1, nil}, nil
				}
			} else { //value str
				return &JsonToken{JsonStr, nil, nil, nil, string(bs), -1, nil}, nil
			}
		default: //in middle, append
			bs = append(bs, b)
		}
	}
}

注:GetNumber并没有对complex类型进行解析。

s := "{\"put\":{\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"

   token分解如下:

4096 {
128 put
256 :
1 {
128 putjsontest
256 :
1 {
128 aaa
256 :
64 sdf	sdfsfe29asdf
512 ,
128 aaab
256 :
1024 true
512 ,
128 arrarrstrct
256 :
1 {
128 nnn
256 :
32 -1234567890
512 ,
128 ccc
256 :
4 [
4 [
64 sdf	sdfsfe29asdf
512 ,
64 nmbndfvdfgfdg
8 ]
512 ,
4 [
64 sdf	sdfsfe29asdf
512 ,
64 poiuiyyttt
8 ]
8 ]
2 }
512 ,
128 ddd
256 :
64 sdf	sdfsfe29asdf
512 ,
128 fff
256 :
2048 false
512 ,
128 comboolarr
256 :
4 [
1 {
128 boolarr0
256 :
4 [
1024 true
512 ,
2048 false
8 ]
2 }
512 ,
1 {
128 boolarr1
256 :
4 [
1024 true
512 ,
2048 false
8 ]
2 }
8 ]
2 }
2 }
8192 }
32768 

(六)json字符串语法分解

// __global_Jsontoken_expect define the rules of a correct json string
var __global_Jsontoken_expect = map[int]int{
	JsonBraceBegin:   JsonStrField | JsonObjField | JsonArrField | JsonAnyField | JsonNumField | JsonBoolField | JsonField | JsonBraceEnd,
	JsonBracketBegin: JsonStr | JsonTrue | JsonFalse | JsonNULL | JsonNum | JsonObjStart | JsonArrStart,
	JsonObjStart:     JsonStrField | JsonObjField | JsonArrField | JsonAnyField | JsonNumField | JsonBoolField | JsonField | JsonObjEnd,
	JsonField:        JsonColon,
	JsonStrField:     JsonColon,
	JsonObjField:     JsonColon,
	JsonArrField:     JsonColon,
	JsonAnyField:     JsonColon,
	JsonNumField:     JsonColon,
	JsonBoolField:    JsonColon,
	JsonColon:        JsonStr | JsonTrue | JsonFalse | JsonNULL | JsonNum | JsonObjStart | JsonArrStart,
	JsonComma:        JsonField | JsonStr | JsonTrue | JsonFalse | JsonNULL | JsonNum | JsonObjStart | JsonArrStart,
	JsonStr:          JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonTrue:         JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonFalse:        JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonNULL:         JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonNum:          JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonArrStart:     JsonStr | JsonTrue | JsonFalse | JsonNULL | JsonNum | JsonObjStart | JsonArrStart,
	JsonObjEnd:       JsonComma | JsonBraceEnd | JsonArrEnd | JsonObjEnd,
	JsonArrEnd:       JsonComma | JsonBraceEnd | JsonObjEnd | JsonArrEnd,
	JsonBraceEnd:     JsonEOF,
	JsonBracketEnd:   JsonEOF,
	//skip comma, special check for arr
	JsonArrStr:   JsonArrStr | JsonArrNULL | JsonStr,
	JsonArrNum:   JsonArrNum | JsonNum,
	JsonArrTrue:  JsonArrTrue | JsonArrFalse | JsonTrue | JsonFalse,
	JsonArrFalse: JsonArrFalse | JsonArrTrue | JsonTrue | JsonFalse,
	JsonArrNULL:  JsonArrStart | JsonObjStart | JsonArrStr | JsonArrNULL | JsonStr | JsonNULL,
}

// FindNormalGrammaError find normal gramma errors with map:__global_Jsontoken_expect
func (jr *JsonParser) FindNormalGrammaError() (int, int, string, error) {
	ljrjts := len(jr.jts)
	for i := 0; i < ljrjts-1; i++ {
		if __global_Jsontoken_expect[jr.jts[i].jtt]&jr.jts[i+1].jtt == 0 {
			return i, jr.jts[i].jtt, jr.jts[i].jttstr, ErrGramma
		}
	}
	return ljrjts, -1, "", nil
}

// DissembleObj assemble a token tree with a same slice of JsonToken pointers recursively
// initial state: jr.jts[0],(starti, endi)--(1,len-1)
func (jr *JsonParser) DissembleObj(parent *JsonToken, starti, end int) error {
	jts := parent.equity[starti:end] //starti and end will be reduced recursively in a same slice of token pointers
	ljts := len(jts)
	for i := 0; i < ljts; i++ {
		switch jts[i].jtt {
		case JsonField: //JsonField will be modified to proprietary field, e.g. JsonStrField, JsonNumField etc.
			if i+2 > len(jts) {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			//skip next byte, i.e. colon
			switch jts[i+2].jtt {
			case JsonStr: // string value
				jts[i].jtt = JsonStrField                       // JsonField update to JsonStrField
				jts[i].parent = parent                          //point to parent
				parent.child = append(parent.child, jts[i])     //append to parent as a child
				jts[i].level = parent.level + 1                 // depth add 1
				jts[i].equity = append(jts[i].equity, jts[i+2]) //append the value to JsonField as a equity
				i = i + 2                                       // index add 2
			case JsonNum: // Num value
				jts[i].jtt = JsonNumField                       // JsonField update to JsonNumField
				jts[i].parent = parent                          //point to parent
				parent.child = append(parent.child, jts[i])     //append to parent as a child
				jts[i].level = parent.level + 1                 // depth add 1
				jts[i].equity = append(jts[i].equity, jts[i+2]) //append the value to JsonField as a equity
				i = i + 2                                       // index add 2
			case JsonNULL: //null value
				jts[i].jtt = JsonAnyField //JsonField update to JsonAnyField, because of specific type is unknown
				jts[i].parent = parent
				parent.child = append(parent.child, jts[i])
				jts[i].level = parent.level + 1
				jts[i].equity = append(jts[i].equity, jts[i+2])
				i = i + 2
			case JsonTrue, JsonFalse: //bool value
				jts[i].jtt = JsonBoolField // JsonField update to JsonBoolField
				jts[i].parent = parent
				parent.child = append(parent.child, jts[i])
				jts[i].level = parent.level + 1
				jts[i].equity = append(jts[i].equity, jts[i+2])
				i = i + 2
			case JsonObjStart: //Object
				jts[i].jtt = JsonObjField // JsonField update to JsonObjField
				jts[i].parent = parent
				n := 1                //for finding JsonObjEnd
				j := i + 3            //skip : and {
				for ; j < ljts; j++ { //len of current token slice
					if jts[j].jtt == JsonObjStart {
						n++
					} else if jts[j].jtt == JsonObjEnd {
						n--
						if n == 0 {
							parent.child = append(parent.child, jts[i]) //get the JsonObjEnd pos
							jts[i].equity = jts[i+3 : j+1]
							break
						}
					}
				}
				jts[i].level = parent.level + 1
				if j >= ljts { //not match, error
					log.Println("EEEEEEE")
					return ErrGramma
				}
				//recursive call DissambleObj for its quity:the token pointers included in {}
				jr.DissembleObj(jts[i], 0, len(jts[i].equity))
				i = j
			case JsonArrStart: //array
				jts[i].jtt = JsonArrField // JsonField update to JsonArrField
				jts[i].parent = parent
				n := 1     //for finding JsonObjEnd
				j := i + 3 //skip : and [
				for ; j < ljts; j++ {
					if jts[j].jtt == JsonArrStart {
						n++
					} else if jts[j].jtt == JsonArrEnd {
						n--
						if n == 0 {
							parent.child = append(parent.child, jts[i]) //get the JsonArrEnd pos
							jts[i].equity = jts[i+3 : j+1]
							break
						}
					}
				}
				jts[i].level = parent.level + 1
				if j >= ljts { //not match, error
					log.Println("EEEEEEE")
					return ErrGramma
				}
				//recursive call DissambleObj for its quity:the token pointers included in []
				jr.DissembleArr(jts[i], 0, len(jts[i].equity))
				i = j
			}

		}
	}
	return nil
}

// DissembleArr assemble a token tree with a same slice of JsonToken pointers recursively
func (jr *JsonParser) DissembleArr(parent *JsonToken, starti, end int) error {
	jts := parent.equity[starti:end]
	ljts := len(jts)
	for i := 0; i < ljts; i++ {
		switch jts[i].jtt {
		case JsonStr: //string value
			jts[i].jtt = JsonArrStr //update JsonStr to JsonArrStr
			//detect gramma error
			//if next token is not JsonComma, probe next expect token
			if jts[i+1].jtt != JsonComma && __global_Jsontoken_expect[JsonStr]&jts[i+1].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
				//if next token is JsonComma, probe next next expect token
			} else if jts[i+1].jtt == JsonComma && __global_Jsontoken_expect[JsonArrStr]&jts[i+2].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jts[i].parent = parent
			jts[i].level = parent.level + 1
			parent.child = append(parent.child, jts[i])
			i = i + 1 //different form DissambleObj (i+2)
		case JsonNum: //analogy with JsonStr in JsonArr
			jts[i].jtt = JsonArrNum
			if jts[i+1].jtt != JsonComma && __global_Jsontoken_expect[JsonNum]&jts[i+1].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			} else if jts[i+1].jtt == JsonComma && __global_Jsontoken_expect[JsonArrNum]&jts[i+2].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jts[i].parent = parent
			jts[i].level = parent.level + 1
			parent.child = append(parent.child, jts[i])
			i = i + 1
		case JsonTrue: //value true
			jts[i].jtt = JsonArrTrue
			if jts[i+1].jtt != JsonComma && __global_Jsontoken_expect[JsonTrue]&jts[i+1].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			} else if jts[i+1].jtt == JsonComma && __global_Jsontoken_expect[JsonArrTrue]&jts[i+2].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jts[i].parent = parent
			jts[i].level = parent.level + 1
			parent.child = append(parent.child, jts[i])
			i = i + 1
		case JsonFalse: //analogy with JsonTrue
			jts[i].jtt = JsonArrFalse
			if jts[i+1].jtt != JsonComma && __global_Jsontoken_expect[JsonFalse]&jts[i+1].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			} else if jts[i+1].jtt == JsonComma && __global_Jsontoken_expect[JsonArrFalse]&jts[i+2].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jts[i].parent = parent
			jts[i].level = parent.level + 1
			parent.child = append(parent.child, jts[i])
			i = i + 1
		case JsonNULL: //check the same type is difficult
			jts[i].jtt = JsonArrNULL
			if jts[i+1].jtt != JsonComma && __global_Jsontoken_expect[JsonNULL]&jts[i+1].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			} else if jts[i+1].jtt == JsonComma && __global_Jsontoken_expect[JsonArrNULL]&jts[i+2].jtt == 0 {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jts[i].parent = parent
			jts[i].level = parent.level + 1
			parent.child = append(parent.child, jts[i])
			i = i + 1
		case JsonObjStart: //check the same type is difficult
			jts[i].parent = parent
			n := 1
			j := i + 1 //different form DissambleObj(i+3)
			for ; j < ljts; j++ {
				if jts[j].jtt == JsonObjStart {
					n++
				} else if jts[j].jtt == JsonObjEnd {
					n--
					if n == 0 {
						parent.child = append(parent.child, jts[i])
						jts[i].equity = jts[i+1 : j+1] //different form DissambleObj(i+3)
						break
					}
				}
			}
			jts[i].level = parent.level + 1
			if j >= ljts {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jr.DissembleObj(jts[i], 0, len(jts[i].equity))
			i = j
		case JsonArrStart: //check the same type is difficult, will be bug
			jts[i].parent = parent
			n := 1
			j := i + 1 //different form DissambleObj(i+3)
			for ; j < ljts; j++ {
				if jts[j].jtt == JsonArrStart {
					n++
				} else if jts[j].jtt == JsonArrEnd {
					n--
					if n == 0 {
						parent.child = append(parent.child, jts[i])
						jts[i].equity = jts[i+1 : j+1] //different form DissambleObj(i+3)
						break
					}
				}
			}
			jts[i].level = parent.level + 1
			if j >= ljts {
				log.Println("EEEEEEE")
				return ErrGramma
			}
			jr.DissembleArr(jts[i], 0, len(jts[i].equity))
			i = j
		}
	}
	return nil
}

// CheckArrTypeRoute checks the token type route of each arr item
func (jr *JsonParser) CheckArrTypeRoute() (*JsonToken, *JsonToken, error) {
	return jr.jts[0].CheckArrTypeRoute() //begin with token 0
}

func (jt *JsonToken) CheckArrTypeRoute() (*JsonToken, *JsonToken, error) {
	if jt.child == nil {
		return nil, nil, nil
	} else {
		//the equity of JsonArrField or JsonArrStart is the tokens included in []
		if jt.jtt == JsonArrField || jt.jtt == JsonArrStart {
			if len(jt.child) == 1 {
				if jt.child[0].jtt == JsonArrStart { //nested arr
					log.Println(jt.child[0].CheckArrTypeRoute())
				}
			}
			//start from first child, equity of child is not nil => child is a obj or arr
			if len(jt.child[0].equity) > 0 {
				for i := 0; i < len(jt.child); i++ {
					if i < len(jt.child)-1 {
						//judge items len, if different, i.e. error
						if len(jt.child[i].equity) != len(jt.child[i+1].equity) {
							log.Println("EEEEEE")
							return jt.child[i], jt.child[i+1], ErrGramma
						}
					}
					//-1 is for comparing with next child
					//equity is a slice of token pointers, that is a equivalence of the token
					for j := 0; j < len(jt.child[i].equity)-1; j++ {
						//-1 is for comparing with next child
						if i < len(jt.child)-1 {
							//the same index of equity should has the same token type, or the expect token type
							if jt.child[i].equity[j].jtt != jt.child[i+1].equity[j].jtt {
								if __global_Jsontoken_expect[jt.child[i].equity[j].jtt]&jt.child[i+1].equity[j].jtt == 0 {
									log.Println("EEEEEE")
									return jt.child[i], jt.child[i+1], ErrGramma
								}
							}
						}
						// add to route
						jt.child[i].route = append(jt.child[i].route, jt.child[i].equity[j].jtt)
					}
				}
				//JsonArrNull need special treatment
				//has no equity
			} else if jt.child[0].jtt == JsonArrNULL {
				for i := 0; i < len(jt.child)-1; i++ {
					//based on the token type of neighbour item  and expect token
					if jt.child[i].jtt != jt.child[i+1].jtt {
						if __global_Jsontoken_expect[jt.child[i].jtt]&jt.child[i+1].jtt == 0 {
							log.Println("EEEEEE")
							return jt.child[i], jt.child[i+1], ErrGramma
						}
					}
				}
			}
		} else {
			//search arr recursively
			for i := 0; i < len(jt.child); i++ {
				log.Println(jt.child[i].CheckArrTypeRoute())
			}
		}
		return nil, nil, nil
	}
}

// Print the token tree
func (jr *JsonParser) Print() {
	jr.jts[0].Print()
}

// Print the token tree
func (jt *JsonToken) Print() {
	if jt.child == nil {
		log.Printf("level:%d,TokenCode:0X%x,TokenString:%s,JsonArrTokenCodeRoute:%v,equity:%v", jt.level, jt.jtt, jt.jttstr, jt.route, jt.equity)
	} else {
		log.Printf("level:%d,TokenCode:0X%x,TokenString:%s,JsonArrTokenCodeRoute:%v,equity:%v", jt.level, jt.jtt, jt.jttstr, jt.route, jt.equity)
		for i := 0; i < len(jt.child); i++ {
			jt.child[i].Print()
		}
	}
}

注:那个全局map用于判断对象型json字符串一般语法错误和数组型json字符串特殊语法错误。 DissembleObj用于建立对象型json字符串的树形语法结构;DissembleArr用于建立数组型json字符串的树形语法结构。CheckArrTypeRoute用于判断数组型json字符串各元素内部的一致性。

s := "{\"put\":{\"putjsontest\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"

Print打印语法树如下:

level:0,TokenCode:0X1000,TokenString:{,JsonArrTokenCodeRoute:[]
equity:&{4096 <nil> [0xc000054000 0xc000054070 0xc0000540e0 0xc000054150 0xc0000541c0 0xc000054230 0xc0000542a0 0xc000054310 0xc000054380 0xc0000543f0 0xc000054460 0xc0000544d0 0xc000054540 0xc0000545b0 0xc000054620 0xc000054690 0xc000054700 0xc000054770 0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030 0xc0000550a0 0xc000055110 0xc000055180 0xc0000551f0 0xc000055260 0xc0000552d0 0xc000055340 0xc0000553b0 0xc000055420 0xc000055490 0xc000055500 0xc000055570 0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30 0xc000055ea0 0xc000055f10 0xc000055f80 0xc00005c000] [0xc000054070] { 0 []}
equity:&{131072 0xc000054000 [0xc0000541c0 0xc000054230 0xc0000542a0 0xc000054310 0xc000054380 0xc0000543f0 0xc000054460 0xc0000544d0 0xc000054540 0xc0000545b0 0xc000054620 0xc000054690 0xc000054700 0xc000054770 0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030 0xc0000550a0 0xc000055110 0xc000055180 0xc0000551f0 0xc000055260 0xc0000552d0 0xc000055340 0xc0000553b0 0xc000055420 0xc000055490 0xc000055500 0xc000055570 0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30 0xc000055ea0 0xc000055f10] [0xc0000541c0] put 1 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{131072 0xc000054070 [0xc000054310 0xc000054380 0xc0000543f0 0xc000054460 0xc0000544d0 0xc000054540 0xc0000545b0 0xc000054620 0xc000054690 0xc000054700 0xc000054770 0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030 0xc0000550a0 0xc000055110 0xc000055180 0xc0000551f0 0xc000055260 0xc0000552d0 0xc000055340 0xc0000553b0 0xc000055420 0xc000055490 0xc000055500 0xc000055570 0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30 0xc000055ea0] [0xc000054310 0xc0000544d0 0xc000054690 0xc000055110 0xc0000552d0 0xc000055490] putjsontest 2 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{65536 0xc0000541c0 [0xc0000543f0] [] aaa 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000545b0] [] aaab 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1024 <nil> [] [] true -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{131072 0xc0000541c0 [0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030] [0xc0000547e0 0xc0000549a0] arrarrstrct 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{1048576 0xc000054690 [0xc0000548c0] [] nnn 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{32 <nil> [] [] -1234567890 -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc000054690 [0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0] [0xc000054af0 0xc000054d90] ccc 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{4 0xc0000549a0 [0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0] [0xc000054b60 0xc000054c40] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4 0xc0000549a0 [0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50] [0xc000054e00 0xc000054ee0] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{65536 0xc0000541c0 [0xc0000551f0] [] ddd 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000553b0] [] fff 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{2048 <nil> [] [] false -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc0000541c0 [0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30] [0xc0000555e0 0xc000055a40] comboolarr 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{1 0xc000055490 [0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960] [0xc000055650] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc0000555e0 [0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0] [0xc0000557a0 0xc000055880] boolarr0 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{1 0xc000055490 [0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0] [0xc000055ab0] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc000055a40 [0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50] [0xc000055c00 0xc000055ce0] boolarr1 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{8192 <nil> [] [] } 0 []}
equity:&{32768 <nil> [0xc000054000] []  -1 []}
level:1,TokenCode:0X20000,TokenString:put,JsonArrTokenCodeRoute:[]
equity:&{131072 0xc000054070 [0xc000054310 0xc000054380 0xc0000543f0 0xc000054460 0xc0000544d0 0xc000054540 0xc0000545b0 0xc000054620 0xc000054690 0xc000054700 0xc000054770 0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030 0xc0000550a0 0xc000055110 0xc000055180 0xc0000551f0 0xc000055260 0xc0000552d0 0xc000055340 0xc0000553b0 0xc000055420 0xc000055490 0xc000055500 0xc000055570 0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30 0xc000055ea0] [0xc000054310 0xc0000544d0 0xc000054690 0xc000055110 0xc0000552d0 0xc000055490] putjsontest 2 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{65536 0xc0000541c0 [0xc0000543f0] [] aaa 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000545b0] [] aaab 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1024 <nil> [] [] true -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{131072 0xc0000541c0 [0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030] [0xc0000547e0 0xc0000549a0] arrarrstrct 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{1048576 0xc000054690 [0xc0000548c0] [] nnn 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{32 <nil> [] [] -1234567890 -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc000054690 [0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0] [0xc000054af0 0xc000054d90] ccc 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{4 0xc0000549a0 [0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0] [0xc000054b60 0xc000054c40] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4 0xc0000549a0 [0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50] [0xc000054e00 0xc000054ee0] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{65536 0xc0000541c0 [0xc0000551f0] [] ddd 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000553b0] [] fff 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{2048 <nil> [] [] false -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc0000541c0 [0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30] [0xc0000555e0 0xc000055a40] comboolarr 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{1 0xc000055490 [0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960] [0xc000055650] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc0000555e0 [0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0] [0xc0000557a0 0xc000055880] boolarr0 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{1 0xc000055490 [0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0] [0xc000055ab0] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc000055a40 [0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50] [0xc000055c00 0xc000055ce0] boolarr1 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{2 <nil> [] [] } -1 []}
level:2,TokenCode:0X20000,TokenString:putjsontest,JsonArrTokenCodeRoute:[]
equity:&{65536 0xc0000541c0 [0xc0000543f0] [] aaa 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000545b0] [] aaab 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1024 <nil> [] [] true -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{131072 0xc0000541c0 [0xc0000547e0 0xc000054850 0xc0000548c0 0xc000054930 0xc0000549a0 0xc000054a10 0xc000054a80 0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0 0xc000055030] [0xc0000547e0 0xc0000549a0] arrarrstrct 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{1 <nil> [] [] { -1 []}
equity:&{1048576 0xc000054690 [0xc0000548c0] [] nnn 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{32 <nil> [] [] -1234567890 -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc000054690 [0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0] [0xc000054af0 0xc000054d90] ccc 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{4 0xc0000549a0 [0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0] [0xc000054b60 0xc000054c40] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4 0xc0000549a0 [0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50] [0xc000054e00 0xc000054ee0] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{65536 0xc0000541c0 [0xc0000551f0] [] ddd 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{2097152 0xc0000541c0 [0xc0000553b0] [] fff 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{2048 <nil> [] [] false -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc0000541c0 [0xc0000555e0 0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960 0xc0000559d0 0xc000055a40 0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0 0xc000055e30] [0xc0000555e0 0xc000055a40] comboolarr 3 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{1 0xc000055490 [0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960] [0xc000055650] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc0000555e0 [0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0] [0xc0000557a0 0xc000055880] boolarr0 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{1 0xc000055490 [0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0] [0xc000055ab0] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc000055a40 [0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50] [0xc000055c00 0xc000055ce0] boolarr1 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
level:3,TokenCode:0X10000,TokenString:aaa,JsonArrTokenCodeRoute:[]
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
level:3,TokenCode:0X200000,TokenString:aaab,JsonArrTokenCodeRoute:[]
equity:&{1024 <nil> [] [] true -1 []}
level:3,TokenCode:0X20000,TokenString:arrarrstrct,JsonArrTokenCodeRoute:[]
equity:&{1048576 0xc000054690 [0xc0000548c0] [] nnn 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{32 <nil> [] [] -1234567890 -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{262144 0xc000054690 [0xc000054af0 0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0 0xc000054d20 0xc000054d90 0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50 0xc000054fc0] [0xc000054af0 0xc000054d90] ccc 4 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{4 0xc0000549a0 [0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0] [0xc000054b60 0xc000054c40] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4 0xc0000549a0 [0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50] [0xc000054e00 0xc000054ee0] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
level:4,TokenCode:0X100000,TokenString:nnn,JsonArrTokenCodeRoute:[]
equity:&{32 <nil> [] [] -1234567890 -1 []}
level:4,TokenCode:0X40000,TokenString:ccc,JsonArrTokenCodeRoute:[]
equity:&{4 0xc0000549a0 [0xc000054b60 0xc000054bd0 0xc000054c40 0xc000054cb0] [0xc000054b60 0xc000054c40] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4 0xc0000549a0 [0xc000054e00 0xc000054e70 0xc000054ee0 0xc000054f50] [0xc000054e00 0xc000054ee0] [ 5 [4194304 512 4194304]}
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{8 <nil> [] [] ] -1 []}
level:5,TokenCode:0X4,TokenString:[,JsonArrTokenCodeRoute:[4194304 512 4194304]
equity:&{4194304 0xc000054af0 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054af0 [] [] nmbndfvdfgfdg 6 []}
equity:&{8 <nil> [] [] ] -1 []}
level:6,TokenCode:0X400000,TokenString:sdf	sdfsfe29asdf,JsonArrTokenCodeRoute:[]
level:6,TokenCode:0X400000,TokenString:nmbndfvdfgfdg,JsonArrTokenCodeRoute:[]
level:5,TokenCode:0X4,TokenString:[,JsonArrTokenCodeRoute:[4194304 512 4194304]
equity:&{4194304 0xc000054d90 [] [] sdf	sdfsfe29asdf 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{4194304 0xc000054d90 [] [] poiuiyyttt 6 []}
equity:&{8 <nil> [] [] ] -1 []}
level:6,TokenCode:0X400000,TokenString:sdf	sdfsfe29asdf,JsonArrTokenCodeRoute:[]
level:6,TokenCode:0X400000,TokenString:poiuiyyttt,JsonArrTokenCodeRoute:[]
level:3,TokenCode:0X10000,TokenString:ddd,JsonArrTokenCodeRoute:[]
equity:&{64 <nil> [] [] sdf	sdfsfe29asdf -1 []}
level:3,TokenCode:0X200000,TokenString:fff,JsonArrTokenCodeRoute:[]
equity:&{2048 <nil> [] [] false -1 []}
level:3,TokenCode:0X40000,TokenString:comboolarr,JsonArrTokenCodeRoute:[]
equity:&{1 0xc000055490 [0xc000055650 0xc0000556c0 0xc000055730 0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0 0xc000055960] [0xc000055650] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc0000555e0 [0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0] [0xc0000557a0 0xc000055880] boolarr0 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{1 0xc000055490 [0xc000055ab0 0xc000055b20 0xc000055b90 0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50 0xc000055dc0] [0xc000055ab0] { 4 [262144 256 4 16777216 512 33554432 8]}
equity:&{262144 0xc000055a40 [0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50] [0xc000055c00 0xc000055ce0] boolarr1 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
equity:&{8 <nil> [] [] ] -1 []}
level:4,TokenCode:0X1,TokenString:{,JsonArrTokenCodeRoute:[262144 256 4 16777216 512 33554432 8]
equity:&{262144 0xc0000555e0 [0xc0000557a0 0xc000055810 0xc000055880 0xc0000558f0] [0xc0000557a0 0xc000055880] boolarr0 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
level:5,TokenCode:0X40000,TokenString:boolarr0,JsonArrTokenCodeRoute:[]
equity:&{16777216 0xc000055650 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055650 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
level:6,TokenCode:0X1000000,TokenString:true,JsonArrTokenCodeRoute:[]
level:6,TokenCode:0X2000000,TokenString:false,JsonArrTokenCodeRoute:[]
level:4,TokenCode:0X1,TokenString:{,JsonArrTokenCodeRoute:[262144 256 4 16777216 512 33554432 8]
equity:&{262144 0xc000055a40 [0xc000055c00 0xc000055c70 0xc000055ce0 0xc000055d50] [0xc000055c00 0xc000055ce0] boolarr1 5 []}
equity:&{256 <nil> [] [] : -1 []}
equity:&{4 <nil> [] [] [ -1 []}
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
equity:&{2 <nil> [] [] } -1 []}
level:5,TokenCode:0X40000,TokenString:boolarr1,JsonArrTokenCodeRoute:[]
equity:&{16777216 0xc000055ab0 [] [] true 6 []}
equity:&{512 <nil> [] [] , -1 []}
equity:&{33554432 0xc000055ab0 [] [] false 6 []}
equity:&{8 <nil> [] [] ] -1 []}
level:6,TokenCode:0X1000000,TokenString:true,JsonArrTokenCodeRoute:[]
level:6,TokenCode:0X2000000,TokenString:false,JsonArrTokenCodeRoute:[]
20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值