Macro parsing
diff --git a/src/attr.rs b/src/attr.rs
index 1f16ab3..fa021d7 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -165,7 +165,7 @@
         |
         do_parse!(
             option!(whitespace) >>
-            peek!(tag!("/**")) >>
+            peek!(tuple!(tag!("/**"), not!(tag!("*")))) >>
             com: block_comment >>
             (Attribute {
                 style: AttrStyle::Outer,
diff --git a/src/expr.rs b/src/expr.rs
index 2865c2c..e3e4e55 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -346,6 +346,7 @@
     use ident::parsing::ident;
     use item::parsing::item;
     use lit::parsing::lit;
+    use mac::parsing::mac;
     use nom::IResult::Error;
     use ty::parsing::{mutability, path, qpath, ty};
 
@@ -388,7 +389,8 @@
             expr_continue
             |
             expr_ret
-            // TODO: Mac
+            |
+            expr_mac
             |
             expr_repeat
         ) >>
@@ -429,6 +431,8 @@
         (e)
     ));
 
+    named!(expr_mac -> Expr, map!(mac, Expr::Mac));
+
     named!(expr_paren -> Expr, do_parse!(
         punct!("(") >>
         e: expr >>
@@ -876,9 +880,12 @@
         // TODO: Lit
         // TODO: Range
         // TODO: Vec
-        // TODO: Mac
+        |
+        pat_mac
     ));
 
+    named!(pat_mac -> Pat, map!(mac, Pat::Mac));
+
     named!(pat_wild -> Pat, map!(keyword!("_"), |_| Pat::Wild));
 
     named!(pat_ident -> Pat, do_parse!(
diff --git a/src/item.rs b/src/item.rs
index 874455f..1c0ec66 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -227,13 +227,14 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use {FunctionRetTy, Generics};
+    use {FunctionRetTy, Generics, Ident, Mac, TokenTree, Visibility};
     use attr::parsing::outer_attr;
     use data::parsing::visibility;
     use expr::parsing::{block, expr, pat};
     use generics::parsing::{generics, where_clause};
     use ident::parsing::ident;
     use lit::parsing::quoted_string;
+    use mac::parsing::delimited;
     use macro_input::{Body, MacroInput};
     use macro_input::parsing::macro_input;
     use ty::parsing::{mutability, ty};
@@ -257,7 +258,25 @@
         // TODO: Trait
         // TODO: DefaultImpl
         // TODO: Impl
-        // TODO: Mac
+        |
+        item_mac
+    ));
+
+    named!(item_mac -> Item, do_parse!(
+        attrs: many0!(outer_attr) >>
+        path: ident >>
+        punct!("!") >>
+        name: option!(ident) >>
+        body: delimited >>
+        (Item {
+            ident: name.unwrap_or_else(|| Ident::new("")),
+            vis: Visibility::Inherited,
+            attrs: attrs,
+            node: ItemKind::Mac(Mac {
+                path: path.into(),
+                tts: vec![TokenTree::Delimited(body)],
+            }),
+        })
     ));
 
     named!(item_extern_crate -> Item, do_parse!(
diff --git a/src/lib.rs b/src/lib.rs
index efde6ba..7173b6f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -119,7 +119,6 @@
     DelimToken,
     Delimited,
     Mac,
-    SequenceRepetition,
     Token,
     TokenTree,
 };
diff --git a/src/mac.rs b/src/mac.rs
index f227a25..b3fed3a 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -30,10 +30,6 @@
     Token(Token),
     /// A delimited sequence of token trees
     Delimited(Delimited),
-
-    // This only makes sense in MBE macros.
-    /// A kleene-style repetition sequence with a span
-    Sequence(SequenceRepetition),
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
@@ -45,26 +41,6 @@
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
-pub struct SequenceRepetition {
-    /// The sequence of token trees
-    pub tts: Vec<TokenTree>,
-    /// The optional separator
-    pub separator: Option<Token>,
-    /// Whether the sequence can be repeated zero (*), or one or more times (+)
-    pub op: KleeneOp,
-    /// The number of `MatchNt`s that appear in the sequence (and subsequences)
-    pub num_captures: usize,
-}
-
-/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
-/// for token sequences.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum KleeneOp {
-    ZeroOrMore,
-    OneOrMore,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Token {
     /* Expression-operator symbols. */
     Eq,
@@ -96,28 +72,16 @@
     Pound,
     Dollar,
     Question,
-    /// An opening delimiter, eg. `{`
-    OpenDelim(DelimToken),
-    /// A closing delimiter, eg. `}`
-    CloseDelim(DelimToken),
 
     /* Literals */
-    Literal(Lit, Option<String>),
+    Literal(Lit),
 
     /* Name components */
     Ident(Ident),
     Underscore,
     Lifetime(Ident),
 
-    // Can be expanded into several tokens.
-    /// Doc comment
     DocComment(String),
-    // In left-hand-sides of MBE macros:
-    /// Parse a nonterminal (name to bind, name of NT)
-    MatchNt(Ident, Ident),
-    // In right-hand-sides of MBE macros:
-    /// A syntactic variable that will be filled in by macro expansion.
-    SubstNt(Ident),
 }
 
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -143,6 +107,189 @@
     Bracket,
     /// A curly brace: `{` or `}`
     Brace,
-    /// An empty delimiter
-    NoDelim,
+}
+
+#[cfg(feature = "parsing")]
+pub mod parsing {
+    use super::*;
+    use Lifetime;
+    use generics::parsing::lifetime;
+    use ident::parsing::ident;
+    use lit::parsing::lit;
+    use space::{block_comment, whitespace};
+
+    named!(pub mac -> Mac, do_parse!(
+        name: ident >>
+        punct!("!") >>
+        body: delimited >>
+        (Mac {
+            path: name.into(),
+            tts: vec![TokenTree::Delimited(body)],
+        })
+    ));
+
+    named!(pub delimited -> Delimited, alt!(
+        delimited!(
+            punct!("("),
+            many0!(token_tree),
+            punct!(")")
+        ) => { |tts| Delimited { delim: DelimToken::Paren, tts: tts } }
+        |
+        delimited!(
+            punct!("["),
+            many0!(token_tree),
+            punct!("]")
+        ) => { |tts| Delimited { delim: DelimToken::Bracket, tts: tts } }
+        |
+        delimited!(
+            punct!("{"),
+            many0!(token_tree),
+            punct!("}")
+        ) => { |tts| Delimited { delim: DelimToken::Brace, tts: tts } }
+    ));
+
+    named!(token_tree -> TokenTree, alt!(
+        map!(token, TokenTree::Token)
+        |
+        map!(delimited, TokenTree::Delimited)
+    ));
+
+    named!(token -> Token, alt!(
+        map!(bin_op_eq, Token::BinOpEq)
+        |
+        map!(bin_op, Token::BinOp)
+        |
+        punct!("=") => { |_| Token::Eq }
+        |
+        punct!("<") => { |_| Token::Lt }
+        |
+        punct!("<=") => { |_| Token::Le }
+        |
+        punct!("==") => { |_| Token::EqEq }
+        |
+        punct!("!=") => { |_| Token::Ne }
+        |
+        punct!(">=") => { |_| Token::Ge }
+        |
+        punct!(">") => { |_| Token::Gt }
+        |
+        punct!("&&") => { |_| Token::AndAnd }
+        |
+        punct!("||") => { |_| Token::OrOr }
+        |
+        punct!("!") => { |_| Token::Not }
+        |
+        punct!("~") => { |_| Token::Tilde }
+        |
+        punct!("@") => { |_| Token::At }
+        |
+        punct!(".") => { |_| Token::Dot }
+        |
+        punct!("..") => { |_| Token::DotDot }
+        |
+        punct!("...") => { |_| Token::DotDotDot }
+        |
+        punct!(",") => { |_| Token::Comma }
+        |
+        punct!(";") => { |_| Token::Semi }
+        |
+        punct!(":") => { |_| Token::Colon }
+        |
+        punct!("::") => { |_| Token::ModSep }
+        |
+        punct!("->") => { |_| Token::RArrow }
+        |
+        punct!("<-") => { |_| Token::LArrow }
+        |
+        punct!("=>") => { |_| Token::FatArrow }
+        |
+        punct!("#") => { |_| Token::Pound }
+        |
+        punct!("$") => { |_| Token::Dollar }
+        |
+        punct!("?") => { |_| Token::Question }
+        |
+        punct!("_") => { |_| Token::Underscore }
+        |
+        map!(lit, Token::Literal)
+        |
+        map!(ident, Token::Ident)
+        |
+        map!(lifetime, |lt: Lifetime| Token::Lifetime(lt.ident))
+        |
+        map!(doc_comment, Token::DocComment)
+    ));
+
+    named!(bin_op -> BinOpToken, alt!(
+        punct!("+") => { |_| BinOpToken::Plus }
+        |
+        punct!("-") => { |_| BinOpToken::Minus }
+        |
+        punct!("*") => { |_| BinOpToken::Star }
+        |
+        punct!("/") => { |_| BinOpToken::Slash }
+        |
+        punct!("%") => { |_| BinOpToken::Percent }
+        |
+        punct!("^") => { |_| BinOpToken::Caret }
+        |
+        punct!("&") => { |_| BinOpToken::And }
+        |
+        punct!("|") => { |_| BinOpToken::Or }
+        |
+        punct!("<<") => { |_| BinOpToken::Shl }
+        |
+        punct!(">>") => { |_| BinOpToken::Shr }
+    ));
+
+    named!(bin_op_eq -> BinOpToken, alt!(
+        punct!("+=") => { |_| BinOpToken::Plus }
+        |
+        punct!("-=") => { |_| BinOpToken::Minus }
+        |
+        punct!("*=") => { |_| BinOpToken::Star }
+        |
+        punct!("/=") => { |_| BinOpToken::Slash }
+        |
+        punct!("%=") => { |_| BinOpToken::Percent }
+        |
+        punct!("^=") => { |_| BinOpToken::Caret }
+        |
+        punct!("&=") => { |_| BinOpToken::And }
+        |
+        punct!("|=") => { |_| BinOpToken::Or }
+        |
+        punct!("<<=") => { |_| BinOpToken::Shl }
+        |
+        punct!(">>=") => { |_| BinOpToken::Shr }
+    ));
+
+    named!(doc_comment -> String, alt!(
+        do_parse!(
+            punct!("//!") >>
+            content: take_until!("\n") >>
+            (format!("//!{}", content))
+        )
+        |
+        do_parse!(
+            option!(whitespace) >>
+            peek!(tag!("/*!")) >>
+            com: block_comment >>
+            (com.to_owned())
+        )
+        |
+        do_parse!(
+            punct!("///") >>
+            not!(peek!(tag!("/"))) >>
+            content: take_until!("\n") >>
+            (format!("///{}", content))
+        )
+        |
+        do_parse!(
+            option!(whitespace) >>
+            peek!(tuple!(tag!("/**"), not!(tag!("*")))) >>
+            com: block_comment >>
+            (com.to_owned())
+        )
+    ));
 }
diff --git a/src/ty.rs b/src/ty.rs
index 7cba5f9..1c4917b 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -59,6 +59,15 @@
     pub segments: Vec<PathSegment>,
 }
 
+impl<T> From<T> for Path where T: Into<PathSegment> {
+    fn from(segment: T) -> Self {
+        Path {
+            global: false,
+            segments: vec![segment.into()],
+        }
+    }
+}
+
 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
 ///
 /// E.g. `std`, `String` or `Box<T>`
@@ -68,10 +77,10 @@
     pub parameters: PathParameters,
 }
 
-impl PathSegment {
-    pub fn ident(ident: Ident) -> Self {
+impl<T> From<T> for PathSegment where T: Into<Ident> {
+    fn from(ident: T) -> Self {
         PathSegment {
-            ident: ident,
+            ident: ident.into(),
             parameters: PathParameters::none(),
         }
     }
@@ -373,7 +382,7 @@
             })
         )
         |
-        map!(ident, PathSegment::ident)
+        map!(ident, Into::into)
     ));
 
     named!(type_binding -> TypeBinding, do_parse!(
diff --git a/tests/test_macro_input.rs b/tests/test_macro_input.rs
index 0334157..c00ba4d 100644
--- a/tests/test_macro_input.rs
+++ b/tests/test_macro_input.rs
@@ -1,13 +1,6 @@
 extern crate syn;
 use syn::*;
 
-fn simple_ty(ident: &str) -> Ty {
-    Ty::Path(None, Path {
-        global: false,
-        segments: vec![PathSegment::ident(ident.into())],
-    })
-}
-
 #[test]
 fn test_unit() {
     let raw = "struct Unit;";
@@ -52,7 +45,7 @@
                 ident: Some("ident".into()),
                 vis: Visibility::Public,
                 attrs: Vec::new(),
-                ty: simple_ty("Ident"),
+                ty: Ty::Path(None, "Ident".into()),
             },
             Field {
                 ident: Some("attrs".into()),
@@ -66,7 +59,7 @@
                             parameters: PathParameters::AngleBracketed(
                                 AngleBracketedParameterData {
                                     lifetimes: Vec::new(),
-                                    types: vec![simple_ty("Attribute")],
+                                    types: vec![Ty::Path(None, "Attribute".into())],
                                     bindings: Vec::new(),
                                 },
                             ),
@@ -140,7 +133,7 @@
                         ident: None,
                         vis: Visibility::Inherited,
                         attrs: Vec::new(),
-                        ty: simple_ty("T"),
+                        ty: Ty::Path(None, "T".into()),
                     },
                 ]),
                 discriminant: None,
@@ -153,7 +146,7 @@
                         ident: None,
                         vis: Visibility::Inherited,
                         attrs: Vec::new(),
-                        ty: simple_ty("E"),
+                        ty: Ty::Path(None, "E".into()),
                     },
                 ]),
                 discriminant: None,