私はbrainfuckプログラムを拡張するマクロを実装しようとしています(いくつかの単純なコードから始めた後、すでに解決策を考え出すのに問題がありました: How to parse single tokens in rust macros )。問題は、再帰マッチングのある時点で、最後に一致することは決してないということです:
error: recursion limit reached while expanding the macro `brainfuck`
--> src/lib.rs:119:9
|
119 | brainfuck!(@impl cell; $($all_tokens)*);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
124 | brainfuck!(++++++++++[>+++++++>++++++++++>+++++++++++>+++>+<<<<<-]>++.>>+.---.<---.>>++.<+.++++++++.-------.<+++.>+.>+.>.);
| --------------------------------------------------------------------------------------------------------------------------- in this macro invocation
|
= help: consider adding a `#![recursion_limit="2000"]` attribute to your crate
マクロコードは次のとおりです。
#[macro_export]
macro_rules! brainfuck {
(@impl $var:ident;) => {};
(@impl $var:ident; + $($t:tt)*) => {
$var.inc();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; - $($t:tt)*) => {
$var.dec();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; > $($t:tt)*) => {
$var.next();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; < $($t:tt)*) => {
$var.prev();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; . $($t:tt)*) => {
$var.printVal();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; , $($t:tt)*) => {
$var.getInput();
brainfuck!(@impl $var; $($t)*);
};
(@impl $var:ident; [$($t:tt)*] $($ts:tt)*) => {
while $var.getVal() != 0 {
brainfuck!(@impl $var; $($t)*);
}
brainfuck!(@impl $var; $($ts)*);
};
($($all_tokens:tt)*) => {
let mut cell = CellData::new();
brainfuck!(@impl cell; $($all_tokens)*);
};
}
custom からメソッドを展開することに基づいていますstruct
。完全なコード コンパイルの問題は、このプレイグラウンドで再現できます
私はこのマッチングにあまり自信がありません:
(@impl $var:ident; [$($t:tt)*] $($ts:tt)*) => {
while $var.getVal() != 0 {
brainfuck!(@impl $var; $($t)*);
}
brainfuck!(@impl $var; $($ts)*);
};
[$($t:tt)*] $($ts:tt)*
これは、 で囲まれたコードの部分を、[]
トークンが内部にあるもので、その後にトークンが続くものと一致させると考えました。しかし、それが機能するかどうかはわかりません。
私はしばらくこれを扱ってきましたが、完全に立ち往生しています。どんな種類の助けも大歓迎です。前もって感謝します!