proc-macro-workshop:seq-1

godme發表於2022-07-05
// This test looks for a function-like macro with the right name to exist. For
// now the test doesn't require any specific code to be generated by the macro,
// so returning an empty TokenStream should be sufficient.
//
// Before moving on to the next test, you'll want some code in your
// implementation to handle parsing the first few tokens of input. The macro
// should expect the input to contain a syn::Ident, Token![in], syn::LitInt,
// Token![..], syn::LitInt.
//
// It is also possible to implement this project without using Syn if you'd
// like, though you will end up writing more code, more tedious code, and more
// explicit error handling than when using Syn as a parsing library.
//
//
// Resources:
//
//   - Parsing in Syn:
//     https://docs.rs/syn/1.0/syn/parse/index.html
//
//   - An example of a function-like procedural macro implemented using Syn:
//     https://github.com/dtolnay/syn/tree/master/examples/lazy-static

use seq::seq;

seq!(N in 0..8 {
    // nothing
});

fn main() {}

還是熟悉的味道,之前我們使用的是syn::DeriveInput,但是實際上我們可以自定義解析結構。
這也是seq中我們需要做的:自定義語法解析。

雖然這一關沒有更多的要求,但是我們還是簡單的抽取一下我們將要解析的結構。

pub(crate) struct SeqParser {
    pub(crate) variable_ident: syn::Ident,
    pub(crate) begin: usize,
    pub(crate) end: usize,
    pub(crate) body: proc_macro2::TokenStream,
}

對照一下測試用例

seq!(N in 0..8 {
    // nothing
});

我們需要解析的幾個部分如下

  • variable_identN
  • in:in
  • begin: 0
  • ..:..
  • end:8
  • {}:{}
  • tokens: nothing

關鍵的資料正如上述結構,後續的使用我們再一一調整。

#[proc_macro]
pub fn seq(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    proc_macro2::TokenStream::new().into()
}

第一關還是熟悉的練手,直接返回結構即可。
具體的解析會在第二關進行。

本作品採用《CC 協議》,轉載必須註明作者和本文連結