// Copyright 2018 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package text// parseNumberValue parses a number from the input and returns a Token object.func ( *Decoder) () (Token, bool) { := .in := parseNumber()if .size == 0 {returnToken{}, false } := .kindif .neg { |= isNegative } := .size := .size - 1if .kind == numFloat && (.in[] == 'f' || .in[] == 'F') { = } := Token{kind: Scalar,attrs: numberValue,pos: len(.orig) - len(.in),raw: .in[:.size],str: string(.in[:]),numAttrs: , } .consume(.size)return , true}const (numDecuint8 = (1 << iota) / 2numHexnumOctnumFloat)// number is the result of parsing out a valid number from parseNumber. It// contains data for doing float or integer conversion via the strconv package// in conjunction with the input bytes.typenumberstruct {kinduint8negboolsizeint}// parseNumber constructs a number object from given input. It allows for the// following patterns://// integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*)// float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?)//// It also returns the number of parsed bytes for the given number, 0 if it is// not a number.func ( []byte) number { := numDecvarintvarbool := iflen() == 0 {returnnumber{} }// Optional -if [0] == '-' { = true = [1:] ++iflen() == 0 {returnnumber{} } }// C++ allows for whitespace and comments in between the negative sign and // the rest of the number. This logic currently does not but is consistent // with v1.switch {case [0] == '0':iflen() > 1 {switch {case [1] == 'x' || [1] == 'X':// Parse as hex number. = numHex := 2 = [2:]forlen() > 0 && (('0' <= [0] && [0] <= '9') || ('a' <= [0] && [0] <= 'f') || ('A' <= [0] && [0] <= 'F')) { = [1:] ++ }if == 2 {returnnumber{} } += case'0' <= [1] && [1] <= '7':// Parse as octal number. = numOct := 2 = [2:]forlen() > 0 && '0' <= [0] && [0] <= '7' { = [1:] ++ } += }if &(numHex|numOct) > 0 {iflen() > 0 && !isDelim([0]) {returnnumber{} }returnnumber{kind: , neg: , size: } } } = [1:] ++case'1' <= [0] && [0] <= '9': := 1 = [1:]forlen() > 0 && '0' <= [0] && [0] <= '9' { = [1:] ++ } += case [0] == '.':// Set kind to numFloat to signify the intent to parse as float. And // that it needs to have other digits after '.'. = numFloatdefault:returnnumber{} }// . followed by 0 or more digits.iflen() > 0 && [0] == '.' { := 1 = [1:]// If decimal point was before any digits, it should be followed by // other digits.iflen() == 0 && == numFloat {returnnumber{} }forlen() > 0 && '0' <= [0] && [0] <= '9' { = [1:] ++ } += = numFloat }// e or E followed by an optional - or + and 1 or more digits.iflen() >= 2 && ([0] == 'e' || [0] == 'E') { = numFloat = [1:] := 1if [0] == '+' || [0] == '-' { = [1:] ++iflen() == 0 {returnnumber{} } }forlen() > 0 && '0' <= [0] && [0] <= '9' { = [1:] ++ } += }// Optional suffix f or F for floats.iflen() > 0 && ([0] == 'f' || [0] == 'F') { = numFloat = [1:] ++ }// Check that next byte is a delimiter or it is at the end.iflen() > 0 && !isDelim([0]) {returnnumber{} }returnnumber{kind: , neg: , size: }}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)