Closed andylokandy closed 2 years ago
Hi, sorry I missed your issue. I think the problem is that pratt requires one token lookahead. Inside the parser I'm creating a peekable iterator using iter.peekable()
which basically consumes the next token when using peek()
. However, you can also pass in your own peekable iterator directly with the parse_input()
function:
fn main() {
let ast = vec![AST::Nilfix, AST::Nilfix, AST::Nilfix];
let iter = &mut ast.into_iter();
let mut iter = iter.peekable();
println!("{:?}", ExprParser.parse_input(&mut iter, Precedence(0)));
println!("{:?}", iter.collect::<Vec<_>>());
}
This prints
Ok(Nilfix)
[Nilfix, Nilfix]
Perhaps we could update the API to allow doing this more easily. I'm not sure what's the best solution.
We could make it so the parse
function takes ownership of the input iterator and parse_input
only borrows it, but requires passing a peekable iterator.
Thank you! The workaround solved the problem. :wink:
BTW, in my use case, a slice as input may work better than an iterator because I parse the input using nom, which always gives me a Vec
of input elements, and I frequently have to query the precedence of elements, where I have to write PrattParser::<std::iter::Once<_>>::query(&mut ExprParser, &elem)
. I'm not urging anyone to change the API but just giving some information.
Given an input
[Literal(1), Literal(1)]
, the pratt parser is expected to output a single1
and leave the latter1
in the input iterator. But it instead returns a single1
, leaving an empty iterator.Here is a minimal reproducible example:
Once it runs, it prints:
while I'm expecting two
Nilfix
in the iterator.