[librsvg] Add the start of a nom-based parser for floating-point numbers



commit 41b944569917d1c316bc12297a07e18ac3b29ee0
Author: Sebastian Dröge <sebastian centricular com>
Date:   Tue Feb 21 10:05:57 2017 -0600

    Add the start of a nom-based parser for floating-point numbers

 rust/Cargo.lock     |    7 +++++
 rust/Cargo.toml     |    3 ++
 rust/src/lib.rs     |    4 +++
 rust/src/parsers.rs |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 0 deletions(-)
---
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index c0be97b..c078c49 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -7,6 +7,7 @@ dependencies = [
  "cairo-sys-rs 0.3.2 (git+https://github.com/federicomenaquintero/cairo.git)",
  "glib 0.1.1 (git+https://github.com/gtk-rs/glib)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 2.1.0 (git+https://github.com/Geal/nom)",
 ]
 
 [[package]]
@@ -89,6 +90,11 @@ version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 
 [[package]]
+name = "nom"
+version = "2.1.0"
+source = "git+https://github.com/Geal/nom#fd9674c7207c8c14548c3f99a05c6c2d15c5ce26";
+
+[[package]]
 name = "pkg-config"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -109,5 +115,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum glib-sys 0.3.2 (git+https://github.com/gtk-rs/sys)" = "<none>"
 "checksum gobject-sys 0.3.2 (git+https://github.com/gtk-rs/sys)" = "<none>"
 "checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = 
"684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
+"checksum nom 2.1.0 (git+https://github.com/Geal/nom)" = "<none>"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = 
"167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 4dc2d97..b96621d 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -23,6 +23,9 @@ git = "https://github.com/federicomenaquintero/cairo.git";
 git = "https://github.com/gtk-rs/glib";
 version = "0.1.1"
 
+[dependencies.nom]
+git = "https://github.com/Geal/nom";
+
 [lib]
 name = "rsvg_internals"
 crate-type = ["staticlib"]
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 02116bf..487a481 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,6 +1,9 @@
 #[macro_use]
 extern crate bitflags;
 
+#[macro_use]
+extern crate nom;
+
 pub use aspect_ratio::{
     FitMode,
     AlignMode,
@@ -99,6 +102,7 @@ mod gradient;
 mod length;
 mod marker;
 mod node;
+mod parsers;
 mod path_builder;
 mod path_parser;
 mod pattern;
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
new file mode 100644
index 0000000..053e185
--- /dev/null
+++ b/rust/src/parsers.rs
@@ -0,0 +1,70 @@
+use nom::{IResult, is_digit};
+use std::str;
+
+#[derive(Debug, PartialEq, Eq)]
+pub enum Sign {
+    Plus,
+    Minus,
+}
+
+named! (pub sign<Sign>,
+        map! (alt! (tag! (b"+") | tag! (b"-")),
+              |x| if x == b"+" { Sign::Plus } else { Sign::Minus }
+        )
+);
+
+type DigitSequence<'a> = &'a[u8];
+named! (pub digit_sequence<DigitSequence>, take_while1! (is_digit));
+
+type Exponent<'a> = (Sign, &'a[u8]);
+named! (pub exponent<Exponent>,
+        do_parse! (alt! (tag! (b"e") | tag! (b"E")) >>
+                   s: opt! (sign)                   >>
+                   d: digit_sequence                >>
+                   (s.unwrap_or (Sign::Plus), d)
+        )
+);
+
+type FractionalConstant<'a> = (Option<&'a[u8]>, Option<&'a[u8]>);
+named! (pub fractional_constant<FractionalConstant>,
+        alt! (do_parse! (i: opt! (digit_sequence) >>
+                         tag! (b".")              >>
+                         f: digit_sequence        >>
+                         (i, Some (f)))           |
+
+              do_parse! (i: digit_sequence        >>
+                         tag! (b".")              >>
+                         (Some(i), None)))
+);
+
+type FloatingPointConstant<'a> = (FractionalConstant<'a>, Option<Exponent<'a>>);
+named! (pub floating_point_constant<FloatingPointConstant>,
+        alt! (do_parse! (f: fractional_constant        >>
+                         e: opt! (exponent)            >>
+                         (f, e))                       |
+
+              do_parse! (d: digit_sequence             >>
+                         e: exponent                   >>
+                         ((Some (d), None), Some (e))))
+);
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn it_works () {
+        assert_eq! (sign (b"+"), IResult::Done (&b""[..], Sign::Plus));
+        assert_eq! (sign (b"-"), IResult::Done (&b""[..], Sign::Minus));
+        assert_eq! (digit_sequence (b"123456"), IResult::Done (&b""[..], &b"123456"[..]));
+        assert_eq! (digit_sequence (b"123456b"), IResult::Done (&b"b"[..], &b"123456"[..]));
+        assert_eq! (digit_sequence (b"1234b56"), IResult::Done (&b"b56"[..], &b"1234"[..]));
+        assert_eq! (exponent (b"e123"), IResult::Done (&b""[..], (Sign::Plus, &b"123"[..])));
+        assert_eq! (exponent (b"e+123"), IResult::Done (&b""[..], (Sign::Plus, &b"123"[..])));
+        assert_eq! (exponent (b"e-123"), IResult::Done (&b""[..], (Sign::Minus, &b"123"[..])));
+        assert_eq! (fractional_constant (b"1.23"), IResult::Done (&b""[..], (Some (&b"1"[..]), Some 
(&b"23"[..]))));
+        assert_eq! (fractional_constant (b"1."), IResult::Done (&b""[..], (Some (&b"1"[..]), None)));
+        assert_eq! (fractional_constant (b".23"), IResult::Done (&b""[..], (None, Some (&b"23"[..]))));
+
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]