Skip to content

Commit 8930d9f

Browse files
committed
0.8.1 clean up the parser after refactoring stuff
1 parent cf7668e commit 8930d9f

File tree

1 file changed

+73
-59
lines changed

1 file changed

+73
-59
lines changed

src/parser.rs

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ use std::str;
33
use std::collections::BTreeMap;
44
use { JsonValue, JsonError, JsonResult };
55

6+
struct Position {
7+
pub line: usize,
8+
pub column: usize,
9+
}
10+
11+
struct Parser<'a> {
12+
source: &'a str,
13+
byte_ptr: *const u8,
14+
index: usize,
15+
length: usize,
16+
}
17+
618
macro_rules! next_byte {
719
($parser:ident || $alt:expr) => {
820
if $parser.index < $parser.length {
@@ -66,19 +78,16 @@ macro_rules! consume_whitespace {
6678
}
6779

6880
macro_rules! expect {
69-
($parser:ident, $byte:pat) => ({
81+
($parser:ident, $byte:expr) => ({
7082
let mut ch = next_byte!($parser);
7183

7284
consume_whitespace!($parser, ch);
7385

74-
match ch {
75-
$byte => {},
76-
_ => return $parser.unexpected_character(ch)
86+
if ch != $byte {
87+
return $parser.unexpected_character(ch)
7788
}
78-
})
79-
}
89+
});
8090

81-
macro_rules! expect_one_of {
8291
{$parser:ident $(, $byte:pat => $then:expr )*} => ({
8392
let mut ch = next_byte!($parser);
8493

@@ -115,6 +124,50 @@ macro_rules! expect_string {
115124
})
116125
}
117126

127+
macro_rules! expect_number {
128+
($parser:ident, $first:ident) => ({
129+
let mut num = ($first - b'0') as u64;
130+
let mut digits = 0u8;
131+
132+
let result: f64;
133+
134+
// Cap on how many iterations we do while reading to u64
135+
// in order to avoid an overflow.
136+
loop {
137+
if digits == 18 {
138+
result = try!($parser.read_big_number(num as f64));
139+
break;
140+
}
141+
142+
digits += 1;
143+
144+
let ch = next_byte!($parser || {
145+
result = num as f64;
146+
break;
147+
});
148+
149+
match ch {
150+
b'0' ... b'9' => {
151+
// Avoid multiplication with bitshifts and addition
152+
num = (num << 1) + (num << 3) + (ch - b'0') as u64;
153+
},
154+
b'.' | b'e' | b'E' => {
155+
$parser.index -= 1;
156+
result = try!($parser.read_number_with_fraction(num as f64));
157+
break;
158+
},
159+
_ => {
160+
$parser.index -= 1;
161+
result = num as f64;
162+
break;
163+
}
164+
}
165+
}
166+
167+
result
168+
})
169+
}
170+
118171
macro_rules! expect_value {
119172
{$parser:ident $(, $byte:pat => $then:expr )*} => ({
120173
let mut ch = next_byte!($parser);
@@ -133,14 +186,14 @@ macro_rules! expect_value {
133186
JsonValue::Number(num)
134187
},
135188
b'1' ... b'9' => {
136-
let num = try!($parser.read_number(ch));
189+
let num = expect_number!($parser, ch);
137190
JsonValue::Number(num)
138191
},
139192
b'-' => {
140193
let ch = next_byte!($parser);
141194
let num = match ch {
142195
b'0' => try!($parser.read_number_with_fraction(0.0)),
143-
b'1' ... b'9' => try!($parser.read_number(ch)),
196+
b'1' ... b'9' => expect_number!($parser, ch),
144197
_ => return $parser.unexpected_character(ch)
145198
};
146199
JsonValue::Number(-num)
@@ -162,18 +215,6 @@ macro_rules! expect_value {
162215
})
163216
}
164217

165-
struct Position {
166-
pub line: usize,
167-
pub column: usize,
168-
}
169-
170-
struct Parser<'a> {
171-
source: &'a str,
172-
byte_ptr: *const u8,
173-
index: usize,
174-
length: usize,
175-
}
176-
177218
impl<'a> Parser<'a> {
178219
pub fn new(source: &'a str) -> Self {
179220
Parser {
@@ -304,41 +345,6 @@ impl<'a> Parser<'a> {
304345
Ok(())
305346
}
306347

307-
fn read_number(&mut self, first: u8) -> JsonResult<f64> {
308-
let mut num = (first - b'0') as u64;
309-
let mut digits = 0u8;
310-
311-
// Cap on how many iterations we do while reading to u64
312-
// in order to avoid an overflow.
313-
while digits < 18 {
314-
digits += 1;
315-
316-
let ch = next_byte!(self || return Ok(num as f64));
317-
match ch {
318-
b'0' ... b'9' => {
319-
// Avoid multiplication with bitshifts and addition
320-
num = (num << 1) + (num << 3) + (ch - b'0') as u64;
321-
},
322-
b'.' | b'e' | b'E' => {
323-
self.index -= 1;
324-
break;
325-
},
326-
_ => {
327-
self.index -= 1;
328-
return Ok(num as f64);
329-
}
330-
}
331-
}
332-
333-
let mut num = num as f64;
334-
335-
// Attempt to continue reading digits that would overflow
336-
// u64 into freshly converted f64
337-
read_num!(self, digit, num = num * 10.0 + digit as f64);
338-
339-
self.read_number_with_fraction(num)
340-
}
341-
342348
fn read_complex_string(&mut self, start: usize) -> JsonResult<String> {
343349
let mut buffer = Vec::new();
344350
let mut ch = b'\\';
@@ -378,6 +384,14 @@ impl<'a> Parser<'a> {
378384
Ok(unsafe { String::from_utf8_unchecked(buffer) })
379385
}
380386

387+
fn read_big_number(&mut self, mut num: f64) -> JsonResult<f64> {
388+
// Attempt to continue reading digits that would overflow
389+
// u64 into freshly converted f64
390+
read_num!(self, digit, num = num * 10.0 + digit as f64);
391+
392+
self.read_number_with_fraction(num)
393+
}
394+
381395
fn read_number_with_fraction(&mut self, mut num: f64) -> JsonResult<f64> {
382396
if next_byte!(self || return Ok(num)) == b'.' {
383397
let mut precision = -1;
@@ -420,7 +434,7 @@ impl<'a> Parser<'a> {
420434
fn read_object(&mut self) -> JsonResult<BTreeMap<String, JsonValue>> {
421435
let mut object = BTreeMap::new();
422436

423-
let key = expect_one_of!{ self,
437+
let key = expect!{ self,
424438
b'}' => return Ok(object),
425439
b'\"' => expect_string!(self)
426440
};
@@ -430,7 +444,7 @@ impl<'a> Parser<'a> {
430444
object.insert(key, expect_value!(self));
431445

432446
loop {
433-
let key = expect_one_of!{ self,
447+
let key = expect!{ self,
434448
b'}' => break,
435449
b',' => {
436450
expect!(self, b'"');
@@ -453,7 +467,7 @@ impl<'a> Parser<'a> {
453467
array.push(first);
454468

455469
loop {
456-
expect_one_of!{ self,
470+
expect!{ self,
457471
b']' => break,
458472
b',' => {
459473
let value = expect_value!(self);

0 commit comments

Comments
 (0)