1
// Copyright 2018 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
7
// parseNumberValue parses a number from the input and returns a Token object.
8
func (d *Decoder) parseNumberValue() (Token, bool) {
10
num := parseNumber(in)
16
numAttrs |= isNegative
21
pos: len(d.orig) - len(d.in),
23
str: num.string(d.in),
31
numDec uint8 = (1 << iota) / 2
37
// number is the result of parsing out a valid number from parseNumber. It
38
// contains data for doing float or integer conversion via the strconv package
39
// in conjunction with the input bytes.
44
// if neg, this is the length of whitespace and comments between
45
// the minus sign and the rest fo the number literal
49
func (num number) string(data []byte) string {
52
if num.kind == numFloat && (data[last] == 'f' || data[last] == 'F') {
55
if num.neg && num.sep > 0 {
56
// strip whitespace/comments between negative sign and the rest
57
strLen := strSize - num.sep
58
str := make([]byte, strLen)
60
copy(str[1:], data[num.sep+1:strSize])
63
return string(data[:strSize])
67
// parseNumber constructs a number object from given input. It allows for the
70
// integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*)
71
// float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?)
73
// It also returns the number of parsed bytes for the given number, 0 if it is
75
func parseNumber(input []byte) number {
91
// Consume any whitespace or comments between the
92
// negative sign and the rest of the number
95
sep = lenBefore - len(s)
106
case s[1] == 'x' || s[1] == 'X':
107
// Parse as hex number.
111
for len(s) > 0 && (('0' <= s[0] && s[0] <= '9') ||
112
('a' <= s[0] && s[0] <= 'f') ||
113
('A' <= s[0] && s[0] <= 'F')) {
122
case '0' <= s[1] && s[1] <= '7':
123
// Parse as octal number.
127
for len(s) > 0 && '0' <= s[0] && s[0] <= '7' {
134
if kind&(numHex|numOct) > 0 {
135
if len(s) > 0 && !isDelim(s[0]) {
138
return number{kind: kind, neg: neg, size: size, sep: sep}
144
case '1' <= s[0] && s[0] <= '9':
147
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
154
// Set kind to numFloat to signify the intent to parse as float. And
155
// that it needs to have other digits after '.'.
162
// . followed by 0 or more digits.
163
if len(s) > 0 && s[0] == '.' {
166
// If decimal point was before any digits, it should be followed by
168
if len(s) == 0 && kind == numFloat {
171
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
179
// e or E followed by an optional - or + and 1 or more digits.
180
if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
184
if s[0] == '+' || s[0] == '-' {
191
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
198
// Optional suffix f or F for floats.
199
if len(s) > 0 && (s[0] == 'f' || s[0] == 'F') {
205
// Check that next byte is a delimiter or it is at the end.
206
if len(s) > 0 && !isDelim(s[0]) {
210
return number{kind: kind, neg: neg, size: size, sep: sep}