在 Rust 的 proc_macro 中解析括号内容

4
我正在使用Rust和syn以及proc_macro2构建一个小型HTML解析器。 到目前为止,我已经实现了对常规HTML标签及其属性的解析。 例如:
html!(
 <div>
   <image></image>
 </div>
)

工作

但我也想解析一些JSX风格的代码,就像这样

html!(
 <div>
     {
      (0..3).map(|| html!(<text value="new"></text>))
     } 
 </div>
)

我遇到一个问题,就是无法解析我的macro_code中括号内的代码,我想要得到只有<text></text>元素的Vector

这里有一个playground示例

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d0a899ee52772565d4043fea24d8f21d


嘿,你是如何能够在处理宏中使用 html!(..) 而不是 html! { .. } 的呢?难道处理宏不总是需要用大括号而不是圆括号包裹吗? - balanceglove2
2个回答

3

我终于想出了解决我的问题的答案,并决定分享给其他也在苦苦挣扎的人。

如果您理解宏中表达式的概念,这很容易。在{}之间的整个代码是一个表达式,当返回宏结果时,您可以将其用作标记内的值。

小例子

impl ToTokens for Response {
fn to_tokens(&self, tokens: &mut TokenStream) {
    let expressions: Vec<Expr> = self.expressions.clone();
    let entries: Vec<u16> = self.values.clone();

    //We can now use our saved numbers and expressions in this quote! and return something totally new to the user.
    tokens.extend(quote! {
       {
            let mut data: Vec<u16> = vec!(#(#entries),*);
            let expressions: Vec<Vec<u16>> = vec!(#(#expressions),*);
            for expr in expressions {
                data.extend(expr);
            };
           data.iter().fold(0, |acc, len| acc + len )
       }
    });
}

0
在当前版本的syn crate(2+)中,有一些宏可以帮助解析由符号括起来的组的内容,例如:
  • {} - syn::braced
  • [] - syn::bracketed
  • () - syn::parenthesized
使用起来非常简单,如syn文档示例所示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接