繁体   English   中英

为什么不能生锈macro_rules! pat 后跟“<”?

[英]Why cant rust macro_rules! pat be followed by "<"?

在 L-System 符号中,模式看起来像这样:

A(a)<A(x)>B(b, c) if a+b+c < 10 => B(a+b, a+c)A(x+a+b+c)

我正在尝试编写 rust 宏来扩展这些。 所以我有这样的事情:

macro_rules! test {
    ($lc:pat < $a:pat > $rc:pat) => { ... };
}

但它不会让我。 它说:

error: `$a:pat` is followed by `>`, which is not allowed for `pat` fragments
 --> src/main.rs:7:23
  |
7 |     ($lc:pat < $a:pat > $rc:pat) => { log_syntax!($lc); log_syntax!($a); log_syntax!($rc); };
  |                       ^ not allowed after `pat` fragments
  |
  = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`

为什么在 pat 类型之后不允许这些? 我可以匹配什么来获得这个?

我不能使用tt因为显然不允许使用括号。

Rust 词法分析器发出了送入macro_rules宏的令牌; 属于 Rust 解析器的同一个词法分析器。 词法分析器允许许多无效的 Rust 标记序列,在解析正常的 Rust 代码时,这些标记会被管道中的语法规则捕获。 但是,词法分析器知道某种级别的上下文,例如,它可以根据它是在处理类型还是表达式来区分<< (左移运算符)和<< (嵌套类型参数的开始)之类的内容。

在许多情况下,宏可以匹配无效的 Rust 令牌流,但实现谨慎地禁止词法分析器可能会愉快地发出的许多组合。 这样做的原因是允许语言开发人员在不破坏现有宏的情况下灵活地执行诸如添加新语法之类的操作。 这条线可能看起来相当随意,部分原因是历史——语言的发展方式以及人们早期发布的宏——但这条线必须在某处划定。

我们保证在摄取有效 Rust 代码的宏(以及许多摄取无效 Rust 代码的宏)中向前兼容,但代价是不允许许多创造性的应用程序。 随着时间的推移,随着语言和编译器变得越来越稳定,规则可能会逐渐放松,但我想这会慢慢发生,如果有的话。

您的宏匹配无效 Rust 的输入:模式永远不会出现在<>之间。 不幸的是,它也不允许在宏中使用,您可能只需要选择不同的语法。

程序宏的限制较少,也可以作为一种选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM