Parse based on proc-macro2
diff --git a/src/lit.rs b/src/lit.rs
index 81be285..4aeec28 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -157,244 +157,159 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use escape::{cooked_byte, cooked_byte_string, cooked_char, cooked_string, raw_string};
-    use synom::space::skip_whitespace;
-    use synom::IResult;
-    use unicode_xid::UnicodeXID;
+    use synom::{IResult, TokenTree, TokenKind};
+    use relex;
 
-    named!(pub lit -> Lit, alt!(
-        string => { |StrLit { value, style }| Lit::Str(value, style) }
-        |
-        byte_string => { |ByteStrLit { value, style }| Lit::ByteStr(value, style) }
-        |
-        byte => { |b| Lit::Byte(b) }
-        |
-        character => { |ch| Lit::Char(ch) }
-        |
-        float => { |FloatLit { value, suffix }| Lit::Float(value, suffix) } // must be before int
-        |
-        int => { |IntLit { value, suffix }| Lit::Int(value, suffix) }
-        |
-        boolean => { |value| Lit::Bool(value) }
-    ));
-
-    named!(pub string -> StrLit, alt!(
-        quoted_string => { |s| StrLit { value: s, style: StrStyle::Cooked } }
-        |
-        preceded!(
-            punct!("r"),
-            raw_string
-        ) => { |(s, n)| StrLit { value: s, style: StrStyle::Raw(n) }}
-    ));
-
-    named!(pub quoted_string -> String, delimited!(
-        punct!("\""),
-        cooked_string,
-        tag!("\"")
-    ));
-
-    named!(pub byte_string -> ByteStrLit, alt!(
-        delimited!(
-            punct!("b\""),
-            cooked_byte_string,
-            tag!("\"")
-        ) => { |vec| ByteStrLit { value: vec, style: StrStyle::Cooked } }
-        |
-        preceded!(
-            punct!("br"),
-            raw_string
-        ) => { |(s, n): (String, _)| ByteStrLit { value: s.into_bytes(), style: StrStyle::Raw(n) } }
-    ));
-
-    named!(pub byte -> u8, do_parse!(
-        punct!("b") >>
-        tag!("'") >>
-        b: cooked_byte >>
-        tag!("'") >>
-        (b)
-    ));
-
-    named!(pub character -> char, do_parse!(
-        punct!("'") >>
-        ch: cooked_char >>
-        tag!("'") >>
-        (ch)
-    ));
-
-    named!(pub float -> FloatLit, do_parse!(
-        value: float_string >>
-        suffix: alt!(
-            tag!("f32") => { |_| FloatTy::F32 }
-            |
-            tag!("f64") => { |_| FloatTy::F64 }
-            |
-            epsilon!() => { |_| FloatTy::Unsuffixed }
-        ) >>
-        (FloatLit { value: value, suffix: suffix })
-    ));
-
-    named!(pub int -> IntLit, do_parse!(
-        value: digits >>
-        suffix: alt!(
-            tag!("isize") => { |_| IntTy::Isize }
-            |
-            tag!("i8") => { |_| IntTy::I8 }
-            |
-            tag!("i16") => { |_| IntTy::I16 }
-            |
-            tag!("i32") => { |_| IntTy::I32 }
-            |
-            tag!("i64") => { |_| IntTy::I64 }
-            |
-            tag!("usize") => { |_| IntTy::Usize }
-            |
-            tag!("u8") => { |_| IntTy::U8 }
-            |
-            tag!("u16") => { |_| IntTy::U16 }
-            |
-            tag!("u32") => { |_| IntTy::U32 }
-            |
-            tag!("u64") => { |_| IntTy::U64 }
-            |
-            epsilon!() => { |_| IntTy::Unsuffixed }
-        ) >>
-        (IntLit { value: value, suffix: suffix })
-    ));
-
-    named!(pub boolean -> bool, alt!(
-        keyword!("true") => { |_| true }
-        |
-        keyword!("false") => { |_| false }
-    ));
-
-    fn float_string(mut input: &str) -> IResult<&str, String> {
-        input = skip_whitespace(input);
-
-        let mut chars = input.chars().peekable();
-        match chars.next() {
-            Some(ch) if ch >= '0' && ch <= '9' => {}
-            _ => return IResult::Error,
-        }
-
-        let mut len = 1;
-        let mut has_dot = false;
-        let mut has_exp = false;
-        while let Some(&ch) = chars.peek() {
-            match ch {
-                '0'...'9' | '_' => {
-                    chars.next();
-                    len += 1;
-                }
-                '.' => {
-                    if has_dot {
-                        break;
+    pub fn lit(i: &[TokenTree]) -> IResult<&[TokenTree], Lit> {
+        match i.first() {
+            Some(&TokenTree{ kind: TokenKind::Literal(ref l), .. }) => {
+                // XXX: I'm using my lexer for this temporarially, as it makes
+                // my life easier. A final version shouldn't be this hacky,
+                // though we'll probably want `proc_macro::Literal` -> actual
+                // literal value conversions to be in a separate crate, rather
+                // than requiring syn (which seems a bit heavyweight for that).
+                let tok = if let Ok(tok) = relex::relex_literal(&l.to_string()) {
+                    tok
+                } else {
+                    return IResult::Error
+                };
+                let lit = match tok {
+                    relex::LToken::Lit(relex::Lit::Byte(b)) => {
+                        Lit::Byte(b)
                     }
-                    chars.next();
-                    if chars.peek()
-                           .map(|&ch| ch == '.' || UnicodeXID::is_xid_start(ch))
-                           .unwrap_or(false) {
-                        return IResult::Error;
+                    relex::LToken::Lit(relex::Lit::Char(c)) => {
+                        Lit::Char(c)
                     }
-                    len += 1;
-                    has_dot = true;
-                }
-                'e' | 'E' => {
-                    chars.next();
-                    len += 1;
-                    has_exp = true;
-                    break;
-                }
-                _ => break,
+                    relex::LToken::Lit(relex::Lit::Integer(v, suffix)) => {
+                        let suffix = match suffix {
+                            relex::IntSuffix::Unsuffixed =>
+                                IntTy::Unsuffixed,
+                            relex::IntSuffix::Isize =>
+                                IntTy::Isize,
+                            relex::IntSuffix::Usize =>
+                                IntTy::Usize,
+                            relex::IntSuffix::I8 =>
+                                IntTy::I8,
+                            relex::IntSuffix::U8 =>
+                                IntTy::U8,
+                            relex::IntSuffix::I16 =>
+                                IntTy::I16,
+                            relex::IntSuffix::U16 =>
+                                IntTy::U16,
+                            relex::IntSuffix::I32 =>
+                                IntTy::I32,
+                            relex::IntSuffix::U32 =>
+                                IntTy::U32,
+                            relex::IntSuffix::I64 =>
+                                IntTy::I64,
+                            relex::IntSuffix::U64 =>
+                                IntTy::U64,
+                        };
+                        Lit::Int(v, suffix)
+                    }
+                    relex::LToken::Lit(relex::Lit::Float(v, suffix)) => {
+                        let suffix = match suffix {
+                            relex::FloatSuffix::Unsuffixed =>
+                                FloatTy::Unsuffixed,
+                            relex::FloatSuffix::F32 =>
+                                FloatTy::F32,
+                            relex::FloatSuffix::F64 =>
+                                FloatTy::F64,
+                        };
+                        Lit::Float(v, suffix)
+                    }
+                    relex::LToken::Lit(relex::Lit::Str(s, relex::StrStyle::Cooked)) => {
+                        Lit::Str(s, StrStyle::Cooked)
+                    }
+                    relex::LToken::Lit(relex::Lit::Str(s, relex::StrStyle::Raw(n))) => {
+                        Lit::Str(s, StrStyle::Raw(n))
+                    }
+                    relex::LToken::Lit(relex::Lit::ByteStr(s, relex::StrStyle::Cooked)) => {
+                        Lit::ByteStr(s, StrStyle::Cooked)
+                    }
+                    relex::LToken::Lit(relex::Lit::ByteStr(s, relex::StrStyle::Raw(n))) => {
+                        Lit::ByteStr(s, StrStyle::Raw(n))
+                    }
+                    _ => return IResult::Error
+                };
+
+                IResult::Done(&i[1..], lit)
             }
-        }
-
-        let rest = &input[len..];
-        if !(has_dot || has_exp || rest.starts_with("f32") || rest.starts_with("f64")) {
-            return IResult::Error;
-        }
-
-        if has_exp {
-            let mut has_exp_value = false;
-            while let Some(&ch) = chars.peek() {
-                match ch {
-                    '+' | '-' => {
-                        if has_exp_value {
-                            break;
-                        }
-                        chars.next();
-                        len += 1;
-                    }
-                    '0'...'9' => {
-                        chars.next();
-                        len += 1;
-                        has_exp_value = true;
-                    }
-                    '_' => {
-                        chars.next();
-                        len += 1;
-                    }
-                    _ => break,
+            Some(&TokenTree{ kind: TokenKind::Word(ref w), .. }) => {
+                if &**w == "true" {
+                    IResult::Done(&i[1..], Lit::Bool(true))
+                } else if &**w == "false" {
+                    IResult::Done(&i[1..], Lit::Bool(false))
+                } else {
+                    IResult::Error
                 }
             }
-            if !has_exp_value {
-                return IResult::Error;
-            }
+            _ => IResult::Error
         }
-
-        IResult::Done(&input[len..], input[..len].replace("_", ""))
     }
 
-    pub fn digits(mut input: &str) -> IResult<&str, u64> {
-        input = skip_whitespace(input);
-
-        let base = if input.starts_with("0x") {
-            input = &input[2..];
-            16
-        } else if input.starts_with("0o") {
-            input = &input[2..];
-            8
-        } else if input.starts_with("0b") {
-            input = &input[2..];
-            2
+    #[cfg(feature = "full")]
+    pub fn digits(i: &[TokenTree]) -> IResult<&[TokenTree], u64> {
+        if let IResult::Done(r, Lit::Int(v, IntTy::Unsuffixed)) = lit(i) {
+            IResult::Done(r, v)
         } else {
-            10
-        };
-
-        let mut value = 0u64;
-        let mut len = 0;
-        let mut empty = true;
-        for b in input.bytes() {
-            let digit = match b {
-                b'0'...b'9' => (b - b'0') as u64,
-                b'a'...b'f' => 10 + (b - b'a') as u64,
-                b'A'...b'F' => 10 + (b - b'A') as u64,
-                b'_' => {
-                    if empty && base == 10 {
-                        return IResult::Error;
-                    }
-                    len += 1;
-                    continue;
-                }
-                _ => break,
-            };
-            if digit >= base {
-                return IResult::Error;
-            }
-            value = match value.checked_mul(base) {
-                Some(value) => value,
-                None => return IResult::Error,
-            };
-            value = match value.checked_add(digit) {
-                Some(value) => value,
-                None => return IResult::Error,
-            };
-            len += 1;
-            empty = false;
-        }
-        if empty {
             IResult::Error
+        }
+    }
+
+    pub fn string(i: &[TokenTree]) -> IResult<&[TokenTree], String> {
+        if let IResult::Done(r, Lit::Str(v, _)) = lit(i) {
+            IResult::Done(r, v)
         } else {
-            IResult::Done(&input[len..], value)
+            IResult::Error
+        }
+    }
+
+    pub fn byte_string(i: &[TokenTree]) -> IResult<&[TokenTree], Vec<u8>> {
+        if let IResult::Done(r, Lit::ByteStr(v, _)) = lit(i) {
+            IResult::Done(r, v)
+        } else {
+            IResult::Error
+        }
+    }
+
+    pub fn byte(i: &[TokenTree]) -> IResult<&[TokenTree], u8> {
+        if let IResult::Done(r, Lit::Byte(b)) = lit(i) {
+            IResult::Done(r, b)
+        } else {
+            IResult::Error
+        }
+    }
+
+    pub fn character(i: &[TokenTree]) -> IResult<&[TokenTree], char> {
+        if let IResult::Done(r, Lit::Char(c)) = lit(i) {
+            IResult::Done(r, c)
+        } else {
+            IResult::Error
+        }
+    }
+
+    pub fn float(i: &[TokenTree]) -> IResult<&[TokenTree], String> {
+        if let IResult::Done(r, Lit::Float(f, _)) = lit(i) {
+            IResult::Done(r, f)
+        } else {
+            IResult::Error
+        }
+    }
+
+    pub fn int(i: &[TokenTree]) -> IResult<&[TokenTree], u64> {
+        if let IResult::Done(r, Lit::Int(v, _)) = lit(i) {
+            IResult::Done(r, v)
+        } else {
+            IResult::Error
+        }
+    }
+
+    pub fn boolean(i: &[TokenTree]) -> IResult<&[TokenTree], bool> {
+        if let IResult::Done(r, Lit::Bool(b)) = lit(i) {
+            IResult::Done(r, b)
+        } else {
+            IResult::Error
         }
     }
 }