简体   繁体   English

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

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

In L-System notation a pattern would look something like this:在 L-System 符号中,模式看起来像这样:

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

I'm trying to write rust macros to expand these.我正在尝试编写 rust 宏来扩展这些。 So I have something like this:所以我有这样的事情:

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

But it won't let me.但它不会让我。 It says:它说:

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`

Why aren't these allowed after the pat type?为什么在 pat 类型之后不允许这些? What can I match against to get this?我可以匹配什么来获得这个?

I can't use tt because apparently parenthesis aren't allowed for that.我不能使用tt因为显然不允许使用括号。

Tokens fed into a macro_rules macro have been emitted by the Rust lexer; Rust 词法分析器发出了送入macro_rules宏的令牌; the same lexer that is part of the Rust parser.属于 Rust 解析器的同一个词法分析器。 The lexer permits many sequences of tokens that are not valid Rust which, when parsing normal Rust code, would be caught by grammar rules down the pipeline.词法分析器允许许多无效的 Rust 标记序列,在解析正常的 Rust 代码时,这些标记会被管道中的语法规则捕获。 However, the lexer is aware of some level of context, for example it can distinguish things like << (left shift operator) from << (the start of nested type parameters), based on whether it is processing a type or an expression.但是,词法分析器知道某种级别的上下文,例如,它可以根据它是在处理类型还是表达式来区分<< (左移运算符)和<< (嵌套类型参数的开始)之类的内容。

In many cases macros can match token streams that are not valid Rust, but the implementation errs on the side of caution to forbid many combinations that the lexer might happily emit.在许多情况下,宏可以匹配无效的 Rust 令牌流,但实现谨慎地禁止词法分析器可能会愉快地发出的许多组合。 The reason for this is to allow the language developers some flexibility to do things like adding new syntax without breaking existing macros.这样做的原因是允许语言开发人员在不破坏现有宏的情况下灵活地执行诸如添加新语法之类的操作。 The line might seem fairly arbitrary, and is partly due to history - how the language developed and the macros that people published early on - but the line had to be drawn somewhere.这条线可能看起来相当随意,部分原因是历史——语言的发展方式以及人们早期发布的宏——但这条线必须在某处划定。

We are guaranteed forwards-compatibility in macros that ingest valid Rust code (as well as a many that ingest invalid Rust code) for the price of disallowing a lot creative applications.我们保证在摄取有效 Rust 代码的宏(以及许多摄取无效 Rust 代码的宏)中向前兼容,但代价是不允许许多创造性的应用程序。 It's possible for the rules to be gradually relaxed over time, as the language and compiler become more and more stable, but I imagine that will happen slowly, if at all.随着时间的推移,随着语言和编译器变得越来越稳定,规则可能会逐渐放松,但我想这会慢慢发生,如果有的话。

Your macro matches input which is not valid Rust: a pattern never can appear between < and > .您的宏匹配无效 Rust 的输入:模式永远不会出现在<>之间。 Unfortunately, it is also not permitted in macros and you may have to just pick different syntax.不幸的是,它也不允许在宏中使用,您可能只需要选择不同的语法。

Procedural macros have fewer restrictions and could also be an option.程序宏的限制较少,也可以作为一种选择。

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

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