Macros to parse parens and brackets
diff --git a/src/group.rs b/src/group.rs
index eb2c4ba..77a9cc6 100644
--- a/src/group.rs
+++ b/src/group.rs
@@ -1,30 +1,84 @@
-use proc_macro2::Delimiter;
+use proc_macro2::{Delimiter, Span};
 
 use error::Result;
 use next::parse::ParseBuffer;
 use token;
 
+pub struct Parens<'a> {
+    pub token: token::Paren,
+    pub content: ParseBuffer<'a>,
+}
+
 pub struct Braces<'a> {
     pub token: token::Brace,
     pub content: ParseBuffer<'a>,
 }
 
+pub struct Brackets<'a> {
+    pub token: token::Bracket,
+    pub content: ParseBuffer<'a>,
+}
+
 impl<'a> ParseBuffer<'a> {
-    // Not public API.
-    #[doc(hidden)]
-    pub fn parse_braces(&self) -> Result<Braces<'a>> {
+    fn parse_group(&self, delimiter: Delimiter) -> Result<(Span, ParseBuffer<'a>)> {
         self.step_cursor(|cursor| {
-            if let Some((content, span, rest)) = cursor.group(Delimiter::Brace) {
-                let braces = Braces {
-                    token: token::Brace(span),
-                    content: ParseBuffer::new(span, cursor.advance(content)),
-                };
-                Ok((braces, rest))
+            if let Some((content, span, rest)) = cursor.group(delimiter) {
+                let content = ParseBuffer::new(span, cursor.advance(content));
+                Ok(((span, content), rest))
             } else {
-                Err(cursor.error("expected curly braces"))
+                let message = match delimiter {
+                    Delimiter::Parenthesis => "expected parentheses",
+                    Delimiter::Brace => "expected curly braces",
+                    Delimiter::Bracket => "expected square brackets",
+                    Delimiter::None => unreachable!(),
+                };
+                Err(cursor.error(message))
             }
         })
     }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_parens(&self) -> Result<Parens<'a>> {
+        self.parse_group(Delimiter::Parenthesis).map(|(span, content)| Parens {
+            token: token::Paren(span),
+            content: content,
+        })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_braces(&self) -> Result<Braces<'a>> {
+        self.parse_group(Delimiter::Brace).map(|(span, content)| Braces {
+            token: token::Brace(span),
+            content: content,
+        })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_brackets(&self) -> Result<Brackets<'a>> {
+        self.parse_group(Delimiter::Bracket).map(|(span, content)| Brackets {
+            token: token::Bracket(span),
+            content: content,
+        })
+    }
+}
+
+/// Parse a set of parentheses and expose their content to subsequent parsers.
+#[macro_export]
+macro_rules! parenthesized {
+    ($content:ident in $cursor:expr) => {
+        match $crate::next::parse::ParseBuffer::parse_parens(&$cursor) {
+            $crate::export::Ok(parens) => {
+                $content = parens.content;
+                parens.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
 }
 
 /// Parse a set of curly braces and expose their content to subsequent parsers.
@@ -89,3 +143,20 @@
         }
     };
 }
+
+/// Parse a set of square brackets and expose their content to subsequent
+/// parsers.
+#[macro_export]
+macro_rules! bracketed {
+    ($content:ident in $cursor:expr) => {
+        match $crate::next::parse::ParseBuffer::parse_brackets(&$cursor) {
+            $crate::export::Ok(brackets) => {
+                $content = brackets.content;
+                brackets.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
+}