43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/numerals/format/notations/text.rb', line 43
def disassemble(text)
text_parts = TextParts.new
s = format.symbols
special = /
\A
#{s.regexp(:plus, :minus, case_sensitivity: true)}?
\s*
#{s.regexp(:nan, :infinity, case_sensitivity: true)}
\Z
/x
if match = special.match(text)
valid = true
text_parts.special = "#{match[1]}#{match[2]}"
else
valid = true
base = format.significand_base
regular = /
\A
#{s.regexp(:plus, :minus)}?
\s*
(?:
(?:(#{s.regexp(:grouped_digits, base: base, no_capture: true)}+)#{s.regexp(:point)}?)
|
#{s.regexp(:point)} # admit empty integer part, but then a point is needed
)
(#{s.regexp(:digits, base: base, no_capture: true)}*)
(?:#{s.regexp(:repeat_begin)}(#{s.regexp(:digits, base: base, no_capture: true)}+)#{s.regexp(:repeat_end)})?
#{s.regexp(:repeat_suffix)}?
(?:#{s.regexp(:exponent)}#{s.regexp(:plus, :minus)}?(\d+))?
\Z
/x
unless s.case_sensitive?
regular = Regexp.new(regular.source, regular.options | Regexp::IGNORECASE)
end
match = regular.match(text)
if match.nil?
valid = false
else
sign = match[1]
integer_part = match[2]
point = match[3]
point_with_no_integer_part = match[4]
fractional_part = match[5]
repeat_begin = match[6]
repeat_part = match[7]
repeat_end = match[8]
repeat_suffix = match[9]
exponent = match[10]
exponent_sign = match[11]
exponent_value = match[12]
text_parts.sign = sign
text_parts.integer = integer_part
text_parts.fractional = fractional_part
if repeat_begin
if !repeat_part || !repeat_end || repeat_suffix
valid = false
end
text_parts.repeat = repeat_part
else
if repeat_part || repeat_end
valid = false
end
if repeat_suffix
text_parts.detect_repeat = true
end
end
text_parts.exponent_base = format.base
if exponent
if !exponent_value
valid = false
end
text_parts.exponent = "#{exponent_sign}#{exponent_value}"
text_parts.exponent_value = text_parts.exponent.to_i
else
if exponent_sign || exponent_value
valid = false
end
end
end
end
raise "Invalid text numeral" unless valid
text_parts
end
|