A sequence of atoms has type Vec<char> where char is the underlying parsing atom. The problem is that we would actually prefer to have a value containing the beginning and the end of the stream range. Example: The expression ["0-9"]+ has type Vec<char> but semantic actions are sometimes more efficient if they directly work on the underlying str slice, in this case, building a vector is unnecessary.
Design
Use std::ops::Range from Rust standard library.
Range<Stream> will be created in the generated code and send to the semantic action.
A trait Span will be created for retrieving the span from a range and can be implemented independently for each range stream.
trait Span {
type Output;
fn span(&self) -> Self::Output;
}
Therefore mark() will be used when we need to backtrack in the current parse state but also for expressing ranges. It could have another name.
Convenience function can be implemented for specific range, for example Range<StrStream<'a>> can implement to_string() or something similar.
When needed, the type of span can be automatically retrieved with <Range<StrStream<'a>> as Span>::Output.
A sequence of atoms has type
Vec<char>
where char is the underlying parsing atom. The problem is that we would actually prefer to have a value containing the beginning and the end of the stream range. Example: The expression["0-9"]+
has typeVec<char>
but semantic actions are sometimes more efficient if they directly work on the underlyingstr
slice, in this case, building a vector is unnecessary.Design
std::ops::Range
from Rust standard library.Range<Stream>
will be created in the generated code and send to the semantic action.Span
will be created for retrieving the span from a range and can be implemented independently for each range stream.mark()
will be used when we need to backtrack in the current parse state but also for expressing ranges. It could have another name.Range<StrStream<'a>>
can implementto_string()
or something similar.<Range<StrStream<'a>> as Span>::Output
.