/[eiffelstudio]/FreeELKS/trunk/library/kernel/string_to_integer_convertor.e
ViewVC logotype

Contents of /FreeELKS/trunk/library/kernel/string_to_integer_convertor.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 91477 - (show annotations)
Sun Jan 14 09:47:13 2007 UTC (13 years ago) by ericb
File size: 8128 byte(s)
Synchronized with ISE 6.0.65740
1 indexing
2 description: "Convertor to do string to integer/natural conversion"
3 library: "Free implementation of ELKS library"
4 copyright: "Copyright (c) 1986-2006, Eiffel Software and others"
5 license: "Eiffel Forum License v2 (see forum.txt)"
6 date: "$Date$"
7 revision: "$Revision$"
8
9 class
10 STRING_TO_INTEGER_CONVERTOR
11
12 inherit
13 STRING_TO_NUMERIC_CONVERTOR
14
15 create
16 make
17
18 feature{NONE} -- Initialization
19
20 make is
21 -- Initialize.
22 do
23 reset (type_no_limitation)
24 set_leading_separators (" ")
25 set_trailing_separators (" ")
26 ensure
27 leading_separators_set: leading_separators.is_equal (" ")
28 trailing_separators_set: trailing_separators.is_equal (" ")
29 leading_separators_not_acceptable:
30 not leading_separators_acceptable
31 trailing_separatorsnot_acceptable:
32 not trailing_separators_acceptable
33 end
34
35 feature -- State machine setting
36
37 reset (type: INTEGER) is
38 -- Reset current convertor to parse integer of type `type'.
39 do
40 last_state := 0
41 part1 := 0
42 part2 := 0
43 sign := 0
44 conversion_type := type
45 internal_overflowed := False
46 ensure then
47 internal_overflowed_set: internal_overflowed = False
48 part1_set: part1 = 0
49 part2_set: part2 = 0
50 end
51
52 feature -- Status reporting
53
54 separators_valid (separators: STRING): BOOLEAN is
55 -- Are separators contained in `separators' valid?
56 local
57 i: INTEGER
58 l_c: INTEGER
59 c: CHARACTER
60 done: BOOLEAN
61 do
62 from
63 i := 1
64 l_c := separators.count
65 done := False
66 Result := True
67 until
68 i > l_c or done
69 loop
70 c := separators.item (i)
71 if (c >='0' and c <= '9') or c ='+' or c = '-' then
72 done := True
73 Result := False
74 end
75 i := i + 1
76 end
77 end
78
79 overflowed: BOOLEAN is
80 -- Is integer parsed so fa overflowed?
81 do
82 Result := (internal_overflowed and then sign = 0)
83 end
84
85 underflowed: BOOLEAN is
86 -- Is integer parsed so fa underflowed?
87 do
88 Result := (internal_overflowed and then sign = 1)
89 end
90
91 parse_successful: BOOLEAN is
92 -- This only means we didn't enter an invalid state when parsing,
93 -- it doesn't mean that we have got an valid integer.
94 -- You need to check `is_integral_integer' or `is_part_of_integer'.
95 do
96 Result := (last_state /=4) and (last_state /=5)
97 end
98
99
100 feature -- String parsing
101
102 parse_string_with_type (s: STRING_GENERAL; type: INTEGER) is
103 -- Parse string `s' as integer of type `type'.
104 local
105 i: INTEGER
106 l_c: INTEGER
107 do
108 reset (type)
109 from
110 i := 1
111 l_c := s.count
112 until
113 i > l_c or last_state = 4 or last_state = 5
114 loop
115 parse_character (s.code (i).to_character_8)
116 i := i + 1
117 end
118 end
119
120 parse_character (c: CHARACTER) is
121 -- Parse next character `c'.
122 local
123 temp_p1: like max_natural_type
124 temp_p2: like max_natural_type
125 do
126 -- Parse according to the following specification:
127 -- Integer/natural specification:
128 -- Integer_literal = [Space] [Sign] Integer [Space]
129 -- Space = " " | " " Space
130 -- Sign = "+" | "-"
131 -- Integer = Digit | Digit Integer
132 -- Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
133
134 -- last_state = 0 : waiting sign or first digit
135 -- last_state = 1 : sign read, waiting first digit
136 -- last_state = 2 : in the number
137 -- last_state = 3 : trailing separators
138 -- last_state = 4 : error state
139 -- last_state = 5 : overflow state
140 if last_state /= 4 and last_state /= 5 then
141 temp_p1 := (0).to_natural_64
142 temp_p2 := (0).to_natural_64
143 inspect last_state
144 when 0 then
145 -- Let's find beginning of an integer, if any.
146 if c.is_digit then
147 last_state := 2
148 part1 := 0
149 part2 := (c.code - 48).to_natural_64
150 elseif c = '-' or c = '+' then
151 last_state := 1
152 if c = '-' then
153 sign := 1
154 else
155 sign := 0
156 end
157 elseif leading_separators_acceptable and then leading_separators.has (c) then
158 else
159 last_state := 4
160 end
161 when 1 then
162 -- Let's find first digit after sign.
163 if c.is_digit then
164 part1 := 0
165 part2 := (c.code - 48).to_natural_64
166 if conversion_type /= type_no_limitation then
167 internal_overflowed := overflow_checker.will_overflow (part1, part2, conversion_type, sign)
168 if internal_overflowed then
169 part1 := temp_p1
170 part2 := temp_p2
171 last_state := 5
172 end
173 end
174 last_state := 2
175 else
176 last_state := 4
177 end
178 when 2 then
179 -- Let's find another digit or end of integer.
180 if c.is_digit then
181 temp_p1 := part1
182 temp_p2 := part2
183 part1 := part1*10 + part2
184 part2 := (c.code - 48).to_natural_64
185 if conversion_type /= type_no_limitation then
186 internal_overflowed := overflow_checker.will_overflow (part1, part2, conversion_type, sign)
187 if overflowed then
188 last_state := 5
189 part1 := temp_p1
190 part2 := temp_p2
191 end
192 end
193 elseif trailing_separators_acceptable and then trailing_separators.has (c) then
194 last_state := 3
195 else
196 last_state := 4
197 end
198 when 3 then
199 -- Consume remaining separators.
200 if trailing_separators_acceptable and then trailing_separators.has (c) then
201 else
202 last_state := 4
203 end
204 end
205 end
206 end
207
208 feature -- Status reporting
209
210 conversion_type_valid (type: INTEGER): BOOLEAN is
211 -- If conversion `type' valid?
212 do
213 Result := integer_natural_type_valid (type)
214 end
215
216 is_part_of_integer: BOOLEAN is
217 -- Is character sequence that has been parsed so far a valid start part of an integer?
218 do
219 Result := ((last_state = 0) or (last_state = 1) or
220 (last_state = 2) or (last_state = 3)) and
221 (not internal_overflowed)
222 end
223
224 is_integral_integer: BOOLEAN is
225 -- Is character sequence that has been parsed so far a valid integral integer?
226 do
227 Result := ((last_state = 2) or (last_state = 3)) and
228 (not internal_overflowed)
229 end
230
231 parsed_integer_8: INTEGER_8 is
232 -- INTEGER_8 representation of parsed string
233 local
234 l1: INTEGER_8
235 do
236
237 l1 := part1.as_integer_8
238 l1 := l1 * 10
239 if sign = 1 then
240 Result := - l1 - part2.as_integer_8
241 else
242 Result := l1 + part2.as_integer_8
243 end
244 end
245
246 parsed_integer_16: INTEGER_16 is
247 -- INTEGER_16 representation of parsed string
248 local
249 l1: INTEGER_16
250 do
251 l1 := part1.as_integer_16
252 l1 := l1 * 10
253 if sign = 1 then
254 Result := - l1 - part2.as_integer_16
255 else
256 Result := l1 + part2.as_integer_16
257 end
258 end
259
260 parsed_integer_32, parsed_integer: INTEGER is
261 -- INTEGER representation of parsed string
262 local
263 l1: INTEGER
264 do
265 l1 := part1.as_integer_32
266 l1 := l1 * 10
267 if sign = 1 then
268 Result := - l1 - part2.as_integer_32
269 else
270 Result := l1 + part2.as_integer_32
271 end
272 end
273
274 parsed_integer_64: INTEGER_64 is
275 -- INTEGER_64 representation of parsed string
276 local
277 l1: INTEGER_64
278 do
279 l1 := part1.as_integer_64
280 l1 := l1 * 10
281 if sign = 1 then
282 Result := - l1 - part2.as_integer_64
283 else
284 Result := l1 + part2.as_integer_64
285 end
286 end
287
288 parsed_natural_8: NATURAL_8 is
289 -- NATURAL_8 representation of parsed string
290 local
291 l1: NATURAL_8
292 do
293 l1 := part1.as_natural_8
294 l1 := l1 * 10
295 Result := l1 + part2.as_natural_8
296 end
297
298 parsed_natural_16: NATURAL_16 is
299 -- NATURAL_16 representation of parsed string
300 local
301 l1: NATURAL_16
302 do
303 l1 := part1.as_natural_16
304 l1 := l1 * 10
305 Result := l1 + part2.as_natural_16
306 end
307
308 parsed_natural_32, parsed_natural: NATURAL_32 is
309 -- NATURAL_32 representation of parsed string
310 local
311 l1: NATURAL_32
312 do
313 l1 := part1.as_natural_32
314 l1 := l1 * 10
315 Result := l1 + part2.as_natural_32
316 end
317
318 parsed_natural_64: NATURAL_64 is
319 -- NATURAL_64 representation of parsed string
320 local
321 l1: NATURAL_64
322 do
323 l1 := part1.as_natural_64
324 l1 := l1 * 10
325 Result := l1 + part2.as_natural_64
326 end
327
328 feature{NONE} -- Implementation
329
330 overflow_checker: INTEGER_OVERFLOW_CHECKER is
331 -- Overflow checker
332 once
333 create Result.make
334 end
335
336 part1, part2: like max_natural_type
337 -- Naturals used for conversion
338
339 internal_overflowed: BOOLEAN
340 -- Internal overflow flag
341
342 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23