Iteration
These types are used to parse a list of items directly after one another (i.e. without a delimiter), and stops if the item cannot start with the next token.
tp::Plus<V: FromIterator<T>, T>
is one or more ofT
tp::Star<V: FromIterator<T> + Default, T>
is zero or more ofT
tp::Vec<T>
andtp::VecDeque<T>
are aliases fortp::Star<Vec<T>, T>
andtp::Star<VecDeque<T>, T>
respectivelytp::Nev<T>
andtp::NevDeque<T>
are aliases fortp::Plus<Vec<T>, T>
andtp::Plus<VecDeque<T>, T>
respectively. Nev stands for "non-empty vector".
The name "Plus" and "Star" are borrowed from regular expression notation "+" and "*" to indicate "one or more" and "zero or more" respectively.
Production
Plus<T> => T Star<T>
Star<T> => Option<Plus<T>>
Examples
Ident
is a terminal struct not shown here
#![allow(unused)] fn main() { use teleparse::prelude::*; use teleparse::GrammarError; #[derive_syntax] #[teleparse(root)] #[derive(Debug, PartialEq, Clone)] struct IdentList(tp::Nev<Ident>); #[test] fn parse() -> Result<(), GrammarError> { let t = IdentList::parse("a b c d e").unwrap(); assert_eq!( t, IdentList( Node::new( 0..10, vec![ Ident::from_span(0..1), Ident::from_span(2..3), Ident::from_span(4..5), Ident::from_span(7..8), Ident::from_span(9..10), ] ) .into() ) ); Ok(()) } }
Deref
Plus
and Star
can be dereferenced to the inner vector type.
For example, you can use tp::Vec<T>
as a &std::vec::Vec<T>
.
Parsing
Plus
and Star
share similar parsing logic. The only difference is that
if the next token is not in FIRST(T), the parser will return Default::default()
for Star
but will panic for Plus
.
The parser keeps trying to parse T
while the next token is in FIRST(T). If the parser
panics while parsing T
, it will record the error and recover with the items already parsed.
The only exception is the first item in a Plus
, in which case the parser panics instead.
Common LL(1) Violations
Vec<Option<T>>
- since there can be an infinite number ofNone
s.