Check for word boundary after numeric suffixes
diff --git a/src/stable.rs b/src/stable.rs
index 02cd626..297177a 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -11,7 +11,7 @@
use proc_macro;
use unicode_xid::UnicodeXID;
-use strnom::{PResult, skip_whitespace, block_comment, whitespace};
+use strnom::{PResult, skip_whitespace, block_comment, whitespace, word_break};
use {TokenTree, TokenKind, Delimiter, OpKind};
@@ -721,19 +721,17 @@
true
}
-named!(float -> (), do_parse!(
- float_string >>
- alt!(
- tag!("f32") => { |_| () }
- |
- tag!("f64") => { |_| () }
- |
- epsilon!()
- ) >>
- (())
-));
+fn float(input: &str) -> PResult<()> {
+ let (rest, ()) = float_digits(input)?;
+ for suffix in &["f32", "f64"] {
+ if rest.starts_with(suffix) {
+ return word_break(&rest[suffix.len()..]);
+ }
+ }
+ word_break(rest)
+}
-fn float_string(input: &str) -> PResult<()> {
+fn float_digits(input: &str) -> PResult<()> {
let mut chars = input.chars().peekable();
match chars.next() {
Some(ch) if ch >= '0' && ch <= '9' => {}
@@ -808,37 +806,28 @@
Ok((&input[len..], ()))
}
-named!(int -> (), do_parse!(
- digits >>
- alt!(
- tag!("isize") => { |_| () }
- |
- tag!("i8") => { |_| () }
- |
- tag!("i16") => { |_| () }
- |
- tag!("i32") => { |_| () }
- |
- tag!("i64") => { |_| () }
- |
- tag!("i128") => { |_| () }
- |
- tag!("usize") => { |_| () }
- |
- tag!("u8") => { |_| () }
- |
- tag!("u16") => { |_| () }
- |
- tag!("u32") => { |_| () }
- |
- tag!("u64") => { |_| () }
- |
- tag!("u128") => { |_| () }
- |
- epsilon!()
- ) >>
- (())
-));
+fn int(input: &str) -> PResult<()> {
+ let (rest, ()) = digits(input)?;
+ for suffix in &[
+ "isize",
+ "i8",
+ "i16",
+ "i32",
+ "i64",
+ "i128",
+ "usize",
+ "u8",
+ "u16",
+ "u32",
+ "u64",
+ "u128",
+ ] {
+ if rest.starts_with(suffix) {
+ return word_break(&rest[suffix.len()..]);
+ }
+ }
+ word_break(rest)
+}
fn digits(mut input: &str) -> PResult<()> {
let base = if input.starts_with("0x") {
@@ -996,4 +985,16 @@
0xffffffffffffffffffffffffffffffff
");
}
+
+ #[test]
+ fn fail() {
+ fn fail(p: &str) {
+ if p.parse::<TokenStream>().is_ok() {
+ panic!("should have failed to parse: {}", p);
+ }
+ }
+ fail("1x");
+ fail("1u80");
+ fail("1f320");
+ }
}
diff --git a/src/strnom.rs b/src/strnom.rs
index 875c4bf..22b39e8 100644
--- a/src/strnom.rs
+++ b/src/strnom.rs
@@ -90,7 +90,7 @@
ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}'
}
-fn word_break(input: &str) -> PResult<()> {
+pub fn word_break(input: &str) -> PResult<()> {
match input.chars().next() {
Some(ch) if UnicodeXID::is_xid_continue(ch) => Err(LexError),
Some(_) | None => Ok((input, ())),
@@ -336,12 +336,6 @@
}
}
-macro_rules! epsilon {
- ($i:expr,) => {
- Ok(($i, ()))
- };
-}
-
macro_rules! preceded {
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => {
match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {