decode_number.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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.
  4. package text
  5. // parseNumberValue parses a number from the input and returns a Token object.
  6. func (d *Decoder) parseNumberValue() (Token, bool) {
  7. in := d.in
  8. num := parseNumber(in)
  9. if num.size == 0 {
  10. return Token{}, false
  11. }
  12. numAttrs := num.kind
  13. if num.neg {
  14. numAttrs |= isNegative
  15. }
  16. tok := Token{
  17. kind: Scalar,
  18. attrs: numberValue,
  19. pos: len(d.orig) - len(d.in),
  20. raw: d.in[:num.size],
  21. str: num.string(d.in),
  22. numAttrs: numAttrs,
  23. }
  24. d.consume(num.size)
  25. return tok, true
  26. }
  27. const (
  28. numDec uint8 = (1 << iota) / 2
  29. numHex
  30. numOct
  31. numFloat
  32. )
  33. // number is the result of parsing out a valid number from parseNumber. It
  34. // contains data for doing float or integer conversion via the strconv package
  35. // in conjunction with the input bytes.
  36. type number struct {
  37. kind uint8
  38. neg bool
  39. size int
  40. // if neg, this is the length of whitespace and comments between
  41. // the minus sign and the rest fo the number literal
  42. sep int
  43. }
  44. func (num number) string(data []byte) string {
  45. strSize := num.size
  46. last := num.size - 1
  47. if num.kind == numFloat && (data[last] == 'f' || data[last] == 'F') {
  48. strSize = last
  49. }
  50. if num.neg && num.sep > 0 {
  51. // strip whitespace/comments between negative sign and the rest
  52. strLen := strSize - num.sep
  53. str := make([]byte, strLen)
  54. str[0] = data[0]
  55. copy(str[1:], data[num.sep+1:strSize])
  56. return string(str)
  57. }
  58. return string(data[:strSize])
  59. }
  60. // parseNumber constructs a number object from given input. It allows for the
  61. // following patterns:
  62. //
  63. // integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*)
  64. // float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?)
  65. //
  66. // It also returns the number of parsed bytes for the given number, 0 if it is
  67. // not a number.
  68. func parseNumber(input []byte) number {
  69. kind := numDec
  70. var size int
  71. var neg bool
  72. s := input
  73. if len(s) == 0 {
  74. return number{}
  75. }
  76. // Optional -
  77. var sep int
  78. if s[0] == '-' {
  79. neg = true
  80. s = s[1:]
  81. size++
  82. // Consume any whitespace or comments between the
  83. // negative sign and the rest of the number
  84. lenBefore := len(s)
  85. s = consume(s, 0)
  86. sep = lenBefore - len(s)
  87. size += sep
  88. if len(s) == 0 {
  89. return number{}
  90. }
  91. }
  92. switch {
  93. case s[0] == '0':
  94. if len(s) > 1 {
  95. switch {
  96. case s[1] == 'x' || s[1] == 'X':
  97. // Parse as hex number.
  98. kind = numHex
  99. n := 2
  100. s = s[2:]
  101. for len(s) > 0 && (('0' <= s[0] && s[0] <= '9') ||
  102. ('a' <= s[0] && s[0] <= 'f') ||
  103. ('A' <= s[0] && s[0] <= 'F')) {
  104. s = s[1:]
  105. n++
  106. }
  107. if n == 2 {
  108. return number{}
  109. }
  110. size += n
  111. case '0' <= s[1] && s[1] <= '7':
  112. // Parse as octal number.
  113. kind = numOct
  114. n := 2
  115. s = s[2:]
  116. for len(s) > 0 && '0' <= s[0] && s[0] <= '7' {
  117. s = s[1:]
  118. n++
  119. }
  120. size += n
  121. }
  122. if kind&(numHex|numOct) > 0 {
  123. if len(s) > 0 && !isDelim(s[0]) {
  124. return number{}
  125. }
  126. return number{kind: kind, neg: neg, size: size, sep: sep}
  127. }
  128. }
  129. s = s[1:]
  130. size++
  131. case '1' <= s[0] && s[0] <= '9':
  132. n := 1
  133. s = s[1:]
  134. for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
  135. s = s[1:]
  136. n++
  137. }
  138. size += n
  139. case s[0] == '.':
  140. // Set kind to numFloat to signify the intent to parse as float. And
  141. // that it needs to have other digits after '.'.
  142. kind = numFloat
  143. default:
  144. return number{}
  145. }
  146. // . followed by 0 or more digits.
  147. if len(s) > 0 && s[0] == '.' {
  148. n := 1
  149. s = s[1:]
  150. // If decimal point was before any digits, it should be followed by
  151. // other digits.
  152. if len(s) == 0 && kind == numFloat {
  153. return number{}
  154. }
  155. for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
  156. s = s[1:]
  157. n++
  158. }
  159. size += n
  160. kind = numFloat
  161. }
  162. // e or E followed by an optional - or + and 1 or more digits.
  163. if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
  164. kind = numFloat
  165. s = s[1:]
  166. n := 1
  167. if s[0] == '+' || s[0] == '-' {
  168. s = s[1:]
  169. n++
  170. if len(s) == 0 {
  171. return number{}
  172. }
  173. }
  174. for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
  175. s = s[1:]
  176. n++
  177. }
  178. size += n
  179. }
  180. // Optional suffix f or F for floats.
  181. if len(s) > 0 && (s[0] == 'f' || s[0] == 'F') {
  182. kind = numFloat
  183. s = s[1:]
  184. size++
  185. }
  186. // Check that next byte is a delimiter or it is at the end.
  187. if len(s) > 0 && !isDelim(s[0]) {
  188. return number{}
  189. }
  190. return number{kind: kind, neg: neg, size: size, sep: sep}
  191. }