Add parse_token_trees.
Token trees are much simpler than an AST.
This makes them easier to work with when they are sufficient
for the task at hand, such as for example [expanding a procedural macro](
https://github.com/servo/html5ever/pull/217).
diff --git a/src/lib.rs b/src/lib.rs
index f331a0b..f051a78 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -92,7 +92,7 @@
use nom::IResult;
#[cfg(feature = "full")]
- use {expr, item, krate};
+ use {expr, item, krate, mac};
pub fn parse_macro_input(input: &str) -> Result<MacroInput, String> {
unwrap("macro input", macro_input::parsing::macro_input, input)
@@ -125,6 +125,11 @@
unwrap("where clause", generics::parsing::where_clause, input)
}
+ #[cfg(feature = "full")]
+ pub fn parse_token_trees(input: &str) -> Result<Vec<TokenTree>, String> {
+ unwrap("token trees", mac::parsing::token_trees, input)
+ }
+
fn unwrap<T>(name: &'static str,
f: fn(&str) -> IResult<&str, T>,
input: &str)
diff --git a/src/mac.rs b/src/mac.rs
index 6ae0120..56d26f8 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -128,6 +128,12 @@
})
));
+ named!(pub token_trees -> Vec<TokenTree>, do_parse!(
+ tts: many0!(token_tree) >>
+ option!(whitespace) >>
+ (tts)
+ ));
+
named!(pub delimited -> Delimited, alt!(
delimited!(
punct!("("),
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
new file mode 100644
index 0000000..8ec2c2f
--- /dev/null
+++ b/tests/test_token_trees.rs
@@ -0,0 +1,62 @@
+extern crate syn;
+use syn::TokenTree::{self, Token};
+use syn::DelimToken::*;
+use syn::Token::*;
+
+#[test]
+fn test_struct() {
+ let raw = "
+ #[derive(Debug, Clone)]
+ pub struct Item {
+ pub ident: Ident,
+ pub attrs: Vec<Attribute>,
+ }
+ ";
+
+ let expected = vec![
+ Token(Pound),
+ delimited(Bracket, vec![
+ ident("derive"),
+ delimited(Paren, vec![
+ ident("Debug"),
+ Token(Comma),
+ ident("Clone"),
+ ]),
+ ]),
+ ident("pub"),
+ ident("struct"),
+ ident("Item"),
+ delimited(Brace, vec![
+ ident("pub"),
+ ident("ident"),
+ Token(Colon),
+ ident("Ident"),
+ Token(Comma),
+
+ ident("pub"),
+ ident("attrs"),
+ Token(Colon),
+ ident("Vec"),
+ Token(Lt),
+ ident("Attribute"),
+ Token(Gt),
+ Token(Comma),
+ ]),
+ ];
+
+ let result = syn::parse_token_trees(raw).unwrap();
+ if result != expected {
+ panic!("{:#?}\n!=\n{:#?}", result, expected);
+ }
+}
+
+fn delimited(delim: syn::DelimToken, tts: Vec<TokenTree>) -> TokenTree {
+ TokenTree::Delimited(syn::Delimited {
+ delim: delim,
+ tts: tts,
+ })
+}
+
+fn ident(s: &str) -> TokenTree {
+ TokenTree::Token(Ident(syn::Ident::new(s)))
+}