所以我有我想要調試的以下宏代碼。我已經從Rust Book的「深度」一節中看到它。我將宏中的變量重命名爲更緊密地遵循this後。如何調試宏?
我的目標是讓程序打印出BCT程序的每一行。我很清楚這是非常重要的編譯器。
的唯一錯誤rustc是給我的是:
[email protected]:~/rust/macros$ rustc --pretty expanded src/main.rs -Z unstable-options > src/main.precomp.rs
src/main.rs:151:34: 151:35 error: no rules expected the token `0`
src/main.rs:151 bct!(0, 1, 1, 1, 0, 0, 0; 1, 0);
我可以採取什麼步驟來找出其中的問題是來自宏碁
這裏是我的代碼:
fn main() {
{
// "Bitwise Cyclic Tag" automation through macros
macro_rules! bct {
// cmd 0: 0 ... => ...
(0, $($program:tt),* ; $_head:tt)
=> (bct_p!($($program),*, 0 ;));
(0, $($program:tt),* ; $_head:tt, $($tail:tt),*)
=> (bct_p!($($program),*, 0 ; $($tail),*));
// cmd 1x: 1 ... => 1 ... x
(1, $x:tt, $($program:tt),* ; 1)
=> (bct_p!($($program),*, 1, $x ; 1, $x));
(1, $x:tt, $($program:tt),* ; 1, $($tail:tt),*)
=> (bct_p!($($program),*, 1, $x ; 1, $($tail),*, $x));
// cmd 1x: 0 ... => 0 ...
(1, $x:tt, $($program:tt),* ; $($tail:tt),*)
=> (bct_p!($($program),*, 1, $x ; $($tail),*));
// halt on empty data string
($($program:tt),* ;)
=> (());
}
macro_rules! print_bct {
($x:tt ;)
=> (print!("{}", stringify!($x)));
(; $d:tt)
=> (print!("{}", stringify!($d)));
($x:tt, $($program:tt),* ;)
=> {
print!("{}", stringify!($x));
print_bct!($program ;);
};
($x:tt, $($program:tt),* ; $($data:tt),*)
=> {
print!("{}", stringify!($x));
print_bct!($program ; $data);
};
(; $d:tt, $($data:tt),*)
=> {
print!("{}", stringify!($d));
print_bct!(; $data);
};
}
macro_rules! bct_p {
($($program:tt),* ;)
=> {
print_bct!($($program:tt),* ;);
println!("");
bct!($($program),* ;);
};
($($program:tt),* ; $(data:tt),*)
=> {
print_bct!($($program),* ; $($data),*);
println!("");
bct!($($program),* ; $($data),*);
};
}
// the compiler is going to hate me...
bct!(0, 1, 1, 1, 0, 0, 0; 1, 0);
}
爲什麼宏編譯步驟不會抱怨'$(not_al_variable),*'?在什麼情況下,它會自行生效?另外,不要忘記--pretty擴展的衛生,當宏外部的變量與宏內部的變量具有相同的名稱(至少,這就是我向他解釋的)時,這是很有用的。 – Nashenas
吃一大堆確切的東西可能是有意義的,例如,人們可以用'$(0),*'去掉尾隨零,這隻會匹配'0,0,0'(等等)。這就是說,這似乎相當罕見,這將是非常有用的。 – huon