[librsvg] parsers::list_of_points() - Implement with cssparser instead of nom
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] parsers::list_of_points() - Implement with cssparser instead of nom
- Date: Mon, 31 Jul 2017 15:27:07 +0000 (UTC)
commit 7fecfb8644276900fc536823701e489a88662b3a
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Jul 20 20:39:16 2017 -0500
parsers::list_of_points() - Implement with cssparser instead of nom
rust/src/parsers.rs | 163 ++++++++-------------------------------------------
1 files changed, 25 insertions(+), 138 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index ac2d8be..5481fd1 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -2,7 +2,6 @@ use ::libc;
use ::cssparser::{Parser, Token, BasicParseError, NumericValue};
use ::glib::translate::*;
use ::glib_sys;
-use ::nom::{IResult, double};
use std::f64::consts::*;
use std::mem;
@@ -10,9 +9,6 @@ use std::ptr;
use std::slice;
use std::str;
-// I don't know how to copy a nom::IError for long-term storage
-// (i.e. when it can no longer reference the &[u8]). So, we explode a
-// nom::IError into a simple error struct that can be passed around.
#[derive(Debug, Clone, PartialEq)]
pub struct ParseError {
pub display: String
@@ -30,39 +26,6 @@ impl<'a> From<BasicParseError<'a>> for ParseError {
}
}
-/*
-impl<'a> From<IError<&'a [u8]>> for NomError {
- fn from (e: IError<&[u8]>) -> NomError {
- match e {
- IError::Error (err) => NomError { display: format! ("{}", err) },
-
- IError::Incomplete (_) => NomError { display: "incomplete data".to_string () }
- }
- }
-}
-*/
-
-fn is_whitespace (c: u8) -> bool {
- match c as char {
- ' ' | '\t' | '\r' | '\n' => true,
- _ => false
- }
-}
-
-// comma-wsp:
-// (wsp+ comma? wsp*) | (comma wsp*)
-
-named! (comma, complete! (tag! (",")));
-named! (wsp, recognize! (take_while1! (is_whitespace)));
-named! (wsp_opt, recognize! (take_while! (is_whitespace)));
-
-named! (comma_wsp,
- alt! (recognize! (tuple! (comma,
- wsp_opt))
- | recognize! (tuple! (wsp,
- opt! (comma),
- wsp_opt))));
-
// angle:
// https://www.w3.org/TR/SVG/types.html#DataTypeAngle
//
@@ -101,15 +64,6 @@ fn optional_comma (parser: &mut Parser) {
let _ = parser.try (|p| p.expect_comma ());
}
-// Coordinate pairs, separated by optional (whitespace-and/or comma)
-//
-// All of these yield (1, -2): "1 -2", "1, -2", "1-2"
-
-named! (coordinate_pair<(f64, f64)>,
- do_parse! (x: double >>
- opt! (comma_wsp) >>
- y: double >>
- (x, y)));
// number-optional-number
//
@@ -171,23 +125,32 @@ pub extern fn rsvg_css_parse_number_optional_number (s: *const libc::c_char,
// Parse a list-of-points as for polyline and polygon elements
// https://www.w3.org/TR/SVG/shapes.html#PointsBNF
-named! (list_of_points_impl<Vec<(f64, f64)>>,
- terminated! (separated_list! (comma_wsp, coordinate_pair),
- eof! ()));
-
pub fn list_of_points (string: &str) -> Result <Vec<(f64, f64)>, ParseError> {
- list_of_points_impl (string.as_bytes ())
- .to_full_result ()
- .map_err (|_| ParseError::new ("invalid syntax for list of points"))
- /*
- .map_err (|e| match e { IError::Error (err) => ParseError::new (format! ("{}", err)),
- _ => ParseError::new ("incomplete list of points")
- })
- */
-}
+ let mut parser = Parser::new (string);
+
+ let mut v = Vec::new ();
+
+ loop {
+ let x = parser.expect_number ()? as f64;
+
+ optional_comma (&mut parser);
+
+ let y = parser.expect_number ()? as f64;
-named! (pub separated_numbers<Vec<f64>>,
- separated_list! (comma_wsp, double));
+ v.push ((x, y));
+
+ if parser.is_exhausted () {
+ break;
+ }
+
+ match parser.next_including_whitespace () {
+ Ok (Token::WhiteSpace(_)) => (),
+ _ => optional_comma (&mut parser)
+ }
+ }
+
+ Ok (v)
+}
// Lists of number values
@@ -296,59 +259,6 @@ mod tests {
use super::*;
#[test]
- fn parses_coordinate_pairs () {
- assert_eq! (coordinate_pair (b"1 2"), IResult::Done (&b""[..], (1.0, 2.0)));
- assert_eq! (coordinate_pair (b"1-2"), IResult::Done (&b""[..], (1.0, -2.0)));
- assert_eq! (coordinate_pair (b"1,2"), IResult::Done (&b""[..], (1.0, 2.0)));
- assert_eq! (coordinate_pair (b"1, 2"), IResult::Done (&b""[..], (1.0, 2.0)));
- assert_eq! (coordinate_pair (b"1 ,2"), IResult::Done (&b""[..], (1.0, 2.0)));
- assert_eq! (coordinate_pair (b"1 , 2"), IResult::Done (&b""[..], (1.0, 2.0)));
- assert_eq! (coordinate_pair (b"1 -2"), IResult::Done (&b""[..], (1.0, -2.0)));
- assert_eq! (coordinate_pair (b"1,-2"), IResult::Done (&b""[..], (1.0, -2.0)));
- assert_eq! (coordinate_pair (b"1, -2"), IResult::Done (&b""[..], (1.0, -2.0)));
- assert_eq! (coordinate_pair (b"1 , -2"), IResult::Done (&b""[..], (1.0, -2.0)));
- }
-
- #[test]
- fn detects_incomplete_coordinate_pair () {
- let result = coordinate_pair (b"1");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
-
- let result = coordinate_pair (b"1,");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
-
- let result = coordinate_pair (b"1, ");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
-
- let result = coordinate_pair (b"1-");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
-
- let result = coordinate_pair (b"1,-");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
-
- let result = coordinate_pair (b"-1 -");
- match result {
- IResult::Incomplete (_) => { },
- _ => { panic! ("{:?} should be an incomplete coordinate-pair", result); }
- }
- }
-
- #[test]
fn parses_number_optional_number () {
assert_eq! (number_optional_number ("1, 2"), Ok ((1.0, 2.0)));
assert_eq! (number_optional_number ("1 2"), Ok ((1.0, 2.0)));
@@ -371,31 +281,8 @@ mod tests {
}
#[test]
- fn parses_comma_wsp () {
- assert_eq! (comma_wsp (b" , "), IResult::Done (&b""[..], &b" , "[..]));
- assert_eq! (comma_wsp (b","), IResult::Done (&b""[..], &b","[..]));
- assert_eq! (comma_wsp (b" "), IResult::Done (&b""[..], &b" "[..]));
- assert_eq! (comma_wsp (b", "), IResult::Done (&b""[..], &b", "[..]));
- assert_eq! (comma_wsp (b" ,"), IResult::Done (&b""[..], &b" ,"[..]));
- }
-
- #[test]
- fn parses_separated_numbers () {
- assert_eq! (separated_numbers (b"1 2 3 4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0, 4.0]));
- assert_eq! (separated_numbers (b"1,2,3,4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0, 4.0]));
- assert_eq! (separated_numbers (b"1 ,2 ,3 ,4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0, 4.0]));
- assert_eq! (separated_numbers (b"1 ,2 ,3 ,4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0,
4.0]));
- assert_eq! (separated_numbers (b"1, 2, 3, 4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0, 4.0]));
- assert_eq! (separated_numbers (b"1, 2, 3, 4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0,
4.0]));
- assert_eq! (separated_numbers (b"1 , 2 , 3 , 4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0,
4.0]));
- assert_eq! (separated_numbers (b"1 , 2 , 3 , 4"), IResult::Done (&b""[..], vec! [1.0, 2.0, 3.0,
4.0]));
- assert_eq! (separated_numbers (b"1 , 2 , 3 , 4"), IResult::Done (&b""[..], vec! [1.0, 2.0,
3.0, 4.0]));
- }
-
- #[test]
fn parses_list_of_points () {
- // FIXME: we are missing optional whitespace at the beginning and end of the list
- assert_eq! (list_of_points ("1 2"), Ok (vec! [(1.0, 2.0)]));
+ assert_eq! (list_of_points (" 1 2 "), Ok (vec! [(1.0, 2.0)]));
assert_eq! (list_of_points ("1 2 3 4"), Ok (vec! [(1.0, 2.0), (3.0, 4.0)]));
assert_eq! (list_of_points ("1,2,3,4"), Ok (vec! [(1.0, 2.0), (3.0, 4.0)]));
assert_eq! (list_of_points ("1,2 3,4"), Ok (vec! [(1.0, 2.0), (3.0, 4.0)]));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]