我正在尝试编写一个 proc 宏
block!
,它使用 syn
板条箱解析模糊类似于 jsx/rsx 的语法。
以下内容应解析为一个块 "wrapper"
,其中包含两个子块 "text_1"
和 "text_2"
:
let block = block! {
<"wrapper">
<"text_1">("hello")
<"text_2">("world")
};
在实现
input.parse::<syn::Token![]>()
时使用 syn::parse
我可以解析一切。
但是有一件事我找不到解决方案:我想强制执行wrapper-children关系的代码风格,这样如果嵌套了某个块,它之前必须有双倍空格或制表符例如。
// -- Good --
let block = block! {
<"text_1">("hello")
<"text_2">("world")
};
// -- Good --
let block = block! {
<"wrapper">
<"text_1">("hello")
<"text_2">("world")
};
// -- Bad --
// Need spaces/tabs before the children tags
let block = block! {
<"wrapper">
<"text_1">("hello")
<"text_2">("world")
};
通过
TokenStream
、Token![<]
、parse::<LitStr>()
、Token![>]
和 parenthesized!
解析 bracketed!
不会强制执行预期规则,但我在 syn
文档中找不到与解析制表符/空格相关的任何内容.
根据控制台中打印的
TokenStream
来判断 - 它甚至在包装器的>
和第一个孩子的<
之间没有任何内容
Input: TokenStream [
Punct {
ch: '<',
spacing: Alone,
span: #0 bytes(118..119),
},
Literal {
kind: Str,
symbol: "wrapper",
suffix: None,
span: #0 bytes(119..128),
},
Punct {
ch: '>',
spacing: Alone,
span: #0 bytes(128..129),
},
Punct {
ch: '<',
spacing: Alone,
span: #0 bytes(144..145),
},
Literal {
kind: Str,
symbol: "text_1",
suffix: None,
span: #0 bytes(145..153),
},
Punct {
ch: '>',
spacing: Alone,
span: #0 bytes(153..154),
},
关于如何可能有什么建议吗?如果可以的话
这是不可能的。 Proc 宏获取没有空格或注释的标记,它们之前已被删除。
可能的(尽管可能不希望)是获取一个巨大的字符串文字并使用它。字符串保留空格。