I am using proc macros to parse a given input into a Node tree, for debugging purposes I want to stringify and print the output to see if I am successfully converting to RPN, my current function:
use proc_macro::*;
#[proc_macro]
pub fn symbolic(body: TokenStream) -> TokenStream {
// ---shunting yard---
let mut stack : Vec<TokenTree> = vec![];
let mut que : Vec<TokenTree> = vec![];
for tt in body.into_iter(){
match tt {
TokenTree::Ident(_) => que.push(tt),
TokenTree::Punct(_) => {
while precedence(Some(&tt)) <= precedence(stack.last()){
que.push(stack.pop().unwrap());
}
stack.push(tt)
},
TokenTree::Literal(_) => que.push(tt),
_ => {}
}
}
while let Some(op) = stack.pop() {
que.push(op);
}
println!(stringify!(output_que));
"fn answer() -> u32 { 42 }".parse().unwrap()
}
fn precedence(tt: Option<&TokenTree>) -> usize{
if let Some(TokenTree::Punct(punct)) = tt{
match punct.as_char() {
'^' => 3,
'/' | '*' => 2,
'-' | '+' => 1,
_ => 0
}
} else {
0
}
}
gives me an error
error: proc macro panicked
--> src\main.rs:5:5
|
5 | symbolic!(x^2 + 2*x)
| ^^^^^^^^^^^^^^^^^^^^
|
= help: message: called `Option::unwrap()` on a `None` value
which I do not understand as this should be outputting an empty token stream since TokenStream::new() -> TokenStream { TokenStream(None) }
is this not acceptable, if not I do not understand why. I changed this to the example given in the rust book "fn answer() -> u32 { 42 }".parse().unwrap()
and still the same error so I don't know what?
Your macro doesn't work because you never push anything to stack
but here:
while precedence(&tt) <= precedence(stack.last().unwrap()){
que.push(stack.pop().unwrap());
You unwrap
as if stack.pop
or stack.last
was guaranteed to return Some
.