問題タブ [rust-macros]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
244 参照

rust - 手続き型マクロなしでアトリビュートで「マクロを行う」方法はありますか?

具体的には、マクロ出力をドキュメント コメントに入れようとしています。これがまさに私が望むことをすることに興奮しました:

次のステップは、その文字列を自分のコンテンツに置き換えることです。thisによると、私は書くことができず#[doc=my_content!()]、属性マクロは手続き型であるため、そのために別のクレートが必要であり、さらに(私は思うに)手続き型マクロ機能を必要とせずにコンテンツを生成できました。

何らかの方法で「従来のマクロ」でこれを行う方法はありますか、それとも運が悪いのでしょうか?

0 投票する
1 に答える
1670 参照

rust - 再帰的なmacro_rulesでサブパターンを展開するには?

enum型付き変数のネストされた構造をコンパイル時のテンプレートに簡単に一致させるマクロを作成しています。Rust のパターン マッチングを利用して、構造の特定の場所に特定の値を強制するか、変数を他の興味深い場所にバインドするという考え方です。私の実装では基本的な考え方は機能しますが、ネストされたパターンでは機能しません。問題は、マクロ入力の一部が解析される$<name>:patと、後で として解析できないことだと思います$<name>:tt

パターンという用語のあいまいな使用を避けるために、Rust のドキュメントに従って次の表記法を使用します。

  • パターンmatchアームやステートメントに現れるものでif letあり、フラグメント指定子によってマクロで照合されます$<name>:pat
  • マッチャーは、マクロ内の構文規則の左側です。
  • テンプレートは、マクロの展開方法を決定するマクロへの入力の一部です。

遊び場MCVE

enumこれは、私が使用しているタイプの簡略版です。

たとえば、次の式

このマクロ呼び出しによって一致する可能性があります。

ここで、一致が成功すると、識別子namebodyは の対応するサブ要素にバインドさexpressionれ、マクロの 2 番目の引数として渡されるブロック内の変数として使用できるようになります。

これは、上記のマクロを作成するための私の努力です:

ネストされていないテンプレートでは期待どおりに機能し、ネストされたテンプレートではマクロ呼び出しを手動でネストできます。ただし、1 回のマクロ呼び出しでネストされたテンプレートを直接指定すると、コンパイル エラーで失敗します。

遊び場MCVE

[Str(name), _, _]エラーは、型の不一致を引き起こす 3 番目のマクロ ルールによって受け入れられる単一のスライス パターンとして一致すると言っていると思われます。ただし、2 番目のルールで一連のパターンに分解できるように、トークン ツリーにしたいと考えています。

2 番目のルールを に変更しようとしました($exp:expr, $action:block, [$first:tt, $($rest:tt)*]) =>が、これによりエラーが外側のレベルで発生するだけです。

このようなテンプレートを再帰的に展開できるようにするには、マクロにどのような変更が必要ですか?

(私は明示的にパターンで識別子をバインドしたいので、Rust で一致アームを解析するための再帰マクロのようにトークンをむしゃむしゃにすることはここでは機能しないと思います。)

seqこれは、マクロ呼び出しが展開されることを期待するものです (簡潔にするために不一致の分岐を無視します。さらに、変数を後置することでマクロの衛生状態をシミュレートしました):

完全な展開は少し冗長ですが、このわずかに短縮されたバージョンは、何が起こるべきかの本質を捉えています:

最後に、再帰的展開の個々のステップを示す別のプレイグラウンド リンクを次に示します。とても濃いです。