Skip to content

Commit

Permalink
Better support scientific notation in the path parser
Browse files Browse the repository at this point in the history
It was able to parse 1e-2 but failed to parse 1.5e-2
  • Loading branch information
nical committed Apr 20, 2024
1 parent 7ec91d2 commit 04be6d6
Showing 1 changed file with 56 additions and 87 deletions.
143 changes: 56 additions & 87 deletions crates/extra/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,16 @@ impl PathParser {
src.advance_one();
}

if src.current == '.' {
self.float_buffer.push('.');
src.advance_one();

while src.current.is_numeric() {
self.float_buffer.push(src.current);
src.advance_one();
}
}

if src.current == 'e' || src.current == 'E' {
self.float_buffer.push(src.current);
src.advance_one();
Expand All @@ -443,16 +453,6 @@ impl PathParser {
}
}

if src.current == '.' {
self.float_buffer.push('.');
src.advance_one();
}

while src.current.is_numeric() {
self.float_buffer.push(src.current);
src.advance_one();
}

match self.float_buffer.parse::<f32>() {
Ok(val) => Ok(val),
Err(_) => Err(ParseError::Number {
Expand Down Expand Up @@ -487,7 +487,7 @@ impl PathParser {
}

#[cfg(test)]
use crate::path::{path::BuilderWithAttributes, Path};
use crate::path::Path;

#[test]
fn empty() {
Expand Down Expand Up @@ -643,60 +643,28 @@ fn bad_numbers() {
};
let mut parser = PathParser::new();

fn bad_number(r: Result<(), ParseError>) -> bool {
let bad_number = &mut|src: &str| {
let r = parser.parse(
&options,
&mut Source::new(src.chars()),
&mut Path::builder_with_attributes(0)
);
match r {
Err(ParseError::Number { .. }) => true,
_ => {
println!("{r:?}");
false
}
}
}

fn builder(num_attributes: usize) -> BuilderWithAttributes {
Path::builder_with_attributes(num_attributes)
}
};

assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 a".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 --1".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 1ee2".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 1e--1".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 *2".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 e".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 1e".chars()),
&mut builder(0)
)));
assert!(bad_number(parser.parse(
&options,
&mut Source::new("M 0 +1".chars()),
&mut builder(0)
)));
assert!(bad_number("M 0 --1"));
assert!(bad_number("M 0 1ee2"));
assert!(bad_number("M 0 1e--1"));
assert!(bad_number("M 0 *2"));
assert!(bad_number("M 0 e"));
assert!(bad_number("M 0 1e"));
assert!(bad_number("M 0 +1"));
}

#[test]
Expand All @@ -708,38 +676,18 @@ fn stop() {
};
let mut parser = PathParser::new();

fn builder(num_attributes: usize) -> BuilderWithAttributes {
Path::builder_with_attributes(num_attributes)
}

parser
.parse(
&options,
&mut Source::new("M 0 0 | xxxxxx".chars()),
&mut builder(0),
)
.unwrap();
parser
.parse(
&options,
&mut Source::new("M 0 0| xxxxxx".chars()),
&mut builder(0),
)
.unwrap();
parser
.parse(
&options,
&mut Source::new("| xxxxxx".chars()),
&mut builder(0),
)
.unwrap();
parser
.parse(
let parse = &mut |src: &str| {
parser.parse(
&options,
&mut Source::new(" | xxxxxx".chars()),
&mut builder(0),
&mut Source::new(src.chars()),
&mut Path::builder_with_attributes(0),
)
.unwrap();
};

parse("M 0 0 | xxxxxx").unwrap();
parse("M 0 0| xxxxxx").unwrap();
parse("| xxxxxx").unwrap();
parse(" | xxxxxx").unwrap();
}

#[test]
Expand Down Expand Up @@ -784,3 +732,24 @@ fn need_start() {
}
}
}

#[test]
fn issue_895() {
let options = ParserOptions::DEFAULT;
let mut parser = PathParser::new();

let parse = &mut |src: &str| {
parser.parse(
&options,
&mut Source::new(src.chars()),
&mut Path::builder_with_attributes(0),
)
};

parse("M 1e-9 0").unwrap();
parse("M -1e-9 0").unwrap();
parse("M -1e11 0").unwrap();
parse("M 1.e-9 1.4e-4z").unwrap();
parse("M 1.6e-9 1.4e-4 z").unwrap();
parse("M0 1.6e-9L0 1.4e-4").unwrap();
}

0 comments on commit 04be6d6

Please sign in to comment.