Token macros
diff --git a/src/attr.rs b/src/attr.rs
index 3b8f4fa..fb51052 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -9,7 +9,7 @@
     /// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
     pub struct Attribute {
         pub style: AttrStyle,
-        pub pound_token: tokens::Pound,
+        pub pound_token: Token![#],
         pub bracket_token: tokens::Bracket,
 
         /// The path of the attribute.
@@ -59,7 +59,7 @@
                 if let TokenNode::Literal(ref lit) = self.tts[1].0.kind {
                     return Some(MetaItem::NameValue(MetaNameValue {
                         ident: name.clone(),
-                        eq_token: tokens::Eq([Span(self.tts[0].0.span)]),
+                        eq_token: Token![=]([Span(self.tts[0].0.span)]),
                         lit: Lit {
                             value: LitKind::Other(lit.clone()),
                             span: Span(self.tts[1].0.span),
@@ -94,7 +94,7 @@
                     if let TokenNode::Literal(ref lit) = tts[2].kind {
                         let pair = MetaNameValue {
                             ident: Ident::new(sym, Span(tts[0].span)),
-                            eq_token: tokens::Eq([Span(tts[1].span)]),
+                            eq_token: Token![=]([Span(tts[1].span)]),
                             lit: Lit {
                                 value: LitKind::Other(lit.clone()),
                                 span: Span(tts[2].span),
@@ -131,7 +131,7 @@
 }
 
 fn list_of_nested_meta_items_from_tokens(mut tts: &[proc_macro2::TokenTree])
-    -> Option<Delimited<NestedMetaItem, tokens::Comma>>
+    -> Option<Delimited<NestedMetaItem, Token![,]>>
 {
     let mut delimited = Delimited::new();
     let mut first = true;
@@ -141,7 +141,7 @@
             first = false;
             None
         } else if let TokenNode::Op(',', Spacing::Alone) = tts[0].kind {
-            let tok = tokens::Comma([Span(tts[0].span)]);
+            let tok = Token![,]([Span(tts[0].span)]);
             tts = &tts[1..];
             if tts.is_empty() {
                 break
@@ -175,7 +175,7 @@
         Outer,
 
         /// Attribute of the form `#![...]`.
-        Inner(tokens::Bang),
+        Inner(Token![!]),
     }
 }
 
@@ -203,7 +203,7 @@
             /// Arguments to this attribute
             ///
             /// E.g. `..` in `#[derive(..)]`
-            pub nested: Delimited<NestedMetaItem, tokens::Comma>,
+            pub nested: Delimited<NestedMetaItem, Token![,]>,
         }),
 
         /// Name-value meta item.
@@ -215,7 +215,7 @@
             /// E.g. `feature` in `#[feature = "foo"]`
             pub ident: Ident,
 
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
 
             /// Arguments to this attribute
             ///
@@ -293,7 +293,6 @@
 pub mod parsing {
     use super::*;
     use synom::{PResult, Cursor, parse_error};
-    use synom::tokens::*;
     use proc_macro2::{TokenNode, Spacing, TokenTree};
 
     fn eq() -> TokenTree {
@@ -307,8 +306,8 @@
         #[cfg(feature = "full")]
         named!(pub parse_inner -> Self, alt!(
             do_parse!(
-                pound: syn!(Pound) >>
-                bang: syn!(Bang) >>
+                pound: punct!(#) >>
+                bang: punct!(!) >>
                 path_and_tts: brackets!(tuple!(
                     call!(::Path::parse_mod_style),
                     call!(::TokenTree::parse_list)
@@ -330,14 +329,14 @@
             map!(
                 lit_doc_comment,
                 |lit| Attribute {
-                    style: AttrStyle::Inner(tokens::Bang::default()),
+                    style: AttrStyle::Inner(<Token![!]>::default()),
                     path: "doc".into(),
                     tts: vec![
                         ::TokenTree(eq()),
                         ::TokenTree(lit),
                     ],
                     is_sugared_doc: true,
-                    pound_token: tokens::Pound::default(),
+                    pound_token: <Token![#]>::default(),
                     bracket_token: tokens::Bracket::default(),
                 }
             )
@@ -345,7 +344,7 @@
 
         named!(pub parse_outer -> Self, alt!(
             do_parse!(
-                pound: syn!(Pound) >>
+                pound: punct!(#) >>
                 path_and_tts: brackets!(tuple!(
                     call!(::Path::parse_mod_style),
                     call!(::TokenTree::parse_list)
@@ -374,7 +373,7 @@
                         ::TokenTree(lit),
                     ],
                     is_sugared_doc: true,
-                    pound_token: tokens::Pound::default(),
+                    pound_token: <Token![#]>::default(),
                     bracket_token: tokens::Bracket::default(),
                 }
             )
diff --git a/src/data.rs b/src/data.rs
index 0f98116..56004a1 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -16,7 +16,7 @@
         /// Explicit discriminant, e.g. `Foo = 1`
         pub discriminant: Option<Expr>,
 
-        pub eq_token: Option<tokens::Eq>,
+        pub eq_token: Option<Token![=]>,
     }
 }
 
@@ -24,10 +24,10 @@
     /// Data stored within an enum variant or struct.
     pub enum VariantData {
         /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
-        Struct(Delimited<Field, tokens::Comma>, tokens::Brace),
+        Struct(Delimited<Field, Token![,]>, tokens::Brace),
 
         /// Tuple variant, e.g. `Some(T)`.
-        Tuple(Delimited<Field, tokens::Comma>, tokens::Paren),
+        Tuple(Delimited<Field, Token![,]>, tokens::Paren),
 
         /// Unit variant, e.g. `None`.
         Unit,
@@ -72,7 +72,7 @@
         /// Type of the field.
         pub ty: Ty,
 
-        pub colon_token: Option<tokens::Colon>,
+        pub colon_token: Option<Token![:]>,
     }
 }
 
@@ -81,21 +81,21 @@
     pub enum Visibility {
         /// Public, i.e. `pub`.
         pub Public(VisPublic {
-            pub pub_token: tokens::Pub,
+            pub pub_token: Token![pub],
         }),
 
         /// Crate-visible, i.e. `pub(crate)`.
         pub Crate(VisCrate {
-            pub pub_token: tokens::Pub,
+            pub pub_token: Token![pub],
             pub paren_token: tokens::Paren,
-            pub crate_token: tokens::Crate,
+            pub crate_token: Token![crate],
         }),
 
         /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
         pub Restricted(VisRestricted {
-            pub pub_token: tokens::Pub,
+            pub pub_token: Token![pub],
             pub paren_token: tokens::Paren,
-            pub in_token: Option<tokens::In>,
+            pub in_token: Option<Token![in]>,
             pub path: Box<Path>,
         }),
 
@@ -109,15 +109,13 @@
     use super::*;
 
     use synom::Synom;
-    use synom::tokens;
-    use synom::tokens::*;
 
     impl Field {
         named!(pub parse_struct -> Self, do_parse!(
             attrs: many0!(call!(Attribute::parse_outer)) >>
             vis: syn!(Visibility) >>
             id: syn!(Ident) >>
-            colon: syn!(Colon) >>
+            colon: punct!(:) >>
             ty: syn!(Ty) >>
             (Field {
                 ident: Some(id),
@@ -145,8 +143,8 @@
     impl Synom for Visibility {
         named!(parse -> Self, alt!(
             do_parse!(
-                pub_token: syn!(Pub) >>
-                other: parens!(syn!(tokens::Crate)) >>
+                pub_token: keyword!(pub) >>
+                other: parens!(keyword!(crate)) >>
                 (Visibility::Crate(VisCrate {
                     crate_token: other.0,
                     paren_token: other.1,
@@ -155,8 +153,8 @@
             )
             |
             do_parse!(
-                pub_token: syn!(Pub) >>
-                other: parens!(syn!(Self_)) >>
+                pub_token: keyword!(pub) >>
+                other: parens!(keyword!(self)) >>
                 (Visibility::Restricted(VisRestricted {
                     path: Box::new(other.0.into()),
                     in_token: None,
@@ -166,8 +164,8 @@
             )
             |
             do_parse!(
-                pub_token: syn!(Pub) >>
-                other: parens!(syn!(Super)) >>
+                pub_token: keyword!(pub) >>
+                other: parens!(keyword!(super)) >>
                 (Visibility::Restricted(VisRestricted {
                     path: Box::new(other.0.into()),
                     in_token: None,
@@ -177,9 +175,9 @@
             )
             |
             do_parse!(
-                pub_token: syn!(Pub) >>
+                pub_token: keyword!(pub) >>
                 other: parens!(do_parse!(
-                    in_tok: syn!(In) >>
+                    in_tok: keyword!(in) >>
                     restricted: call!(Path::parse_mod_style) >>
                     (in_tok, restricted)
                 )) >>
@@ -191,7 +189,7 @@
                 }))
             )
             |
-            syn!(Pub) => { |tok| {
+            keyword!(pub) => { |tok| {
                 Visibility::Public(VisPublic {
                     pub_token: tok,
                 })
diff --git a/src/derive.rs b/src/derive.rs
index a0c1c8d..9671598 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -27,16 +27,16 @@
     pub enum Body {
         /// It's an enum.
         pub Enum(BodyEnum {
-            pub enum_token: tokens::Enum,
+            pub enum_token: Token![enum],
             pub brace_token: tokens::Brace,
-            pub variants: Delimited<Variant, tokens::Comma>,
+            pub variants: Delimited<Variant, Token![,]>,
         }),
 
         /// It's a struct.
         pub Struct(BodyStruct {
             pub data: VariantData,
-            pub struct_token: tokens::Struct,
-            pub semi_token: Option<tokens::Semi>,
+            pub struct_token: Token![struct],
+            pub semi_token: Option<Token![;]>,
         }),
     }
 
@@ -48,16 +48,15 @@
     use super::*;
 
     use synom::Synom;
-    use synom::tokens::*;
 
     impl Synom for DeriveInput {
         named!(parse -> Self, do_parse!(
             attrs: many0!(call!(Attribute::parse_outer)) >>
             vis: syn!(Visibility) >>
             which: alt!(
-                syn!(Struct) => { Ok }
+                keyword!(struct) => { Ok }
                 |
-                syn!(Enum) => { Err }
+                keyword!(enum) => { Err }
             ) >>
             id: syn!(Ident) >>
             generics: syn!(Generics) >>
@@ -101,7 +100,7 @@
     }
 
 
-    named!(struct_body -> (WhereClause, VariantData, Option<tokens::Semi>), alt!(
+    named!(struct_body -> (WhereClause, VariantData, Option<Token![;]>), alt!(
         do_parse!(
             wh: syn!(WhereClause) >>
             body: struct_like_body >>
@@ -111,18 +110,18 @@
         do_parse!(
             body: tuple_like_body >>
             wh: syn!(WhereClause) >>
-            semi: syn!(Semi) >>
+            semi: punct!(;) >>
             (wh, VariantData::Tuple(body.0, body.1), Some(semi))
         )
         |
         do_parse!(
             wh: syn!(WhereClause) >>
-            semi: syn!(Semi) >>
+            semi: punct!(;) >>
             (wh, VariantData::Unit, Some(semi))
         )
     ));
 
-    named!(enum_body -> (WhereClause, Delimited<Variant, tokens::Comma>, tokens::Brace), do_parse!(
+    named!(enum_body -> (WhereClause, Delimited<Variant, Token![,]>, tokens::Brace), do_parse!(
         wh: syn!(WhereClause) >>
         data: braces!(Delimited::parse_terminated) >>
         (wh, data.0, data.1)
@@ -140,7 +139,7 @@
                 epsilon!() => { |_| VariantData::Unit }
             ) >>
             disr: option!(do_parse!(
-                eq: syn!(Eq) >>
+                eq: punct!(=) >>
                 disr: syn!(Expr) >>
                 (eq, disr)
             )) >>
@@ -148,16 +147,16 @@
                 ident: id,
                 attrs: attrs,
                 data: data,
-                eq_token: disr.as_ref().map(|p| tokens::Eq((p.0).0)),
+                eq_token: disr.as_ref().map(|p| Token![=]((p.0).0)),
                 discriminant: disr.map(|p| p.1),
             })
         ));
     }
 
-    named!(struct_like_body -> (Delimited<Field, tokens::Comma>, tokens::Brace),
+    named!(struct_like_body -> (Delimited<Field, Token![,]>, tokens::Brace),
            braces!(call!(Delimited::parse_terminated_with, Field::parse_struct)));
 
-    named!(tuple_like_body -> (Delimited<Field, tokens::Comma>, tokens::Paren),
+    named!(tuple_like_body -> (Delimited<Field, Token![,]>, tokens::Paren),
            parens!(call!(Delimited::parse_terminated_with, Field::parse_tuple)));
 }
 
diff --git a/src/expr.rs b/src/expr.rs
index d8114fb..3271431 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -26,7 +26,7 @@
         /// A `box x` expression.
         pub Box(ExprBox #full {
             pub expr: Box<Expr>,
-            pub box_token: tokens::Box_,
+            pub box_token: Token![box],
         }),
 
         /// E.g. 'place <- val' or `in place { val }`.
@@ -38,14 +38,14 @@
 
         /// An array, e.g. `[a, b, c, d]`.
         pub Array(ExprArray #full {
-            pub exprs: Delimited<Expr, tokens::Comma>,
+            pub exprs: Delimited<Expr, Token![,]>,
             pub bracket_token: tokens::Bracket,
         }),
 
         /// A function call.
         pub Call(ExprCall {
             pub func: Box<Expr>,
-            pub args: Delimited<Expr, tokens::Comma>,
+            pub args: Delimited<Expr, Token![,]>,
             pub paren_token: tokens::Paren,
         }),
 
@@ -60,20 +60,20 @@
         pub MethodCall(ExprMethodCall #full {
             pub expr: Box<Expr>,
             pub method: Ident,
-            pub typarams: Delimited<Ty, tokens::Comma>,
-            pub args: Delimited<Expr, tokens::Comma>,
+            pub typarams: Delimited<Ty, Token![,]>,
+            pub args: Delimited<Expr, Token![,]>,
             pub paren_token: tokens::Paren,
-            pub dot_token: tokens::Dot,
-            pub lt_token: Option<tokens::Lt>,
-            pub colon2_token: Option<tokens::Colon2>,
-            pub gt_token: Option<tokens::Gt>,
+            pub dot_token: Token![.],
+            pub lt_token: Option<Token![<]>,
+            pub colon2_token: Option<Token![::]>,
+            pub gt_token: Option<Token![>]>,
         }),
 
         /// A tuple, e.g. `(a, b, c, d)`.
         pub Tup(ExprTup #full {
-            pub args: Delimited<Expr, tokens::Comma>,
+            pub args: Delimited<Expr, Token![,]>,
             pub paren_token: tokens::Paren,
-            pub lone_comma: Option<tokens::Comma>,
+            pub lone_comma: Option<Token![,]>,
         }),
 
         /// A binary operation, e.g. `a + b`, `a * b`.
@@ -95,14 +95,14 @@
         /// A cast, e.g. `foo as f64`.
         pub Cast(ExprCast {
             pub expr: Box<Expr>,
-            pub as_token: tokens::As,
+            pub as_token: Token![as],
             pub ty: Box<Ty>,
         }),
 
         /// A type ascription, e.g. `foo: f64`.
         pub Type(ExprType {
             pub expr: Box<Expr>,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Box<Ty>,
         }),
 
@@ -113,8 +113,8 @@
             pub cond: Box<Expr>,
             pub if_true: Block,
             pub if_false: Option<Box<Expr>>,
-            pub if_token: tokens::If,
-            pub else_token: Option<tokens::Else>,
+            pub if_token: Token![if],
+            pub else_token: Option<Token![else]>,
         }),
 
         /// An `if let` expression with an optional else block
@@ -127,10 +127,10 @@
             pub expr: Box<Expr>,
             pub if_true: Block,
             pub if_false: Option<Box<Expr>>,
-            pub if_token: tokens::If,
-            pub let_token: tokens::Let,
-            pub eq_token: tokens::Eq,
-            pub else_token: Option<tokens::Else>,
+            pub if_token: Token![if],
+            pub let_token: Token![let],
+            pub eq_token: Token![=],
+            pub else_token: Option<Token![else]>,
         }),
 
         /// A while loop, with an optional label
@@ -140,8 +140,8 @@
             pub cond: Box<Expr>,
             pub body: Block,
             pub label: Option<Lifetime>,
-            pub colon_token: Option<tokens::Colon>,
-            pub while_token: tokens::While,
+            pub colon_token: Option<Token![:]>,
+            pub while_token: Token![while],
         }),
 
         /// A while-let loop, with an optional label.
@@ -154,10 +154,10 @@
             pub expr: Box<Expr>,
             pub body: Block,
             pub label: Option<Lifetime>,
-            pub colon_token: Option<tokens::Colon>,
-            pub while_token: tokens::While,
-            pub let_token: tokens::Let,
-            pub eq_token: tokens::Eq,
+            pub colon_token: Option<Token![:]>,
+            pub while_token: Token![while],
+            pub let_token: Token![let],
+            pub eq_token: Token![=],
         }),
 
         /// A for loop, with an optional label.
@@ -170,9 +170,9 @@
             pub expr: Box<Expr>,
             pub body: Block,
             pub label: Option<Lifetime>,
-            pub for_token: tokens::For,
-            pub colon_token: Option<tokens::Colon>,
-            pub in_token: tokens::In,
+            pub for_token: Token![for],
+            pub colon_token: Option<Token![:]>,
+            pub in_token: Token![in],
         }),
 
         /// Conditionless loop with an optional label.
@@ -181,13 +181,13 @@
         pub Loop(ExprLoop #full {
             pub body: Block,
             pub label: Option<Lifetime>,
-            pub loop_token: tokens::Loop,
-            pub colon_token: Option<tokens::Colon>,
+            pub loop_token: Token![loop],
+            pub colon_token: Option<Token![:]>,
         }),
 
         /// A `match` block.
         pub Match(ExprMatch #full {
-            pub match_token: tokens::Match,
+            pub match_token: Token![match],
             pub brace_token: tokens::Brace,
             pub expr: Box<Expr>,
             pub arms: Vec<Arm>,
@@ -198,8 +198,8 @@
             pub capture: CaptureBy,
             pub decl: Box<FnDecl>,
             pub body: Box<Expr>,
-            pub or1_token: tokens::Or,
-            pub or2_token: tokens::Or,
+            pub or1_token: Token![|],
+            pub or2_token: Token![|],
         }),
 
         /// A block (`{ ... }` or `unsafe { ... }`)
@@ -212,7 +212,7 @@
         pub Assign(ExprAssign #full {
             pub left: Box<Expr>,
             pub right: Box<Expr>,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
         }),
 
         /// An assignment with an operator
@@ -228,7 +228,7 @@
         pub Field(ExprField #full {
             pub expr: Box<Expr>,
             pub field: Ident,
-            pub dot_token: tokens::Dot,
+            pub dot_token: Token![.],
         }),
 
         /// Access of an unnamed field of a struct or tuple-struct
@@ -237,7 +237,7 @@
         pub TupField(ExprTupField #full {
             pub expr: Box<Expr>,
             pub field: Lit,
-            pub dot_token: tokens::Dot,
+            pub dot_token: Token![.],
         }),
 
         /// An indexing operation (`foo[2]`)
@@ -266,7 +266,7 @@
 
         /// A referencing operation (`&a` or `&mut a`)
         pub AddrOf(ExprAddrOf #full {
-            pub and_token: tokens::And,
+            pub and_token: Token![&],
             pub mutbl: Mutability,
             pub expr: Box<Expr>,
         }),
@@ -275,19 +275,19 @@
         pub Break(ExprBreak #full {
             pub label: Option<Lifetime>,
             pub expr: Option<Box<Expr>>,
-            pub break_token: tokens::Break,
+            pub break_token: Token![break],
         }),
 
         /// A `continue`, with an optional label
         pub Continue(ExprContinue #full {
             pub label: Option<Lifetime>,
-            pub continue_token: tokens::Continue,
+            pub continue_token: Token![continue],
         }),
 
         /// A `return`, with an optional value to be returned
         pub Ret(ExprRet #full {
             pub expr: Option<Box<Expr>>,
-            pub return_token: tokens::Return,
+            pub return_token: Token![return],
         }),
 
         /// A macro invocation; pre-expansion
@@ -299,9 +299,9 @@
         /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
         pub Struct(ExprStruct #full {
             pub path: Path,
-            pub fields: Delimited<FieldValue, tokens::Comma>,
+            pub fields: Delimited<FieldValue, Token![,]>,
             pub rest: Option<Box<Expr>>,
-            pub dot2_token: Option<tokens::Dot2>,
+            pub dot2_token: Option<Token![..]>,
             pub brace_token: tokens::Brace,
         }),
 
@@ -311,7 +311,7 @@
         /// to be repeated; the second is the number of times to repeat it.
         pub Repeat(ExprRepeat #full {
             pub bracket_token: tokens::Bracket,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
             pub expr: Box<Expr>,
             pub amt: Box<Expr>,
         }),
@@ -335,15 +335,15 @@
         /// `expr?`
         pub Try(ExprTry #full {
             pub expr: Box<Expr>,
-            pub question_token: tokens::Question,
+            pub question_token: Token![?],
         }),
 
         /// A catch expression.
         ///
         /// E.g. `do catch { block }`
         pub Catch(ExprCatch #full {
-            pub do_token: tokens::Do,
-            pub catch_token: tokens::Catch,
+            pub do_token: Token![do],
+            pub catch_token: Token![catch],
             pub block: Block,
         }),
 
@@ -351,7 +351,7 @@
         ///
         /// E.g. `yield expr`
         pub Yield(ExprYield #full {
-            pub yield_token: tokens::Yield,
+            pub yield_token: Token![yield],
             pub expr: Option<Box<Expr>>,
         }),
     }
@@ -374,7 +374,7 @@
         /// Attributes tagged on the field.
         pub attrs: Vec<Attribute>,
 
-        pub colon_token: Option<tokens::Colon>,
+        pub colon_token: Option<Token![:]>,
     }
 }
 
@@ -404,7 +404,7 @@
         Expr(Box<Expr>),
 
         /// Expression with trailing semicolon;
-        Semi(Box<Expr>, tokens::Semi),
+        Semi(Box<Expr>, Token![;]),
 
         /// Macro invocation.
         Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
@@ -418,7 +418,7 @@
     pub enum MacStmtStyle {
         /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
         /// `foo!(...);`, `foo![...];`
-        Semicolon(tokens::Semi),
+        Semicolon(Token![;]),
 
         /// The macro statement had braces; e.g. foo! { ... }
         Braces,
@@ -434,10 +434,10 @@
 ast_struct! {
     /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
     pub struct Local {
-        pub let_token: tokens::Let,
-        pub colon_token: Option<tokens::Colon>,
-        pub eq_token: Option<tokens::Eq>,
-        pub semi_token: tokens::Semi,
+        pub let_token: Token![let],
+        pub colon_token: Option<Token![:]>,
+        pub eq_token: Option<Token![=]>,
+        pub semi_token: Token![;],
 
         pub pat: Box<Pat>,
         pub ty: Option<Box<Ty>>,
@@ -456,7 +456,7 @@
     pub enum Pat {
         /// Represents a wildcard pattern (`_`)
         pub Wild(PatWild {
-            pub underscore_token: tokens::Underscore,
+            pub underscore_token: Token![_],
         }),
 
         /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
@@ -467,16 +467,16 @@
             pub mode: BindingMode,
             pub ident: Ident,
             pub subpat: Option<Box<Pat>>,
-            pub at_token: Option<tokens::At>,
+            pub at_token: Option<Token![@]>,
         }),
 
         /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
         /// The `bool` is `true` in the presence of a `..`.
         pub Struct(PatStruct {
             pub path: Path,
-            pub fields: Delimited<FieldPat, tokens::Comma>,
+            pub fields: Delimited<FieldPat, Token![,]>,
             pub brace_token: tokens::Brace,
-            pub dot2_token: Option<tokens::Dot2>,
+            pub dot2_token: Option<Token![..]>,
         }),
 
         /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
@@ -500,22 +500,22 @@
         /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
         /// 0 <= position <= subpats.len()
         pub Tuple(PatTuple {
-            pub pats: Delimited<Pat, tokens::Comma>,
+            pub pats: Delimited<Pat, Token![,]>,
             pub dots_pos: Option<usize>,
             pub paren_token: tokens::Paren,
-            pub dot2_token: Option<tokens::Dot2>,
-            pub comma_token: Option<tokens::Comma>,
+            pub dot2_token: Option<Token![..]>,
+            pub comma_token: Option<Token![,]>,
         }),
         /// A `box` pattern
         pub Box(PatBox {
             pub pat: Box<Pat>,
-            pub box_token: tokens::Box_,
+            pub box_token: Token![box],
         }),
         /// A reference pattern, e.g. `&mut (a, b)`
         pub Ref(PatRef {
             pub pat: Box<Pat>,
             pub mutbl: Mutability,
-            pub and_token: tokens::And,
+            pub and_token: Token![&],
         }),
         /// A literal
         pub Lit(PatLit {
@@ -529,11 +529,11 @@
         }),
         /// `[a, b, i.., y, z]` is represented as:
         pub Slice(PatSlice {
-            pub front: Delimited<Pat, tokens::Comma>,
+            pub front: Delimited<Pat, Token![,]>,
             pub middle: Option<Box<Pat>>,
-            pub back: Delimited<Pat, tokens::Comma>,
-            pub dot2_token: Option<tokens::Dot2>,
-            pub comma_token: Option<tokens::Comma>,
+            pub back: Delimited<Pat, Token![,]>,
+            pub dot2_token: Option<Token![..]>,
+            pub comma_token: Option<Token![,]>,
             pub bracket_token: tokens::Bracket,
         }),
         /// A macro pattern; pre-expansion
@@ -555,12 +555,12 @@
     /// ```
     pub struct Arm {
         pub attrs: Vec<Attribute>,
-        pub pats: Delimited<Pat, tokens::Or>,
-        pub if_token: Option<tokens::If>,
+        pub pats: Delimited<Pat, Token![|]>,
+        pub if_token: Option<Token![if]>,
         pub guard: Option<Box<Expr>>,
-        pub rocket_token: tokens::Rocket,
+        pub rocket_token: Token![=>],
         pub body: Box<Expr>,
-        pub comma: Option<tokens::Comma>,
+        pub comma: Option<Token![,]>,
     }
 }
 
@@ -569,7 +569,7 @@
     /// A capture clause
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum CaptureBy {
-        Value(tokens::Move),
+        Value(Token![move]),
         Ref,
     }
 }
@@ -580,9 +580,9 @@
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum RangeLimits {
         /// Inclusive at the beginning, exclusive at the end
-        HalfOpen(tokens::Dot2),
+        HalfOpen(Token![..]),
         /// Inclusive at the beginning and end
-        Closed(tokens::Dot3),
+        Closed(Token![...]),
     }
 }
 
@@ -599,7 +599,7 @@
         /// The pattern the field is destructured to
         pub pat: Box<Pat>,
         pub is_shorthand: bool,
-        pub colon_token: Option<tokens::Colon>,
+        pub colon_token: Option<Token![:]>,
         pub attrs: Vec<Attribute>,
     }
 }
@@ -608,7 +608,7 @@
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum BindingMode {
-        ByRef(tokens::Ref, Mutability),
+        ByRef(Token![ref], Mutability),
         ByValue(Mutability),
     }
 }
@@ -617,8 +617,8 @@
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum InPlaceKind {
-        Arrow(tokens::LArrow),
-        In(tokens::In),
+        Arrow(Token![<-]),
+        In(Token![in]),
     }
 }
 
@@ -651,7 +651,6 @@
     use synom::{PResult, Cursor, Synom};
     #[cfg(feature = "full")]
     use synom::parse_error;
-    use synom::tokens::*;
 
     /// When we're parsing expressions which occur before blocks, like in
     /// an if statement's condition, we cannot parse a struct literal.
@@ -765,7 +764,7 @@
         mut e: call!(placement_expr, allow_struct, allow_block) >>
         alt!(
             do_parse!(
-                eq: syn!(Eq) >>
+                eq: punct!(=) >>
                 // Recurse into self to parse right-associative operator.
                 rhs: call!(assign_expr, allow_struct, true) >>
                 ({
@@ -808,7 +807,7 @@
         mut e: call!(range_expr, allow_struct, allow_block) >>
         alt!(
             do_parse!(
-                arrow: syn!(LArrow) >>
+                arrow: punct!(<-) >>
                 // Recurse into self to parse right-associative operator.
                 rhs: call!(placement_expr, allow_struct, true) >>
                 ({
@@ -861,12 +860,12 @@
     /// ```ignore
     /// <and> || <and> ...
     /// ```
-    binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
+    binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
 
     /// ```ignore
     /// <compare> && <compare> ...
     /// ```
-    binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
+    binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
 
     /// ```ignore
     /// <bitor> == <bitor> ...
@@ -880,33 +879,33 @@
     /// NOTE: This operator appears to be parsed as left-associative, but errors
     /// if it is used in a non-associative manner.
     binop!(compare_expr, bitor_expr, alt!(
-        syn!(EqEq) => { BinOp::Eq }
+        punct!(==) => { BinOp::Eq }
         |
-        syn!(Ne) => { BinOp::Ne }
+        punct!(!=) => { BinOp::Ne }
         |
         // must be above Lt
-        syn!(Le) => { BinOp::Le }
+        punct!(<=) => { BinOp::Le }
         |
         // must be above Gt
-        syn!(Ge) => { BinOp::Ge }
+        punct!(>=) => { BinOp::Ge }
         |
         do_parse!(
             // Make sure that we don't eat the < part of a <- operator
-            not!(syn!(LArrow)) >>
-            t: syn!(Lt) >>
+            not!(punct!(<-)) >>
+            t: punct!(<) >>
             (BinOp::Lt(t))
         )
         |
-        syn!(Gt) => { BinOp::Gt }
+        punct!(>) => { BinOp::Gt }
     ));
 
     /// ```ignore
     /// <bitxor> | <bitxor> ...
     /// ```
     binop!(bitor_expr, bitxor_expr, do_parse!(
-        not!(syn!(OrOr)) >>
-        not!(syn!(OrEq)) >>
-        t: syn!(Or) >>
+        not!(punct!(||)) >>
+        not!(punct!(|=)) >>
+        t: punct!(|) >>
         (BinOp::BitOr(t))
     ));
 
@@ -915,8 +914,8 @@
     /// ```
     binop!(bitxor_expr, bitand_expr, do_parse!(
         // NOTE: Make sure we aren't looking at ^=.
-        not!(syn!(CaretEq)) >>
-        t: syn!(Caret) >>
+        not!(punct!(^=)) >>
+        t: punct!(^) >>
         (BinOp::BitXor(t))
     ));
 
@@ -925,9 +924,9 @@
     /// ```
     binop!(bitand_expr, shift_expr, do_parse!(
         // NOTE: Make sure we aren't looking at && or &=.
-        not!(syn!(AndAnd)) >>
-        not!(syn!(AndEq)) >>
-        t: syn!(And) >>
+        not!(punct!(&&)) >>
+        not!(punct!(&=)) >>
+        t: punct!(&) >>
         (BinOp::BitAnd(t))
     ));
 
@@ -936,9 +935,9 @@
     /// <arith> >> <arith> ...
     /// ```
     binop!(shift_expr, arith_expr, alt!(
-        syn!(Shl) => { BinOp::Shl }
+        punct!(<<) => { BinOp::Shl }
         |
-        syn!(Shr) => { BinOp::Shr }
+        punct!(>>) => { BinOp::Shr }
     ));
 
     /// ```ignore
@@ -946,9 +945,9 @@
     /// <term> - <term> ...
     /// ```
     binop!(arith_expr, term_expr, alt!(
-        syn!(Add) => { BinOp::Add }
+        punct!(+) => { BinOp::Add }
         |
-        syn!(Sub) => { BinOp::Sub }
+        punct!(-) => { BinOp::Sub }
     ));
 
     /// ```ignore
@@ -957,11 +956,11 @@
     /// <cast> % <cast> ...
     /// ```
     binop!(term_expr, cast_expr, alt!(
-        syn!(Star) => { BinOp::Mul }
+        punct!(*) => { BinOp::Mul }
         |
-        syn!(Div) => { BinOp::Div }
+        punct!(/) => { BinOp::Div }
         |
-        syn!(Rem) => { BinOp::Rem }
+        punct!(%) => { BinOp::Rem }
     ));
 
     /// ```ignore
@@ -972,7 +971,7 @@
         mut e: call!(unary_expr, allow_struct, allow_block) >>
         many0!(alt!(
             do_parse!(
-                as_: syn!(As) >>
+                as_: keyword!(as) >>
                 // We can't accept `A + B` in cast expressions, as it's
                 // ambiguous with the + expression.
                 ty: call!(Ty::without_plus) >>
@@ -986,7 +985,7 @@
             )
             |
             do_parse!(
-                colon: syn!(Colon) >>
+                colon: punct!(:) >>
                 // We can't accept `A + B` in cast expressions, as it's
                 // ambiguous with the + expression.
                 ty: call!(Ty::without_plus) >>
@@ -1020,7 +1019,7 @@
         )
         |
         do_parse!(
-            and: syn!(And) >>
+            and: punct!(&) >>
             mutability: syn!(Mutability) >>
             expr: call!(unary_expr, allow_struct, true) >>
             (ExprAddrOf {
@@ -1031,7 +1030,7 @@
         )
         |
         do_parse!(
-            box_: syn!(Box_) >>
+            box_: keyword!(box) >>
             expr: call!(unary_expr, allow_struct, true) >>
             (ExprBox {
                 box_token: box_,
@@ -1111,7 +1110,7 @@
                 }.into();
             })
             |
-            tap!(question: syn!(Question) => {
+            tap!(question: punct!(?) => {
                 e = ExprTry {
                     expr: Box::new(e.into()),
                     question_token: question,
@@ -1265,7 +1264,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprInPlace {
         named!(parse -> Self, do_parse!(
-            in_: syn!(In) >>
+            in_: keyword!(in) >>
             place: expr_no_struct >>
             value: braces!(call!(Block::parse_within)) >>
             (ExprInPlace {
@@ -1296,18 +1295,18 @@
         ));
     }
 
-    named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
+    named!(and_call -> (Delimited<Expr, Token![,]>, tokens::Paren),
            parens!(call!(Delimited::parse_terminated)));
 
     #[cfg(feature = "full")]
     named!(and_method_call -> ExprMethodCall, do_parse!(
-        dot: syn!(Dot) >>
+        dot: punct!(.) >>
         method: syn!(Ident) >>
         typarams: option!(do_parse!(
-            colon2: syn!(Colon2) >>
-            lt: syn!(Lt) >>
+            colon2: punct!(::) >>
+            lt: punct!(<) >>
             tys: call!(Delimited::parse_terminated) >>
-            gt: syn!(Gt) >>
+            gt: punct!(>) >>
             (colon2, lt, tys, gt)
         )) >>
         args: parens!(call!(Delimited::parse_terminated)) >>
@@ -1350,10 +1349,10 @@
     #[cfg(feature = "full")]
     impl Synom for ExprIfLet {
         named!(parse -> Self, do_parse!(
-            if_: syn!(If) >>
-            let_: syn!(Let) >>
+            if_: keyword!(if) >>
+            let_: keyword!(let) >>
             pat: syn!(Pat) >>
-            eq: syn!(Eq) >>
+            eq: punct!(=) >>
             cond: expr_no_struct >>
             then_block: braces!(call!(Block::parse_within)) >>
             else_block: option!(else_block) >>
@@ -1367,7 +1366,7 @@
                     brace_token: then_block.1,
                 },
                 if_token: if_,
-                else_token: else_block.as_ref().map(|p| Else((p.0).0)),
+                else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
                 if_false: else_block.map(|p| Box::new(p.1.into())),
             })
         ));
@@ -1376,7 +1375,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprIf {
         named!(parse -> Self, do_parse!(
-            if_: syn!(If) >>
+            if_: keyword!(if) >>
             cond: expr_no_struct >>
             then_block: braces!(call!(Block::parse_within)) >>
             else_block: option!(else_block) >>
@@ -1387,15 +1386,15 @@
                     brace_token: then_block.1,
                 },
                 if_token: if_,
-                else_token: else_block.as_ref().map(|p| Else((p.0).0)),
+                else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
                 if_false: else_block.map(|p| Box::new(p.1.into())),
             })
         ));
     }
 
     #[cfg(feature = "full")]
-    named!(else_block -> (Else, ExprKind), do_parse!(
-        else_: syn!(Else) >>
+    named!(else_block -> (Token![else], ExprKind), do_parse!(
+        else_: keyword!(else) >>
         expr: alt!(
             syn!(ExprIf) => { ExprKind::If }
             |
@@ -1419,10 +1418,10 @@
     #[cfg(feature = "full")]
     impl Synom for ExprForLoop {
         named!(parse -> Self, do_parse!(
-            lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
-            for_: syn!(For) >>
+            lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+            for_: keyword!(for) >>
             pat: syn!(Pat) >>
-            in_: syn!(In) >>
+            in_: keyword!(in) >>
             expr: expr_no_struct >>
             loop_block: syn!(Block) >>
             (ExprForLoop {
@@ -1431,7 +1430,7 @@
                 pat: Box::new(pat),
                 expr: Box::new(expr),
                 body: loop_block,
-                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
                 label: lbl.map(|p| p.0),
             })
         ));
@@ -1440,13 +1439,13 @@
     #[cfg(feature = "full")]
     impl Synom for ExprLoop {
         named!(parse -> Self, do_parse!(
-            lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
-            loop_: syn!(Loop) >>
+            lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+            loop_: keyword!(loop) >>
             loop_block: syn!(Block) >>
             (ExprLoop {
                 loop_token: loop_,
                 body: loop_block,
-                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
                 label: lbl.map(|p| p.0),
             })
         ));
@@ -1455,7 +1454,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprMatch {
         named!(parse -> Self, do_parse!(
-            match_: syn!(Match) >>
+            match_: keyword!(match) >>
             obj: expr_no_struct >>
             res: braces!(many0!(syn!(Arm))) >>
             ({
@@ -1473,8 +1472,8 @@
     #[cfg(feature = "full")]
     impl Synom for ExprCatch {
         named!(parse -> Self, do_parse!(
-            do_: syn!(Do) >>
-            catch_: syn!(Catch) >>
+            do_: keyword!(do) >>
+            catch_: keyword!(catch) >>
             catch_block: syn!(Block) >>
             (ExprCatch {
                 block: catch_block,
@@ -1487,7 +1486,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprYield {
         named!(parse -> Self, do_parse!(
-            yield_: syn!(Yield) >>
+            yield_: keyword!(yield) >>
             expr: option!(syn!(Expr)) >>
             (ExprYield {
                 yield_token: yield_,
@@ -1501,21 +1500,21 @@
         named!(parse -> Self, do_parse!(
             attrs: many0!(call!(Attribute::parse_outer)) >>
             pats: call!(Delimited::parse_separated_nonempty) >>
-            guard: option!(tuple!(syn!(If), syn!(Expr))) >>
-            rocket: syn!(Rocket) >>
+            guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
+            rocket: punct!(=>) >>
             body: do_parse!(
                 expr: alt!(expr_nosemi | syn!(Expr)) >>
                 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
                     map!(input_end!(), |_| None)
                     |
-                    map!(syn!(Comma), Some)
+                    map!(punct!(,), Some)
                 )) >>
-                comma2: cond!(!arm_expr_requires_comma(&expr), option!(syn!(Comma))) >>
+                comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
                 (expr, comma1.and_then(|x| x).or(comma2.and_then(|x| x)))
             ) >>
             (Arm {
                 rocket_token: rocket,
-                if_token: guard.as_ref().map(|p| If((p.0).0)),
+                if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
                 attrs: attrs,
                 pats: pats,
                 guard: guard.map(|p| Box::new(p.1)),
@@ -1528,12 +1527,12 @@
     #[cfg(feature = "full")]
     named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
         capture: syn!(CaptureBy) >>
-        or1: syn!(Or) >>
+        or1: punct!(|) >>
         inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
-        or2: syn!(Or) >>
+        or2: punct!(|) >>
         ret_and_body: alt!(
             do_parse!(
-                arrow: syn!(RArrow) >>
+                arrow: punct!(->) >>
                 ty: syn!(Ty) >>
                 body: syn!(Block) >>
                 (ReturnType::Ty(ty, arrow),
@@ -1554,7 +1553,7 @@
                 output: ret_and_body.0,
                 variadic: false,
                 dot_tokens: None,
-                fn_token: tokens::Fn_::default(),
+                fn_token: <Token![fn]>::default(),
                 generics: Generics::default(),
                 paren_token: tokens::Paren::default(),
             }),
@@ -1565,11 +1564,11 @@
     #[cfg(feature = "full")]
     named!(fn_arg -> FnArg, do_parse!(
         pat: syn!(Pat) >>
-        ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
+        ty: option!(tuple!(punct!(:), syn!(Ty))) >>
         ({
             let (colon, ty) = ty.unwrap_or_else(|| {
-                (Colon::default(), TyInfer {
-                    underscore_token: Underscore::default(),
+                (<Token![:]>::default(), TyInfer {
+                    underscore_token: <Token![_]>::default(),
                 }.into())
             });
             ArgCaptured {
@@ -1583,13 +1582,13 @@
     #[cfg(feature = "full")]
     impl Synom for ExprWhile {
         named!(parse -> Self, do_parse!(
-            lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
-            while_: syn!(While) >>
+            lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+            while_: keyword!(while) >>
             cond: expr_no_struct >>
             while_block: syn!(Block) >>
             (ExprWhile {
                 while_token: while_,
-                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
                 cond: Box::new(cond),
                 body: while_block,
                 label: lbl.map(|p| p.0),
@@ -1600,18 +1599,18 @@
     #[cfg(feature = "full")]
     impl Synom for ExprWhileLet {
         named!(parse -> Self, do_parse!(
-            lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
-            while_: syn!(While) >>
-            let_: syn!(Let) >>
+            lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+            while_: keyword!(while) >>
+            let_: keyword!(let) >>
             pat: syn!(Pat) >>
-            eq: syn!(Eq) >>
+            eq: punct!(=) >>
             value: expr_no_struct >>
             while_block: syn!(Block) >>
             (ExprWhileLet {
                 eq_token: eq,
                 let_token: let_,
                 while_token: while_,
-                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
                 pat: Box::new(pat),
                 expr: Box::new(value),
                 body: while_block,
@@ -1623,7 +1622,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprContinue {
         named!(parse -> Self, do_parse!(
-            cont: syn!(Continue) >>
+            cont: keyword!(continue) >>
             lbl: option!(syn!(Lifetime)) >>
             (ExprContinue {
                 continue_token: cont,
@@ -1634,7 +1633,7 @@
 
     #[cfg(feature = "full")]
     named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
-        break_: syn!(Break) >>
+        break_: keyword!(break) >>
         lbl: option!(syn!(Lifetime)) >>
         // We can't allow blocks after a `break` expression when we wouldn't
         // allow structs, as this expression is ambiguous.
@@ -1648,7 +1647,7 @@
 
     #[cfg(feature = "full")]
     named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
-        return_: syn!(Return) >>
+        return_: keyword!(return) >>
         // NOTE: return is greedy and eats blocks after it even when in a
         // position where structs are not allowed, such as in if statement
         // conditions. For example:
@@ -1670,7 +1669,7 @@
                 base: option!(
                     cond!(fields.is_empty() || fields.trailing_delim(),
                         do_parse!(
-                            dots: syn!(Dot2) >>
+                            dots: punct!(..) >>
                             base: syn!(Expr) >>
                             (dots, base)
                         )
@@ -1700,7 +1699,7 @@
         named!(parse -> Self, alt!(
             do_parse!(
                 ident: field_ident >>
-                colon: syn!(Colon) >>
+                colon: punct!(:) >>
                 value: syn!(Expr) >>
                 (FieldValue {
                     ident: ident,
@@ -1726,7 +1725,7 @@
         named!(parse -> Self, do_parse!(
             data: brackets!(do_parse!(
                 value: syn!(Expr) >>
-                semi: syn!(Semi) >>
+                semi: punct!(;) >>
                 times: syn!(Expr) >>
                 (value, semi, times)
             )) >>
@@ -1762,9 +1761,9 @@
     impl Synom for RangeLimits {
         named!(parse -> Self, alt!(
             // Must come before Dot2
-            syn!(Dot3) => { RangeLimits::Closed }
+            punct!(...) => { RangeLimits::Closed }
             |
-            syn!(Dot2) => { RangeLimits::HalfOpen }
+            punct!(..) => { RangeLimits::HalfOpen }
         ));
     }
 
@@ -1779,12 +1778,12 @@
     }
 
     #[cfg(feature = "full")]
-    named!(and_field -> (Ident, Dot),
-           map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
+    named!(and_field -> (Ident, Token![.]),
+           map!(tuple!(punct!(.), syn!(Ident)), |(a, b)| (b, a)));
 
     #[cfg(feature = "full")]
-    named!(and_tup_field -> (Lit, Dot),
-           map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
+    named!(and_tup_field -> (Lit, Token![.]),
+           map!(tuple!(punct!(.), syn!(Lit)), |(a, b)| (b, a)));
 
     named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
 
@@ -1802,8 +1801,8 @@
     #[cfg(feature = "full")]
     impl Block {
         named!(pub parse_within -> Vec<Stmt>, do_parse!(
-            many0!(syn!(Semi)) >>
-            mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
+            many0!(punct!(;)) >>
+            mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
             last: option!(do_parse!(
                 attrs: many0!(call!(Attribute::parse_outer)) >>
                 mut e: syn!(Expr) >>
@@ -1841,11 +1840,11 @@
     named!(stmt_mac -> Stmt, do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         what: syn!(Path) >>
-        bang: syn!(Bang) >>
+        bang: punct!(!) >>
     // Only parse braces here; paren and bracket will get parsed as
     // expression statements
         data: braces!(syn!(TokenStream)) >>
-        semi: option!(syn!(Semi)) >>
+        semi: option!(punct!(;)) >>
         (Stmt::Macro(Box::new((
             Macro {
                 path: what,
@@ -1866,16 +1865,16 @@
     #[cfg(feature = "full")]
     named!(stmt_local -> Stmt, do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
-        let_: syn!(Let) >>
+        let_: keyword!(let) >>
         pat: syn!(Pat) >>
-        ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
-        init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
-        semi: syn!(Semi) >>
+        ty: option!(tuple!(punct!(:), syn!(Ty))) >>
+        init: option!(tuple!(punct!(=), syn!(Expr))) >>
+        semi: punct!(;) >>
         (Stmt::Local(Box::new(Local {
             let_token: let_,
             semi_token: semi,
-            colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
-            eq_token: init.as_ref().map(|p| Eq((p.0).0)),
+            colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
+            eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
             pat: Box::new(pat),
             ty: ty.map(|p| Box::new(p.1)),
             init: init.map(|p| Box::new(p.1)),
@@ -1892,9 +1891,9 @@
         mut e: expr_nosemi >>
         // If the next token is a `.` or a `?` it is special-cased to parse as
         // an expression instead of a blockexpression.
-        not!(syn!(Dot)) >>
-        not!(syn!(Question)) >>
-        semi: option!(syn!(Semi)) >>
+        not!(punct!(.)) >>
+        not!(punct!(?)) >>
+        semi: option!(punct!(;)) >>
         ({
             e.attrs = attrs;
             if let Some(semi) = semi {
@@ -1909,7 +1908,7 @@
     named!(stmt_expr -> Stmt, do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         mut e: syn!(Expr) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         ({
             e.attrs = attrs;
             Stmt::Semi(Box::new(e), semi)
@@ -1948,7 +1947,7 @@
     #[cfg(feature = "full")]
     impl Synom for PatWild {
         named!(parse -> Self, map!(
-            syn!(Underscore),
+            punct!(_),
             |u| PatWild { underscore_token: u }
         ));
     }
@@ -1956,7 +1955,7 @@
     #[cfg(feature = "full")]
     impl Synom for PatBox {
         named!(parse -> Self, do_parse!(
-            boxed: syn!(Box_) >>
+            boxed: keyword!(box) >>
             pat: syn!(Pat) >>
             (PatBox {
                 pat: Box::new(pat),
@@ -1968,23 +1967,23 @@
     #[cfg(feature = "full")]
     impl Synom for PatIdent {
         named!(parse -> Self, do_parse!(
-            mode: option!(syn!(Ref)) >>
+            mode: option!(keyword!(ref)) >>
             mutability: syn!(Mutability) >>
             name: alt!(
                 syn!(Ident)
                 |
-                syn!(Self_) => { Into::into }
+                keyword!(self) => { Into::into }
             ) >>
-            not!(syn!(Lt)) >>
-            not!(syn!(Colon2)) >>
-            subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
+            not!(punct!(<)) >>
+            not!(punct!(::)) >>
+            subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
             (PatIdent {
                 mode: match mode {
                     Some(mode) => BindingMode::ByRef(mode, mutability),
                     None => BindingMode::ByValue(mutability),
                 },
                 ident: name,
-                at_token: subpat.as_ref().map(|p| At((p.0).0)),
+                at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
                 subpat: subpat.map(|p| Box::new(p.1)),
             })
         ));
@@ -2010,7 +2009,7 @@
                 fields: call!(Delimited::parse_terminated) >>
                 base: option!(
                     cond!(fields.is_empty() || fields.trailing_delim(),
-                          syn!(Dot2))
+                          punct!(..))
                 ) >>
                 (fields, base)
             )) >>
@@ -2028,7 +2027,7 @@
         named!(parse -> Self, alt!(
             do_parse!(
                 ident: field_ident >>
-                colon: syn!(Colon) >>
+                colon: punct!(:) >>
                 pat: syn!(Pat) >>
                 (FieldPat {
                     ident: ident,
@@ -2040,8 +2039,8 @@
             )
             |
             do_parse!(
-                boxed: option!(syn!(Box_)) >>
-                mode: option!(syn!(Ref)) >>
+                boxed: option!(keyword!(box)) >>
+                mode: option!(keyword!(ref)) >>
                 mutability: syn!(Mutability) >>
                 ident: syn!(Ident) >>
                 ({
@@ -2106,8 +2105,8 @@
                 dotdot: map!(cond!(
                     elems.is_empty() || elems.trailing_delim(),
                     option!(do_parse!(
-                        dots: syn!(Dot2) >>
-                        trailing: option!(syn!(Comma)) >>
+                        dots: punct!(..) >>
+                        trailing: option!(punct!(,)) >>
                         (dots, trailing)
                     ))
                 ), |x| x.and_then(|x| x)) >>
@@ -2145,7 +2144,7 @@
     #[cfg(feature = "full")]
     impl Synom for PatRef {
         named!(parse -> Self, do_parse!(
-            and: syn!(And) >>
+            and: punct!(&) >>
             mutability: syn!(Mutability) >>
             pat: syn!(Pat) >>
             (PatRef {
@@ -2186,7 +2185,7 @@
 
     #[cfg(feature = "full")]
     named!(pat_lit_expr -> Expr, do_parse!(
-        neg: option!(syn!(Sub)) >>
+        neg: option!(punct!(-)) >>
         v: alt!(
             syn!(Lit) => { ExprKind::Lit }
             |
@@ -2194,7 +2193,7 @@
         ) >>
         (if neg.is_some() {
             ExprKind::Unary(ExprUnary {
-                op: UnOp::Neg(tokens::Sub::default()),
+                op: UnOp::Neg(<Token![-]>::default()),
                 expr: Box::new(v.into())
             }).into()
         } else {
@@ -2208,8 +2207,8 @@
             brackets!(do_parse!(
                 before: call!(Delimited::parse_terminated) >>
                 middle: option!(do_parse!(
-                    dots: syn!(Dot2) >>
-                    trailing: option!(syn!(Comma)) >>
+                    dots: punct!(..) >>
+                    trailing: option!(punct!(,)) >>
                     (dots, trailing)
                 )) >>
                 after: cond!(
@@ -2222,13 +2221,13 @@
                 (before, middle, after)
             )),
             |((before, middle, after), brackets)| {
-                let mut before: Delimited<Pat, tokens::Comma> = before;
-                let after: Option<Delimited<Pat, tokens::Comma>> = after;
-                let middle: Option<(Dot2, Option<Comma>)> = middle;
+                let mut before: Delimited<Pat, Token![,]> = before;
+                let after: Option<Delimited<Pat, Token![,]>> = after;
+                let middle: Option<(Token![..], Option<Token![,]>)> = middle;
                 PatSlice {
-                    dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
+                    dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
                     comma_token: middle.as_ref().and_then(|m| {
-                        m.1.as_ref().map(|m| Comma(m.0))
+                        m.1.as_ref().map(|m| Token![,](m.0))
                     }),
                     bracket_token: brackets,
                     middle: middle.and_then(|_| {
@@ -2248,7 +2247,7 @@
     #[cfg(feature = "full")]
     impl Synom for CaptureBy {
         named!(parse -> Self, alt!(
-            syn!(Move) => { CaptureBy::Value }
+            keyword!(move) => { CaptureBy::Value }
             |
             epsilon!() => { |_| CaptureBy::Ref }
         ));
@@ -2366,7 +2365,7 @@
                 // If we only have one argument, we need a trailing comma to
                 // distinguish ExprTup from ExprParen.
                 if self.args.len() == 1 && !self.args.trailing_delim() {
-                    tokens::Comma::default().to_tokens(tokens);
+                    <Token![,]>::default().to_tokens(tokens);
                 }
                 // XXX: Not sure how to handle this, but we never parse it yet.
                 // Is this for an expression like (0,)? Can't we use the
@@ -2410,7 +2409,7 @@
 
     #[cfg(feature = "full")]
     fn maybe_wrap_else(tokens: &mut Tokens,
-                       else_token: &Option<tokens::Else>,
+                       else_token: &Option<Token![else]>,
                        if_false: &Option<Box<Expr>>)
     {
         if let Some(ref if_false) = *if_false {
@@ -2524,7 +2523,7 @@
                     // for the last one.
                     let is_last = i == self.arms.len() - 1;
                     if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
-                        tokens::Comma::default().to_tokens(tokens);
+                        <Token![,]>::default().to_tokens(tokens);
                     }
                 }
             });
@@ -2776,7 +2775,7 @@
                 self.fields.to_tokens(tokens);
                 // NOTE: We need a comma before the dot2 token if it is present.
                 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
-                    tokens::Comma::default().to_tokens(tokens);
+                    <Token![,]>::default().to_tokens(tokens);
                 }
                 self.dot2_token.to_tokens(tokens);
             });
@@ -2813,7 +2812,7 @@
                 if Some(self.pats.len()) == self.dots_pos {
                     // Ensure there is a comma before the .. token.
                     if !self.pats.empty_or_trailing() {
-                        tokens::Comma::default().to_tokens(tokens);
+                        <Token![,]>::default().to_tokens(tokens);
                     }
                     self.dot2_token.to_tokens(tokens);
                 }
@@ -2867,7 +2866,7 @@
                 if !self.front.empty_or_trailing() &&
                     (self.middle.is_some() || self.dot2_token.is_some())
                 {
-                    tokens::Comma::default().to_tokens(tokens);
+                    <Token![,]>::default().to_tokens(tokens);
                 }
 
                 // If we have an identifier, we always need a .. token.
diff --git a/src/generics.rs b/src/generics.rs
index f989795..71aadb3 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -6,10 +6,10 @@
     /// of a function, enum, trait, etc.
     #[derive(Default)]
     pub struct Generics {
-        pub lt_token: Option<tokens::Lt>,
-        pub gt_token: Option<tokens::Gt>,
-        pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
-        pub ty_params: Delimited<TyParam, tokens::Comma>,
+        pub lt_token: Option<Token![<]>,
+        pub gt_token: Option<Token![>]>,
+        pub lifetimes: Delimited<LifetimeDef, Token![,]>,
+        pub ty_params: Delimited<TyParam, Token![,]>,
         pub where_clause: WhereClause,
     }
 }
@@ -70,10 +70,10 @@
     /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>`
     #[derive(Default)]
     pub struct BoundLifetimes {
-        pub for_token: tokens::For,
-        pub lt_token: tokens::Lt,
-        pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
-        pub gt_token: tokens::Gt,
+        pub for_token: Token![for],
+        pub lt_token: Token![<],
+        pub lifetimes: Delimited<LifetimeDef, Token![,]>,
+        pub gt_token: Token![>],
     }
 }
 
@@ -82,8 +82,8 @@
     pub struct LifetimeDef {
         pub attrs: Vec<Attribute>,
         pub lifetime: Lifetime,
-        pub colon_token: Option<tokens::Colon>,
-        pub bounds: Delimited<Lifetime, tokens::Add>,
+        pub colon_token: Option<Token![:]>,
+        pub bounds: Delimited<Lifetime, Token![+]>,
     }
 }
 
@@ -103,9 +103,9 @@
     pub struct TyParam {
         pub attrs: Vec<Attribute>,
         pub ident: Ident,
-        pub colon_token: Option<tokens::Colon>,
-        pub bounds: Delimited<TyParamBound, tokens::Add>,
-        pub eq_token: Option<tokens::Eq>,
+        pub colon_token: Option<Token![:]>,
+        pub bounds: Delimited<TyParamBound, Token![+]>,
+        pub eq_token: Option<Token![=]>,
         pub default: Option<Ty>,
     }
 }
@@ -140,7 +140,7 @@
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum TraitBoundModifier {
         None,
-        Maybe(tokens::Question),
+        Maybe(Token![?]),
     }
 }
 
@@ -148,8 +148,8 @@
     /// A `where` clause in a definition
     #[derive(Default)]
     pub struct WhereClause {
-        pub where_token: Option<tokens::Where>,
-        pub predicates: Delimited<WherePredicate, tokens::Comma>,
+        pub where_token: Option<Token![where]>,
+        pub predicates: Delimited<WherePredicate, Token![,]>,
     }
 }
 
@@ -168,22 +168,22 @@
             pub bound_lifetimes: Option<BoundLifetimes>,
             /// The type being bounded
             pub bounded_ty: Ty,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             /// Trait and lifetime bounds (`Clone+Send+'static`)
-            pub bounds: Delimited<TyParamBound, tokens::Add>,
+            pub bounds: Delimited<TyParamBound, Token![+]>,
         }),
 
         /// A lifetime predicate, e.g. `'a: 'b+'c`
         pub RegionPredicate(WhereRegionPredicate {
             pub lifetime: Lifetime,
-            pub colon_token: Option<tokens::Colon>,
-            pub bounds: Delimited<Lifetime, tokens::Add>,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Delimited<Lifetime, Token![+]>,
         }),
 
         /// An equality predicate (unsupported)
         pub EqPredicate(WhereEqPredicate {
             pub lhs_ty: Ty,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub rhs_ty: Ty,
         }),
     }
@@ -194,19 +194,18 @@
     use super::*;
 
     use synom::Synom;
-    use synom::tokens::*;
 
     impl Synom for Generics {
         named!(parse -> Self, map!(
             alt!(
                 do_parse!(
-                    lt: syn!(Lt) >>
+                    lt: punct!(<) >>
                     lifetimes: call!(Delimited::parse_terminated) >>
                     ty_params: cond!(
                         lifetimes.is_empty() || lifetimes.trailing_delim(),
                         call!(Delimited::parse_terminated)
                     ) >>
-                    gt: syn!(Gt) >>
+                    gt: punct!(>) >>
                     (lifetimes, ty_params, Some(lt), Some(gt))
                 )
                 |
@@ -226,7 +225,7 @@
         named!(parse -> Self, do_parse!(
             attrs: many0!(call!(Attribute::parse_outer)) >>
             life: syn!(Lifetime) >>
-            colon: option!(syn!(Colon)) >>
+            colon: option!(punct!(:)) >>
             bounds: cond!(
                 colon.is_some(),
                 call!(Delimited::parse_separated_nonempty)
@@ -235,17 +234,17 @@
                 attrs: attrs,
                 lifetime: life,
                 bounds: bounds.unwrap_or_default(),
-                colon_token: colon.map(|_| tokens::Colon::default()),
+                colon_token: colon.map(|_| <Token![:]>::default()),
             })
         ));
     }
 
     impl Synom for BoundLifetimes {
         named!(parse -> Self, do_parse!(
-            for_: syn!(For) >>
-            lt: syn!(Lt) >>
+            for_: keyword!(for) >>
+            lt: punct!(<) >>
             lifetimes: call!(Delimited::parse_terminated) >>
-            gt: syn!(Gt) >>
+            gt: punct!(>) >>
             (BoundLifetimes {
                 for_token: for_,
                 lt_token: lt,
@@ -259,13 +258,13 @@
         named!(parse -> Self, do_parse!(
             attrs: many0!(call!(Attribute::parse_outer)) >>
             id: syn!(Ident) >>
-            colon: option!(syn!(Colon)) >>
+            colon: option!(punct!(:)) >>
             bounds: cond!(
                 colon.is_some(),
                 call!(Delimited::parse_separated_nonempty)
             ) >>
             default: option!(do_parse!(
-                eq: syn!(Eq) >>
+                eq: punct!(=) >>
                 ty: syn!(Ty) >>
                 (eq, ty)
             )) >>
@@ -274,7 +273,7 @@
                 ident: id,
                 bounds: bounds.unwrap_or_default(),
                 colon_token: colon,
-                eq_token: default.as_ref().map(|d| tokens::Eq((d.0).0)),
+                eq_token: default.as_ref().map(|d| Token![=]((d.0).0)),
                 default: default.map(|d| d.1),
             })
         ));
@@ -283,7 +282,7 @@
     impl Synom for TyParamBound {
         named!(parse -> Self, alt!(
             do_parse!(
-                question: syn!(Question) >>
+                question: punct!(?) >>
                 poly: syn!(PolyTraitRef) >>
                 (TyParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
             )
@@ -303,7 +302,7 @@
     impl Synom for WhereClause {
         named!(parse -> Self, alt!(
             do_parse!(
-                where_: syn!(Where) >>
+                where_: keyword!(where) >>
                 predicates: call!(Delimited::parse_terminated) >>
                 (WhereClause {
                     predicates: predicates,
@@ -323,7 +322,7 @@
         named!(parse -> Self, alt!(
             do_parse!(
                 ident: syn!(Lifetime) >>
-                colon: option!(syn!(Colon)) >>
+                colon: option!(punct!(:)) >>
                 bounds: cond!(
                     colon.is_some(),
                     call!(Delimited::parse_separated)
@@ -338,7 +337,7 @@
             do_parse!(
                 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
                 bounded_ty: syn!(Ty) >>
-                colon: syn!(Colon) >>
+                colon: punct!(:) >>
                 bounds: call!(Delimited::parse_separated_nonempty) >>
                 (WherePredicate::BoundPredicate(WhereBoundPredicate {
                     bound_lifetimes: bound_lifetimes,
@@ -369,7 +368,7 @@
     fn maybe_add_lifetime_params_comma(tokens: &mut Tokens, generics: &Generics) {
         // We may need to require a trailing comma if we have any ty_params.
         if !generics.lifetimes.empty_or_trailing() && !generics.ty_params.is_empty() {
-            tokens::Comma::default().to_tokens(tokens);
+            <Token![,]>::default().to_tokens(tokens);
         }
     }
 
@@ -436,7 +435,7 @@
     impl<'a> ToTokens for Turbofish<'a> {
         fn to_tokens(&self, tokens: &mut Tokens) {
             if !empty_normal_generics(&self.0) {
-                tokens::Colon2::default().to_tokens(tokens);
+                <Token![::]>::default().to_tokens(tokens);
                 TyGenerics(self.0).to_tokens(tokens);
             }
         }
diff --git a/src/ident.rs b/src/ident.rs
index fa55f2f..4af78e6 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -7,7 +7,6 @@
 use unicode_xid::UnicodeXID;
 
 use Span;
-use tokens;
 
 /// A word of Rust code, such as a keyword or variable name.
 ///
@@ -18,7 +17,7 @@
 ///
 /// - The empty string is not an identifier. Use `Option<Ident>`.
 /// - An underscore by itself is not an identifier. Use
-///   `syn::tokens::Underscore` instead.
+///   `Token![_]` instead.
 /// - A lifetime is not an identifier. Use `syn::Lifetime` instead.
 ///
 /// An identifier constructed with `Ident::new` is permitted to be a Rust
@@ -148,20 +147,20 @@
     }
 }
 
-impl From<tokens::Self_> for Ident {
-    fn from(tok: tokens::Self_) -> Self {
+impl From<Token![self]> for Ident {
+    fn from(tok: Token![self]) -> Self {
         Ident::new(Term::intern("self"), tok.0)
     }
 }
 
-impl From<tokens::CapSelf> for Ident {
-    fn from(tok: tokens::CapSelf) -> Self {
+impl From<Token![Self]> for Ident {
+    fn from(tok: Token![Self]) -> Self {
         Ident::new(Term::intern("Self"), tok.0)
     }
 }
 
-impl From<tokens::Super> for Ident {
-    fn from(tok: tokens::Super) -> Self {
+impl From<Token![super]> for Ident {
+    fn from(tok: Token![super]) -> Self {
         Ident::new(Term::intern("super"), tok.0)
     }
 }
diff --git a/src/item.rs b/src/item.rs
index 86b0ea9..77c83d1 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -10,11 +10,11 @@
         pub ExternCrate(ItemExternCrate {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub extern_token: tokens::Extern,
-            pub crate_token: tokens::Crate,
+            pub extern_token: Token![extern],
+            pub crate_token: Token![crate],
             pub ident: Ident,
-            pub rename: Option<(tokens::As, Ident)>,
-            pub semi_token: tokens::Semi,
+            pub rename: Option<(Token![as], Ident)>,
+            pub semi_token: Token![;],
         }),
         /// A use declaration (`use` or `pub use`) item.
         ///
@@ -22,9 +22,9 @@
         pub Use(ItemUse {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub use_token: tokens::Use,
+            pub use_token: Token![use],
             pub path: Box<ViewPath>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         /// A static item (`static` or `pub static`).
         ///
@@ -32,14 +32,14 @@
         pub Static(ItemStatic {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub static_token: tokens::Static,
+            pub static_token: Token![static],
             pub mutbl: Mutability,
             pub ident: Ident,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Box<Ty>,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub expr: Box<Expr>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         /// A constant item (`const` or `pub const`).
         ///
@@ -47,13 +47,13 @@
         pub Const(ItemConst {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub const_token: tokens::Const,
+            pub const_token: Token![const],
             pub ident: Ident,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Box<Ty>,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub expr: Box<Expr>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         /// A function declaration (`fn` or `pub fn`).
         ///
@@ -74,10 +74,10 @@
         pub Mod(ItemMod {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub mod_token: tokens::Mod,
+            pub mod_token: Token![mod],
             pub ident: Ident,
             pub content: Option<(tokens::Brace, Vec<Item>)>,
-            pub semi: Option<tokens::Semi>,
+            pub semi: Option<Token![;]>,
         }),
         /// An external module (`extern` or `pub extern`).
         ///
@@ -94,12 +94,12 @@
         pub Ty(ItemTy {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub type_token: tokens::Type,
+            pub type_token: Token![type],
             pub ident: Ident,
             pub generics: Generics,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub ty: Box<Ty>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         /// An enum definition (`enum` or `pub enum`).
         ///
@@ -107,11 +107,11 @@
         pub Enum(ItemEnum {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub enum_token: tokens::Enum,
+            pub enum_token: Token![enum],
             pub ident: Ident,
             pub generics: Generics,
             pub brace_token: tokens::Brace,
-            pub variants: Delimited<Variant, tokens::Comma>,
+            pub variants: Delimited<Variant, Token![,]>,
         }),
         /// A struct definition (`struct` or `pub struct`).
         ///
@@ -119,11 +119,11 @@
         pub Struct(ItemStruct {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub struct_token: tokens::Struct,
+            pub struct_token: Token![struct],
             pub ident: Ident,
             pub generics: Generics,
             pub data: VariantData,
-            pub semi_token: Option<tokens::Semi>,
+            pub semi_token: Option<Token![;]>,
         }),
         /// A union definition (`union` or `pub union`).
         ///
@@ -131,7 +131,7 @@
         pub Union(ItemUnion {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub union_token: tokens::Union,
+            pub union_token: Token![union],
             pub ident: Ident,
             pub generics: Generics,
             pub data: VariantData,
@@ -143,11 +143,11 @@
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub unsafety: Unsafety,
-            pub trait_token: tokens::Trait,
+            pub trait_token: Token![trait],
             pub ident: Ident,
             pub generics: Generics,
-            pub colon_token: Option<tokens::Colon>,
-            pub supertraits: Delimited<TyParamBound, tokens::Add>,
+            pub colon_token: Option<Token![:]>,
+            pub supertraits: Delimited<TyParamBound, Token![+]>,
             pub brace_token: tokens::Brace,
             pub items: Vec<TraitItem>,
         }),
@@ -157,10 +157,10 @@
         pub DefaultImpl(ItemDefaultImpl {
             pub attrs: Vec<Attribute>,
             pub unsafety: Unsafety,
-            pub impl_token: tokens::Impl,
+            pub impl_token: Token![impl],
             pub path: Path,
-            pub for_token: tokens::For,
-            pub dot2_token: tokens::Dot2,
+            pub for_token: Token![for],
+            pub dot2_token: Token![..],
             pub brace_token: tokens::Brace,
         }),
         /// An implementation.
@@ -170,10 +170,10 @@
             pub attrs: Vec<Attribute>,
             pub defaultness: Defaultness,
             pub unsafety: Unsafety,
-            pub impl_token: tokens::Impl,
+            pub impl_token: Token![impl],
             pub generics: Generics,
             /// Trait this impl implements.
-            pub trait_: Option<(ImplPolarity, Path, tokens::For)>,
+            pub trait_: Option<(ImplPolarity, Path, Token![for])>,
             /// The Self type of the impl.
             pub self_ty: Box<Ty>,
             pub brace_token: tokens::Brace,
@@ -229,23 +229,23 @@
         /// `foo::bar::baz` (with `as baz` implicitly on the right)
         pub Simple(PathSimple {
             pub path: Path,
-            pub as_token: Option<tokens::As>,
+            pub as_token: Option<Token![as]>,
             pub rename: Option<Ident>,
         }),
 
         /// `foo::bar::*`
         pub Glob(PathGlob {
             pub path: Path,
-            pub colon2_token: Option<tokens::Colon2>,
-            pub star_token: tokens::Star,
+            pub colon2_token: Option<Token![::]>,
+            pub star_token: Token![*],
         }),
 
         /// `foo::bar::{a, b, c}`
         pub List(PathList {
             pub path: Path,
-            pub colon2_token: tokens::Colon2,
+            pub colon2_token: Token![::],
             pub brace_token: tokens::Brace,
-            pub items: Delimited<PathListItem, tokens::Comma>,
+            pub items: Delimited<PathListItem, Token![,]>,
         }),
     }
 }
@@ -255,14 +255,14 @@
         pub name: Ident,
         /// renamed in list, e.g. `use foo::{bar as baz};`
         pub rename: Option<Ident>,
-        pub as_token: Option<tokens::As>,
+        pub as_token: Option<Token![as]>,
     }
 }
 
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum Constness {
-        Const(tokens::Const),
+        Const(Token![const]),
         NotConst,
     }
 }
@@ -270,7 +270,7 @@
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum Defaultness {
-        Default(tokens::Default_),
+        Default(Token![default]),
         Final,
     }
 }
@@ -284,18 +284,18 @@
             pub vis: Visibility,
             pub ident: Ident,
             pub decl: Box<FnDecl>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         /// A foreign static item (`static ext: u8`)
         pub Static(ForeignItemStatic {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
-            pub static_token: tokens::Static,
+            pub static_token: Token![static],
             pub mutbl: Mutability,
             pub ident: Ident,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Box<Ty>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
     }
 }
@@ -308,27 +308,27 @@
     pub enum TraitItem {
         pub Const(TraitItemConst {
             pub attrs: Vec<Attribute>,
-            pub const_token: tokens::Const,
+            pub const_token: Token![const],
             pub ident: Ident,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Ty,
-            pub default: Option<(tokens::Eq, Expr)>,
-            pub semi_token: tokens::Semi,
+            pub default: Option<(Token![=], Expr)>,
+            pub semi_token: Token![;],
         }),
         pub Method(TraitItemMethod {
             pub attrs: Vec<Attribute>,
             pub sig: MethodSig,
             pub default: Option<Block>,
-            pub semi_token: Option<tokens::Semi>,
+            pub semi_token: Option<Token![;]>,
         }),
         pub Type(TraitItemType {
             pub attrs: Vec<Attribute>,
-            pub type_token: tokens::Type,
+            pub type_token: Token![type],
             pub ident: Ident,
-            pub colon_token: Option<tokens::Colon>,
-            pub bounds: Delimited<TyParamBound, tokens::Add>,
-            pub default: Option<(tokens::Eq, Ty)>,
-            pub semi_token: tokens::Semi,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Delimited<TyParamBound, Token![+]>,
+            pub default: Option<(Token![=], Ty)>,
+            pub semi_token: Token![;],
         }),
         pub Macro(TraitItemMacro {
             pub attrs: Vec<Attribute>,
@@ -343,7 +343,7 @@
         /// `impl Trait for Type`
         Positive,
         /// `impl !Trait for Type`
-        Negative(tokens::Bang),
+        Negative(Token![!]),
     }
 }
 
@@ -353,13 +353,13 @@
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub defaultness: Defaultness,
-            pub const_token: tokens::Const,
+            pub const_token: Token![const],
             pub ident: Ident,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Ty,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub expr: Expr,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         pub Method(ImplItemMethod {
             pub attrs: Vec<Attribute>,
@@ -372,11 +372,11 @@
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub defaultness: Defaultness,
-            pub type_token: tokens::Type,
+            pub type_token: Token![type],
             pub ident: Ident,
-            pub eq_token: tokens::Eq,
+            pub eq_token: Token![=],
             pub ty: Ty,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
         }),
         pub Macro(ImplItemMacro {
             pub attrs: Vec<Attribute>,
@@ -402,13 +402,13 @@
     ///
     /// E.g. `fn foo(bar: baz)`
     pub struct FnDecl {
-        pub fn_token: tokens::Fn_,
+        pub fn_token: Token![fn],
         pub paren_token: tokens::Paren,
-        pub inputs: Delimited<FnArg, tokens::Comma>,
+        pub inputs: Delimited<FnArg, Token![,]>,
         pub output: ReturnType,
         pub generics: Generics,
         pub variadic: bool,
-        pub dot_tokens: Option<tokens::Dot3>,
+        pub dot_tokens: Option<Token![...]>,
     }
 }
 
@@ -418,18 +418,18 @@
     /// E.g. `bar: usize` as in `fn foo(bar: usize)`
     pub enum FnArg {
         pub SelfRef(ArgSelfRef {
-            pub and_token: tokens::And,
-            pub self_token: tokens::Self_,
+            pub and_token: Token![&],
+            pub self_token: Token![self],
             pub lifetime: Option<Lifetime>,
             pub mutbl: Mutability,
         }),
         pub SelfValue(ArgSelf {
             pub mutbl: Mutability,
-            pub self_token: tokens::Self_,
+            pub self_token: Token![self],
         }),
         pub Captured(ArgCaptured {
             pub pat: Pat,
-            pub colon_token: tokens::Colon,
+            pub colon_token: Token![:],
             pub ty: Ty,
         }),
         pub Ignored(Ty),
@@ -441,8 +441,6 @@
     use super::*;
 
     use synom::Synom;
-    use synom::tokens::*;
-    use synom::tokens;
 
     impl_synom!(Item "item" alt!(
         syn!(ItemExternCrate) => { Item::ExternCrate }
@@ -479,10 +477,10 @@
     impl_synom!(ItemMacro "macro item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         what: syn!(Path) >>
-        bang: syn!(Bang) >>
+        bang: punct!(!) >>
         ident: option!(syn!(Ident)) >>
         body: call!(::TokenTree::parse_delimited) >>
-        cond!(!body.is_braced(), syn!(Semi)) >>
+        cond!(!body.is_braced(), punct!(;)) >>
         (ItemMacro {
             attrs: attrs,
             ident: ident,
@@ -497,11 +495,11 @@
     impl_synom!(ItemExternCrate "extern crate item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        extern_: syn!(Extern) >>
-        crate_: syn!(tokens::Crate) >>
+        extern_: keyword!(extern) >>
+        crate_: keyword!(crate) >>
         ident: syn!(Ident) >>
-        rename: option!(tuple!(syn!(As), syn!(Ident))) >>
-        semi: syn!(Semi) >>
+        rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
+        semi: punct!(;) >>
         (ItemExternCrate {
             attrs: attrs,
             vis: vis,
@@ -516,9 +514,9 @@
     impl_synom!(ItemUse "use item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        use_: syn!(Use) >>
+        use_: keyword!(use) >>
         what: syn!(ViewPath) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ItemUse {
             attrs: attrs,
             vis: vis,
@@ -541,10 +539,10 @@
     impl Synom for PathSimple {
         named!(parse -> Self, do_parse!(
             path: syn!(Path) >>
-            rename: option!(tuple!(syn!(As), syn!(Ident))) >>
+            rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
             (PathSimple {
                 path: path,
-                as_token: rename.as_ref().map(|p| As((p.0).0)),
+                as_token: rename.as_ref().map(|p| Token![as]((p.0).0)),
                 rename: rename.map(|p| p.1),
             })
         ));
@@ -554,10 +552,10 @@
         named!(parse -> Self, do_parse!(
             path: option!(do_parse!(
                 path: syn!(Path) >>
-                colon2: syn!(Colon2) >>
+                colon2: punct!(::) >>
                 (path, colon2)
             )) >>
-            star: syn!(Star) >>
+            star: punct!(*) >>
             ({
                 match path {
                     Some((path, colon2)) => {
@@ -586,7 +584,7 @@
         named!(parse -> Self, alt!(
             do_parse!(
                 path: syn!(Path) >>
-                colon2: syn!(Colon2) >>
+                colon2: punct!(::) >>
                 items: braces!(call!(Delimited::parse_terminated)) >>
                 (PathList {
                     path: path,
@@ -597,7 +595,7 @@
             )
             |
             do_parse!(
-                colon: option!(syn!(Colon2)) >>
+                colon: option!(punct!(::)) >>
                 items: braces!(call!(Delimited::parse_terminated)) >>
                 (PathList {
                     path: Path {
@@ -617,12 +615,12 @@
             name: alt!(
                 syn!(Ident)
                 |
-                map!(syn!(Self_), Into::into)
+                map!(keyword!(self), Into::into)
             ) >>
-            rename: option!(tuple!(syn!(As), syn!(Ident))) >>
+            rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
             (PathListItem {
                 name: name,
-                as_token: rename.as_ref().map(|p| As((p.0).0)),
+                as_token: rename.as_ref().map(|p| Token![as]((p.0).0)),
                 rename: rename.map(|p| p.1),
             })
         ));
@@ -631,14 +629,14 @@
     impl_synom!(ItemStatic "static item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        static_: syn!(Static) >>
+        static_: keyword!(static) >>
         mutability: syn!(Mutability) >>
         ident: syn!(Ident) >>
-        colon: syn!(Colon) >>
+        colon: punct!(:) >>
         ty: syn!(Ty) >>
-        eq: syn!(Eq) >>
+        eq: punct!(=) >>
         value: syn!(Expr) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ItemStatic {
             attrs: attrs,
             vis: vis,
@@ -656,13 +654,13 @@
     impl_synom!(ItemConst "const item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        const_: syn!(Const) >>
+        const_: keyword!(const) >>
         ident: syn!(Ident) >>
-        colon: syn!(Colon) >>
+        colon: punct!(:) >>
         ty: syn!(Ty) >>
-        eq: syn!(Eq) >>
+        eq: punct!(=) >>
         value: syn!(Expr) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ItemConst {
             attrs: attrs,
             vis: vis,
@@ -682,7 +680,7 @@
         constness: syn!(Constness) >>
         unsafety: syn!(Unsafety) >>
         abi: option!(syn!(Abi)) >>
-        fn_: syn!(Fn_) >>
+        fn_: keyword!(fn) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         inputs: parens!(Delimited::parse_terminated) >>
@@ -725,11 +723,11 @@
     impl Synom for FnArg {
         named!(parse -> Self, alt!(
             do_parse!(
-                and: syn!(And) >>
+                and: punct!(&) >>
                 lt: option!(syn!(Lifetime)) >>
                 mutability: syn!(Mutability) >>
-                self_: syn!(Self_) >>
-                not!(syn!(Colon)) >>
+                self_: keyword!(self) >>
+                not!(punct!(:)) >>
                 (ArgSelfRef {
                     lifetime: lt,
                     mutbl: mutability,
@@ -740,8 +738,8 @@
             |
             do_parse!(
                 mutability: syn!(Mutability) >>
-                self_: syn!(Self_) >>
-                not!(syn!(Colon)) >>
+                self_: keyword!(self) >>
+                not!(punct!(:)) >>
                 (ArgSelf {
                     mutbl: mutability,
                     self_token: self_,
@@ -750,7 +748,7 @@
             |
             do_parse!(
                 pat: syn!(Pat) >>
-                colon: syn!(Colon) >>
+                colon: punct!(:) >>
                 ty: syn!(Ty) >>
                 (ArgCaptured {
                     pat: pat,
@@ -766,10 +764,10 @@
     impl_synom!(ItemMod "mod item" do_parse!(
         outer_attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        mod_: syn!(Mod) >>
+        mod_: keyword!(mod) >>
         ident: syn!(Ident) >>
         content_semi: alt!(
-            syn!(Semi) => {|semi| (
+            punct!(;) => {|semi| (
                 Vec::new(),
                 None,
                 Some(semi),
@@ -821,18 +819,18 @@
     impl_synom!(ForeignItemFn "foreign function" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        fn_: syn!(Fn_) >>
+        fn_: keyword!(fn) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         inputs: parens!(do_parse!(
             args: call!(Delimited::parse_terminated) >>
             variadic: cond!(args.is_empty() || args.trailing_delim(),
-                            option!(syn!(Dot3))) >>
+                            option!(punct!(...))) >>
             (args, variadic)
         )) >>
         ret: syn!(ReturnType) >>
         where_clause: syn!(WhereClause) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         ({
             let ((inputs, variadic), parens) = inputs;
             let variadic = variadic.and_then(|v| v);
@@ -860,12 +858,12 @@
     impl_synom!(ForeignItemStatic "foreign static" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        static_: syn!(Static) >>
+        static_: keyword!(static) >>
         mutability: syn!(Mutability) >>
         ident: syn!(Ident) >>
-        colon: syn!(Colon) >>
+        colon: punct!(:) >>
         ty: syn!(Ty) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ForeignItemStatic {
             ident: ident,
             attrs: attrs,
@@ -881,13 +879,13 @@
     impl_synom!(ItemTy "type item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        type_: syn!(Type) >>
+        type_: keyword!(type) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         where_clause: syn!(WhereClause) >>
-        eq: syn!(Eq) >>
+        eq: punct!(=) >>
         ty: syn!(Ty) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ItemTy {
             attrs: attrs,
             vis: vis,
@@ -920,7 +918,7 @@
     impl_synom!(ItemUnion "union item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
-        union_: syn!(Union) >>
+        union_: keyword!(union) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         where_clause: syn!(WhereClause) >>
@@ -943,10 +941,10 @@
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
         unsafety: syn!(Unsafety) >>
-        trait_: syn!(Trait) >>
+        trait_: keyword!(trait) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
-        colon: option!(syn!(Colon)) >>
+        colon: option!(punct!(:)) >>
         bounds: cond!(colon.is_some(),
             call!(Delimited::parse_separated_nonempty)
         ) >>
@@ -972,10 +970,10 @@
     impl_synom!(ItemDefaultImpl "default impl item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         unsafety: syn!(Unsafety) >>
-        impl_: syn!(Impl) >>
+        impl_: keyword!(impl) >>
         path: syn!(Path) >>
-        for_: syn!(For) >>
-        dot2: syn!(Dot2) >>
+        for_: keyword!(for) >>
+        dot2: punct!(..) >>
         braces: braces!(epsilon!()) >>
         (ItemDefaultImpl {
             attrs: attrs,
@@ -1000,12 +998,12 @@
 
     impl_synom!(TraitItemConst "const trait item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
-        const_: syn!(Const) >>
+        const_: keyword!(const) >>
         ident: syn!(Ident) >>
-        colon: syn!(Colon) >>
+        colon: punct!(:) >>
         ty: syn!(Ty) >>
-        default: option!(tuple!(syn!(Eq), syn!(Expr))) >>
-        semi: syn!(Semi) >>
+        default: option!(tuple!(punct!(=), syn!(Expr))) >>
+        semi: punct!(;) >>
         (TraitItemConst {
             attrs: attrs,
             const_token: const_,
@@ -1022,7 +1020,7 @@
         constness: syn!(Constness) >>
         unsafety: syn!(Unsafety) >>
         abi: option!(syn!(Abi)) >>
-        fn_: syn!(Fn_) >>
+        fn_: keyword!(fn) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         inputs: parens!(call!(Delimited::parse_terminated)) >>
@@ -1032,7 +1030,7 @@
             tuple!(many0!(call!(Attribute::parse_inner)),
                    call!(Block::parse_within))
         )) >>
-        semi: cond!(body.is_none(), syn!(Semi)) >>
+        semi: cond!(body.is_none(), punct!(;)) >>
         ({
             let (inner_attrs, stmts) = match body {
                 Some(((inner_attrs, stmts), b)) => (inner_attrs, Some((stmts, b))),
@@ -1075,14 +1073,14 @@
 
     impl_synom!(TraitItemType "trait item type" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
-        type_: syn!(Type) >>
+        type_: keyword!(type) >>
         ident: syn!(Ident) >>
-        colon: option!(syn!(Colon)) >>
+        colon: option!(punct!(:)) >>
         bounds: cond!(colon.is_some(),
             call!(Delimited::parse_separated_nonempty)
         ) >>
-        default: option!(tuple!(syn!(Eq), syn!(Ty))) >>
-        semi: syn!(Semi) >>
+        default: option!(tuple!(punct!(=), syn!(Ty))) >>
+        semi: punct!(;) >>
         (TraitItemType {
             attrs: attrs,
             type_token: type_,
@@ -1097,7 +1095,7 @@
     impl_synom!(TraitItemMacro "trait item macro" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         mac: syn!(Macro) >>
-        cond!(!mac.is_braced(), syn!(Semi)) >>
+        cond!(!mac.is_braced(), punct!(;)) >>
         (TraitItemMacro {
             attrs: attrs,
             mac: mac,
@@ -1108,13 +1106,13 @@
         attrs: many0!(call!(Attribute::parse_outer)) >>
         defaultness: syn!(Defaultness) >>
         unsafety: syn!(Unsafety) >>
-        impl_: syn!(Impl) >>
+        impl_: keyword!(impl) >>
         generics: syn!(Generics) >>
         polarity_path: alt!(
             do_parse!(
                 polarity: syn!(ImplPolarity) >>
                 path: syn!(Path) >>
-                for_: syn!(For) >>
+                for_: keyword!(for) >>
                 (Some((polarity, path, for_)))
             )
             |
@@ -1153,13 +1151,13 @@
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
         defaultness: syn!(Defaultness) >>
-        const_: syn!(Const) >>
+        const_: keyword!(const) >>
         ident: syn!(Ident) >>
-        colon: syn!(Colon) >>
+        colon: punct!(:) >>
         ty: syn!(Ty) >>
-        eq: syn!(Eq) >>
+        eq: punct!(=) >>
         value: syn!(Expr) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ImplItemConst {
             attrs: attrs,
             vis: vis,
@@ -1181,7 +1179,7 @@
         constness: syn!(Constness) >>
         unsafety: syn!(Unsafety) >>
         abi: option!(syn!(Abi)) >>
-        fn_: syn!(Fn_) >>
+        fn_: keyword!(fn) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
         inputs: parens!(call!(Delimited::parse_terminated)) >>
@@ -1228,11 +1226,11 @@
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
         defaultness: syn!(Defaultness) >>
-        type_: syn!(Type) >>
+        type_: keyword!(type) >>
         ident: syn!(Ident) >>
-        eq: syn!(Eq) >>
+        eq: punct!(=) >>
         ty: syn!(Ty) >>
-        semi: syn!(Semi) >>
+        semi: punct!(;) >>
         (ImplItemType {
             attrs: attrs,
             vis: vis,
@@ -1248,7 +1246,7 @@
     impl_synom!(ImplItemMacro "macro in impl block" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         mac: syn!(Macro) >>
-        cond!(!mac.is_braced(), syn!(Semi)) >>
+        cond!(!mac.is_braced(), punct!(;)) >>
         (ImplItemMacro {
             attrs: attrs,
             mac: mac,
@@ -1257,7 +1255,7 @@
 
     impl Synom for ImplPolarity {
         named!(parse -> Self, alt!(
-            syn!(Bang) => { ImplPolarity::Negative }
+            punct!(!) => { ImplPolarity::Negative }
             |
             epsilon!() => { |_| ImplPolarity::Positive }
         ));
@@ -1265,7 +1263,7 @@
 
     impl Synom for Constness {
         named!(parse -> Self, alt!(
-            syn!(Const) => { Constness::Const }
+            keyword!(const) => { Constness::Const }
             |
             epsilon!() => { |_| Constness::NotConst }
         ));
@@ -1273,7 +1271,7 @@
 
     impl Synom for Defaultness {
         named!(parse -> Self, alt!(
-            syn!(Default_) => { Defaultness::Default }
+            keyword!(default) => { Defaultness::Default }
             |
             epsilon!() => { |_| Defaultness::Final }
         ));
@@ -1509,7 +1507,7 @@
             self.ident.to_tokens(tokens);
             tokens.append_all(&self.mac.tokens);
             if !self.mac.is_braced() {
-                tokens::Semi::default().to_tokens(tokens);
+                <Token![;]>::default().to_tokens(tokens);
             }
         }
     }
@@ -1609,7 +1607,7 @@
             tokens.append_all(self.attrs.outer());
             self.mac.to_tokens(tokens);
             if !self.mac.is_braced() {
-                tokens::Semi::default().to_tokens(tokens);
+                <Token![;]>::default().to_tokens(tokens);
             }
         }
     }
@@ -1661,7 +1659,7 @@
             self.mac.to_tokens(tokens);
             if !self.mac.is_braced() {
                 // FIXME needs a span
-                tokens::Semi::default().to_tokens(tokens);
+                <Token![;]>::default().to_tokens(tokens);
             }
         }
     }
@@ -1709,7 +1707,7 @@
 
                 if self.0.variadic {
                     if !self.0.inputs.empty_or_trailing() {
-                        tokens::Comma::default().to_tokens(tokens);
+                        <Token![,]>::default().to_tokens(tokens);
                     }
                     TokensOrDefault(&self.0.dot_tokens).to_tokens(tokens);
                 }
diff --git a/src/lib.rs b/src/lib.rs
index 5e86bc4..5c246cc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,7 +9,7 @@
 #[cfg(any(feature = "printing", feature = "parsing"))]
 extern crate quote;
 
-#[cfg_attr(feature = "parsing", macro_use)]
+#[macro_use]
 extern crate synom;
 
 #[macro_use]
diff --git a/src/mac.rs b/src/mac.rs
index 4e59bc9..234969a 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -11,7 +11,7 @@
     /// of the macro invocation.
     pub struct Macro {
         pub path: Path,
-        pub bang_token: tokens::Bang,
+        pub bang_token: Token![!],
         pub tokens: Vec<TokenTree>,
     }
 }
@@ -133,13 +133,12 @@
     use super::*;
 
     use proc_macro2::{TokenNode, TokenTree};
-    use synom::tokens::*;
     use synom::{Synom, PResult, Cursor, parse_error};
 
     impl Synom for Macro {
         named!(parse -> Self, do_parse!(
             what: syn!(Path) >>
-            bang: syn!(Bang) >>
+            bang: punct!(!) >>
             body: call!(::TokenTree::parse_delimited) >>
             (Macro {
                 path: what,
diff --git a/src/op.rs b/src/op.rs
index a044359..b5a86cc 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -1,64 +1,62 @@
-use tokens;
-
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum BinOp {
         /// The `+` operator (addition)
-        Add(tokens::Add),
+        Add(Token![+]),
         /// The `-` operator (subtraction)
-        Sub(tokens::Sub),
+        Sub(Token![-]),
         /// The `*` operator (multiplication)
-        Mul(tokens::Star),
+        Mul(Token![*]),
         /// The `/` operator (division)
-        Div(tokens::Div),
+        Div(Token![/]),
         /// The `%` operator (modulus)
-        Rem(tokens::Rem),
+        Rem(Token![%]),
         /// The `&&` operator (logical and)
-        And(tokens::AndAnd),
+        And(Token![&&]),
         /// The `||` operator (logical or)
-        Or(tokens::OrOr),
+        Or(Token![||]),
         /// The `^` operator (bitwise xor)
-        BitXor(tokens::Caret),
+        BitXor(Token![^]),
         /// The `&` operator (bitwise and)
-        BitAnd(tokens::And),
+        BitAnd(Token![&]),
         /// The `|` operator (bitwise or)
-        BitOr(tokens::Or),
+        BitOr(Token![|]),
         /// The `<<` operator (shift left)
-        Shl(tokens::Shl),
+        Shl(Token![<<]),
         /// The `>>` operator (shift right)
-        Shr(tokens::Shr),
+        Shr(Token![>>]),
         /// The `==` operator (equality)
-        Eq(tokens::EqEq),
+        Eq(Token![==]),
         /// The `<` operator (less than)
-        Lt(tokens::Lt),
+        Lt(Token![<]),
         /// The `<=` operator (less than or equal to)
-        Le(tokens::Le),
+        Le(Token![<=]),
         /// The `!=` operator (not equal to)
-        Ne(tokens::Ne),
+        Ne(Token![!=]),
         /// The `>=` operator (greater than or equal to)
-        Ge(tokens::Ge),
+        Ge(Token![>=]),
         /// The `>` operator (greater than)
-        Gt(tokens::Gt),
+        Gt(Token![>]),
         /// The `+=` operator
-        AddEq(tokens::AddEq),
+        AddEq(Token![+=]),
         /// The `-=` operator
-        SubEq(tokens::SubEq),
+        SubEq(Token![-=]),
         /// The `*=` operator
-        MulEq(tokens::MulEq),
+        MulEq(Token![*=]),
         /// The `/=` operator
-        DivEq(tokens::DivEq),
+        DivEq(Token![/=]),
         /// The `%=` operator
-        RemEq(tokens::RemEq),
+        RemEq(Token![%=]),
         /// The `^=` operator
-        BitXorEq(tokens::CaretEq),
+        BitXorEq(Token![^=]),
         /// The `&=` operator
-        BitAndEq(tokens::AndEq),
+        BitAndEq(Token![&=]),
         /// The `|=` operator
-        BitOrEq(tokens::OrEq),
+        BitOrEq(Token![|=]),
         /// The `<<=` operator
-        ShlEq(tokens::ShlEq),
+        ShlEq(Token![<<=]),
         /// The `>>=` operator
-        ShrEq(tokens::ShrEq),
+        ShrEq(Token![>>=]),
     }
 }
 
@@ -66,11 +64,11 @@
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum UnOp {
         /// The `*` operator for dereferencing
-        Deref(tokens::Star),
+        Deref(Token![*]),
         /// The `!` operator for logical inversion
-        Not(tokens::Bang),
+        Not(Token![!]),
         /// The `-` operator for negation
-        Neg(tokens::Sub),
+        Neg(Token![-]),
     }
 }
 
@@ -78,78 +76,77 @@
 pub mod parsing {
     use super::*;
     use synom::Synom;
-    use synom::tokens::*;
 
     impl BinOp {
         named!(pub parse_binop -> Self, alt!(
-            syn!(AndAnd) => { BinOp::And }
+            punct!(&&) => { BinOp::And }
             |
-            syn!(OrOr) => { BinOp::Or }
+            punct!(||) => { BinOp::Or }
             |
-            syn!(Shl) => { BinOp::Shl }
+            punct!(<<) => { BinOp::Shl }
             |
-            syn!(Shr) => { BinOp::Shr }
+            punct!(>>) => { BinOp::Shr }
             |
-            syn!(EqEq) => { BinOp::Eq }
+            punct!(==) => { BinOp::Eq }
             |
-            syn!(Le) => { BinOp::Le }
+            punct!(<=) => { BinOp::Le }
             |
-            syn!(Ne) => { BinOp::Ne }
+            punct!(!=) => { BinOp::Ne }
             |
-            syn!(Ge) => { BinOp::Ge }
+            punct!(>=) => { BinOp::Ge }
             |
-            syn!(Add) => { BinOp::Add }
+            punct!(+) => { BinOp::Add }
             |
-            syn!(Sub) => { BinOp::Sub }
+            punct!(-) => { BinOp::Sub }
             |
-            syn!(Star) => { BinOp::Mul }
+            punct!(*) => { BinOp::Mul }
             |
-            syn!(Div) => { BinOp::Div }
+            punct!(/) => { BinOp::Div }
             |
-            syn!(Rem) => { BinOp::Rem }
+            punct!(%) => { BinOp::Rem }
             |
-            syn!(Caret) => { BinOp::BitXor }
+            punct!(^) => { BinOp::BitXor }
             |
-            syn!(And) => { BinOp::BitAnd }
+            punct!(&) => { BinOp::BitAnd }
             |
-            syn!(Or) => { BinOp::BitOr }
+            punct!(|) => { BinOp::BitOr }
             |
-            syn!(Lt) => { BinOp::Lt }
+            punct!(<) => { BinOp::Lt }
             |
-            syn!(Gt) => { BinOp::Gt }
+            punct!(>) => { BinOp::Gt }
         ));
 
         #[cfg(feature = "full")]
         named!(pub parse_assign_op -> Self, alt!(
-            syn!(AddEq) => { BinOp::AddEq }
+            punct!(+=) => { BinOp::AddEq }
             |
-            syn!(SubEq) => { BinOp::SubEq }
+            punct!(-=) => { BinOp::SubEq }
             |
-            syn!(MulEq) => { BinOp::MulEq }
+            punct!(*=) => { BinOp::MulEq }
             |
-            syn!(DivEq) => { BinOp::DivEq }
+            punct!(/=) => { BinOp::DivEq }
             |
-            syn!(RemEq) => { BinOp::RemEq }
+            punct!(%=) => { BinOp::RemEq }
             |
-            syn!(CaretEq) => { BinOp::BitXorEq }
+            punct!(^=) => { BinOp::BitXorEq }
             |
-            syn!(AndEq) => { BinOp::BitAndEq }
+            punct!(&=) => { BinOp::BitAndEq }
             |
-            syn!(OrEq) => { BinOp::BitOrEq }
+            punct!(|=) => { BinOp::BitOrEq }
             |
-            syn!(ShlEq) => { BinOp::ShlEq }
+            punct!(<<=) => { BinOp::ShlEq }
             |
-            syn!(ShrEq) => { BinOp::ShrEq }
+            punct!(>>=) => { BinOp::ShrEq }
         ));
     }
 
     impl Synom for UnOp {
         named!(parse -> Self, alt!(
-            syn!(Star) => { UnOp::Deref }
+            punct!(*) => { UnOp::Deref }
             |
-            syn!(Bang) => { UnOp::Not }
+            punct!(!) => { UnOp::Not }
             |
-            syn!(Sub) => { UnOp::Neg }
+            punct!(-) => { UnOp::Neg }
         ));
     }
 }
diff --git a/src/ty.rs b/src/ty.rs
index d5987f2..3321176 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -13,18 +13,18 @@
         pub Array(TyArray {
             pub bracket_token: tokens::Bracket,
             pub ty: Box<Ty>,
-            pub semi_token: tokens::Semi,
+            pub semi_token: Token![;],
             pub amt: Expr,
         }),
         /// A raw pointer (`*const T` or `*mut T`)
         pub Ptr(TyPtr {
-            pub star_token: tokens::Star,
-            pub const_token: Option<tokens::Const>,
+            pub star_token: Token![*],
+            pub const_token: Option<Token![const]>,
             pub ty: Box<MutTy>,
         }),
         /// A reference (`&'a T` or `&'a mut T`)
         pub Rptr(TyRptr {
-            pub and_token: tokens::And,
+            pub and_token: Token![&],
             pub lifetime: Option<Lifetime>,
             pub ty: Box<MutTy>,
         }),
@@ -34,13 +34,13 @@
         }),
         /// The never type (`!`)
         pub Never(TyNever {
-            pub bang_token: tokens::Bang,
+            pub bang_token: Token![!],
         }),
         /// A tuple (`(A, B, C, D, ...)`)
         pub Tup(TyTup {
             pub paren_token: tokens::Paren,
-            pub tys: Delimited<Ty, tokens::Comma>,
-            pub lone_comma: Option<tokens::Comma>,
+            pub tys: Delimited<Ty, Token![,]>,
+            pub lone_comma: Option<Token![,]>,
         }),
         /// A path (`module::module::...::Type`), optionally
         /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
@@ -53,13 +53,13 @@
         /// A trait object type `Bound1 + Bound2 + Bound3`
         /// where `Bound` is a trait or a lifetime.
         pub TraitObject(TyTraitObject {
-            pub bounds: Delimited<TyParamBound, tokens::Add>,
+            pub bounds: Delimited<TyParamBound, Token![+]>,
         }),
         /// An `impl Bound1 + Bound2 + Bound3` type
         /// where `Bound` is a trait or a lifetime.
         pub ImplTrait(TyImplTrait {
-            pub impl_token: tokens::Impl,
-            pub bounds: Delimited<TyParamBound, tokens::Add>,
+            pub impl_token: Token![impl],
+            pub bounds: Delimited<TyParamBound, Token![+]>,
         }),
         /// No-op; kept solely so that we can pretty-print faithfully
         pub Paren(TyParen {
@@ -74,7 +74,7 @@
         /// TyKind::Infer means the type should be inferred instead of it having been
         /// specified. This can appear anywhere in a type.
         pub Infer(TyInfer {
-            pub underscore_token: tokens::Underscore
+            pub underscore_token: Token![_],
         }),
         /// A macro in the type position.
         pub Macro(Macro),
@@ -91,7 +91,7 @@
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum Mutability {
-        Mutable(tokens::Mut),
+        Mutable(Token![mut]),
         Immutable,
     }
 }
@@ -106,9 +106,9 @@
     pub struct Path {
         /// A `::foo` path, is relative to the crate root rather than current
         /// module (like paths in an import).
-        pub leading_colon: Option<tokens::Colon2>,
+        pub leading_colon: Option<Token![::]>,
         /// The segments in the path: the things separated by `::`.
-        pub segments: Delimited<PathSegment, tokens::Colon2>,
+        pub segments: Delimited<PathSegment, Token![::]>,
     }
 }
 
@@ -196,17 +196,17 @@
 ast_struct! {
     /// A path like `Foo<'a, T>`
     pub struct AngleBracketedParameterData {
-        pub turbofish: Option<tokens::Colon2>,
-        pub lt_token: tokens::Lt,
+        pub turbofish: Option<Token![::]>,
+        pub lt_token: Token![<],
         /// The lifetime parameters for this path segment.
-        pub lifetimes: Delimited<Lifetime, tokens::Comma>,
+        pub lifetimes: Delimited<Lifetime, Token![,]>,
         /// The type parameters for this path segment, if present.
-        pub types: Delimited<Ty, tokens::Comma>,
+        pub types: Delimited<Ty, Token![,]>,
         /// Bindings (equality constraints) on associated types, if present.
         ///
         /// E.g., `Foo<A=Bar>`.
-        pub bindings: Delimited<TypeBinding, tokens::Comma>,
-        pub gt_token: tokens::Gt,
+        pub bindings: Delimited<TypeBinding, Token![,]>,
+        pub gt_token: Token![>],
     }
 }
 
@@ -214,7 +214,7 @@
     /// Bind a type to an associated type: `A=Foo`.
     pub struct TypeBinding {
         pub ident: Ident,
-        pub eq_token: tokens::Eq,
+        pub eq_token: Token![=],
         pub ty: Ty,
     }
 }
@@ -225,7 +225,7 @@
     pub struct ParenthesizedParameterData {
         pub paren_token: tokens::Paren,
         /// `(A, B)`
-        pub inputs: Delimited<Ty, tokens::Comma>,
+        pub inputs: Delimited<Ty, Token![,]>,
         /// `C`
         pub output: ReturnType,
     }
@@ -256,11 +256,11 @@
     ///  ty       position = 0
     /// ```
     pub struct QSelf {
-        pub lt_token: tokens::Lt,
+        pub lt_token: Token![<],
         pub ty: Box<Ty>,
         pub position: usize,
-        pub as_token: Option<tokens::As>,
-        pub gt_token: tokens::Gt,
+        pub as_token: Option<Token![as]>,
+        pub gt_token: Token![>],
     }
 }
 
@@ -269,10 +269,10 @@
         pub lifetimes: Option<BoundLifetimes>,
         pub unsafety: Unsafety,
         pub abi: Option<Abi>,
-        pub fn_token: tokens::Fn_,
+        pub fn_token: Token![fn],
         pub paren_token: tokens::Paren,
-        pub inputs: Delimited<BareFnArg, tokens::Comma>,
-        pub variadic: Option<tokens::Dot3>,
+        pub inputs: Delimited<BareFnArg, Token![,]>,
+        pub variadic: Option<Token![...]>,
         pub output: ReturnType,
     }
 }
@@ -280,14 +280,14 @@
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum Unsafety {
-        Unsafe(tokens::Unsafe),
+        Unsafe(Token![unsafe]),
         Normal,
     }
 }
 
 ast_struct! {
     pub struct Abi {
-        pub extern_token: tokens::Extern,
+        pub extern_token: Token![extern],
         pub kind: AbiKind,
     }
 }
@@ -304,7 +304,7 @@
     ///
     /// E.g. `bar: usize` as in `fn foo(bar: usize)`
     pub struct BareFnArg {
-        pub name: Option<(BareFnArgName, tokens::Colon)>,
+        pub name: Option<(BareFnArgName, Token![:])>,
         pub ty: Ty,
     }
 }
@@ -315,7 +315,7 @@
         /// Argument with the provided name
         Named(Ident),
         /// Argument matched with `_`
-        Wild(tokens::Underscore),
+        Wild(Token![_]),
     }
 }
 
@@ -328,7 +328,7 @@
         /// type would be inserted.
         Default,
         /// Everything else
-        Ty(Ty, tokens::RArrow),
+        Ty(Ty, Token![->]),
     }
 }
 
@@ -336,7 +336,6 @@
 pub mod parsing {
     use super::*;
     use synom::Synom;
-    use synom::tokens::*;
 
     impl Synom for Ty {
         named!(parse -> Self, call!(ambig_ty, true));
@@ -403,7 +402,7 @@
         named!(parse -> Self, map!(
             brackets!(do_parse!(
                 elem: syn!(Ty) >>
-                    semi: syn!(Semi) >>
+                    semi: punct!(;) >>
                     len: syn!(Expr) >>
                     (elem, semi, len)
             )),
@@ -420,11 +419,11 @@
 
     impl Synom for TyPtr {
         named!(parse -> Self, do_parse!(
-            star: syn!(Star) >>
+            star: punct!(*) >>
             mutability: alt!(
-                syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
+                keyword!(const) => { |c| (Mutability::Immutable, Some(c)) }
                 |
-                syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
+                keyword!(mut) => { |m| (Mutability::Mutable(m), None) }
             ) >>
             target: call!(Ty::without_plus) >>
             (TyPtr {
@@ -440,7 +439,7 @@
 
     impl Synom for TyRptr {
         named!(parse -> Self, do_parse!(
-            amp: syn!(And) >>
+            amp: punct!(&) >>
             life: option!(syn!(Lifetime)) >>
             mutability: syn!(Mutability) >>
             // & binds tighter than +, so we don't allow + here.
@@ -461,11 +460,11 @@
             lifetimes: option!(syn!(BoundLifetimes)) >>
             unsafety: syn!(Unsafety) >>
             abi: option!(syn!(Abi)) >>
-            fn_: syn!(Fn_) >>
+            fn_: keyword!(fn) >>
             parens: parens!(do_parse!(
                 inputs: call!(Delimited::parse_terminated) >>
                 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
-                                                syn!(Dot3))) >>
+                                                punct!(...))) >>
                 (inputs, variadic)
             )) >>
             output: syn!(ReturnType) >>
@@ -486,14 +485,14 @@
 
     impl Synom for TyNever {
         named!(parse -> Self, map!(
-            syn!(Bang),
+            punct!(!),
             |b| TyNever { bang_token: b }
         ));
     }
 
     impl Synom for TyInfer {
         named!(parse -> Self, map!(
-            syn!(Underscore),
+            punct!(_),
             |u| TyInfer { underscore_token: u }
         ));
     }
@@ -519,7 +518,7 @@
         bounds: alt!(
             cond_reduce!(
                 allow_plus,
-                many0!(tuple!(syn!(Add), syn!(TyParamBound)))
+                many0!(tuple!(punct!(+), syn!(TyParamBound)))
             )
             |
             value!(vec![])
@@ -555,15 +554,15 @@
         map!(syn!(Path), |p| (None, p))
         |
         do_parse!(
-            lt: syn!(Lt) >>
+            lt: punct!(<) >>
             this: syn!(Ty) >>
             path: option!(do_parse!(
-                as_: syn!(As) >>
+                as_: keyword!(as) >>
                 path: syn!(Path) >>
                 (as_, path)
             )) >>
-            gt: syn!(Gt) >>
-            colon2: syn!(Colon2) >>
+            gt: punct!(>) >>
+            colon2: punct!(::) >>
             rest: call!(Delimited::parse_separated_nonempty) >>
             ({
                 let (pos, as_, path) = match path {
@@ -594,7 +593,7 @@
             })
         )
         |
-        map!(syn!(Self_), |s| (None, s.into()))
+        map!(keyword!(self), |s| (None, s.into()))
     ));
 
     impl Synom for ParenthesizedParameterData {
@@ -612,7 +611,7 @@
     impl Synom for ReturnType {
         named!(parse -> Self, alt!(
             do_parse!(
-                arrow: syn!(RArrow) >>
+                arrow: punct!(->) >>
                 ty: syn!(Ty) >>
                 (ReturnType::Ty(ty, arrow))
             )
@@ -634,7 +633,7 @@
 
     impl Synom for TyImplTrait {
         named!(parse -> Self, do_parse!(
-            impl_: syn!(Impl) >>
+            impl_: keyword!(impl) >>
             // NOTE: rust-lang/rust#34511 includes discussion about whether or
             // not + should be allowed in ImplTrait directly without ().
             elem: call!(Delimited::parse_separated_nonempty) >>
@@ -667,7 +666,7 @@
 
     impl Synom for Mutability {
         named!(parse -> Self, alt!(
-            syn!(Mut) => { Mutability::Mutable }
+            keyword!(mut) => { Mutability::Mutable }
             |
             epsilon!() => { |_| Mutability::Immutable }
         ));
@@ -675,7 +674,7 @@
 
     impl Synom for Path {
         named!(parse -> Self, do_parse!(
-            colon: option!(syn!(Colon2)) >>
+            colon: option!(punct!(::)) >>
             segments: call!(Delimited::parse_separated_nonempty) >>
             (Path {
                 leading_colon: colon,
@@ -692,8 +691,8 @@
         named!(parse -> Self, alt!(
             do_parse!(
                 ident: syn!(Ident) >>
-                turbofish: option!(syn!(Colon2)) >>
-                lt: syn!(Lt) >>
+                turbofish: option!(punct!(::)) >>
+                lt: punct!(<) >>
                 lifetimes: call!(Delimited::parse_terminated) >>
                 types: cond!(
                     lifetimes.is_empty() || lifetimes.trailing_delim(),
@@ -707,7 +706,7 @@
                     },
                     call!(Delimited::parse_terminated)
                 ) >>
-                gt: syn!(Gt) >>
+                gt: punct!(>) >>
                 (PathSegment {
                     ident: ident,
                     parameters: PathParameters::AngleBracketed(
@@ -727,11 +726,11 @@
         ));
     }
 
-    named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
+    named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(punct!(=))));
 
     impl Path {
         named!(pub parse_mod_style -> Self, do_parse!(
-            colon: option!(syn!(Colon2)) >>
+            colon: option!(punct!(::)) >>
             segments: call!(Delimited::parse_separated_nonempty_with,
                             mod_style_path_segment) >>
             (Path {
@@ -745,18 +744,18 @@
         map!(syn!(Ident), Into::into)
         |
         alt!(
-            syn!(Super) => { Into::into }
+            keyword!(super) => { Into::into }
             |
-            syn!(Self_) => { Into::into }
+            keyword!(self) => { Into::into }
             |
-            syn!(CapSelf) => { Into::into }
+            keyword!(Self) => { Into::into }
         )
     ));
 
     impl Synom for TypeBinding {
         named!(parse -> Self, do_parse!(
             id: syn!(Ident) >>
-            eq: syn!(Eq) >>
+            eq: punct!(=) >>
             ty: syn!(Ty) >>
             (TypeBinding {
                 ident: id,
@@ -793,8 +792,8 @@
         named!(parse -> Self, do_parse!(
             name: option!(do_parse!(
                 name: syn!(BareFnArgName) >>
-                not!(syn!(Colon2)) >>
-                colon: syn!(Colon) >>
+                not!(punct!(::)) >>
+                colon: punct!(:) >>
                 (name, colon)
             )) >>
             ty: syn!(Ty) >>
@@ -809,13 +808,13 @@
         named!(parse -> Self, alt!(
             map!(syn!(Ident), BareFnArgName::Named)
             |
-            map!(syn!(Underscore), BareFnArgName::Wild)
+            map!(punct!(_), BareFnArgName::Wild)
         ));
     }
 
     impl Synom for Unsafety {
         named!(parse -> Self, alt!(
-            syn!(Unsafe) => { Unsafety::Unsafe }
+            keyword!(unsafe) => { Unsafety::Unsafe }
             |
             epsilon!() => { |_| Unsafety::Normal }
         ));
@@ -823,7 +822,7 @@
 
     impl Synom for Abi {
         named!(parse -> Self, do_parse!(
-            extern_: syn!(Extern) >>
+            extern_: keyword!(extern) >>
             // TODO: this parses all literals, not just strings
             name: option!(syn!(Lit)) >>
             (Abi {
@@ -1025,7 +1024,7 @@
             self.lt_token.to_tokens(tokens);
             self.lifetimes.to_tokens(tokens);
             if !self.lifetimes.empty_or_trailing() && !self.types.is_empty() {
-                tokens::Comma::default().to_tokens(tokens);
+                <Token![,]>::default().to_tokens(tokens);
             }
             self.types.to_tokens(tokens);
             if (
@@ -1037,7 +1036,7 @@
                 // We have some bindings, then we need a comma.
                 !self.bindings.is_empty()
             {
-                tokens::Comma::default().to_tokens(tokens);
+                <Token![,]>::default().to_tokens(tokens);
             }
             self.bindings.to_tokens(tokens);
             self.gt_token.to_tokens(tokens);
@@ -1089,7 +1088,7 @@
             self.paren_token.surround(tokens, |tokens| {
                 self.inputs.to_tokens(tokens);
                 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
-                    tokens::Comma::default().to_tokens(tokens);
+                    <Token![,]>::default().to_tokens(tokens);
                 }
                 self.variadic.to_tokens(tokens);
             });