Option
tp::Option<T>
and tp::Exists<T>
are types used to represent optional syntax trees.
tp::Option<T>
stores the syntax tree itself, and tp::Exists<T>
stores a boolean value to test if the syntax tree is present.
Production
Option<T> => ε | T
Example
Ident
is a terminal struct not shown here
#![allow(unused)] fn main() { use teleparse::prelude::*; #[derive_syntax] #[teleparse(root)] #[derive(Debug, PartialEq)] struct OptIdent(tp::Option<Ident>); #[test] fn test_none() -> Result<(), GrammarError> { let t = OptIdent::parse("+")?.unwrap(); assert_eq!(t, OptIdent(Node::new(0..0, None).into())); Ok(()) } #[test] fn test_some() -> Result<(), GrammarError> { let t = OptIdent::parse("a")?.unwrap(); assert_eq!(t, OptIdent(Node::new(0..1, Some(Ident::from_span(0..1)).into())); Ok(()) } }
Deref
tp::Option<T>
/ tp::Exists<T>
implements Deref
and DerefMut
. So you can
use them as &std::option::Option<T>
/ &bool
.
#![allow(unused)] fn main() { let t = OptIdent::parse("a")?.unwrap(); assert!(t.0.is_some()); }
Parsing
There are 3 possible outcomes when parsing an Option<T>
:
- The next token is not in FIRST(T). The parser will return
None
. - The next token is in FIRST(T):
- If the parser can parse
T
, it will returnSome(T)
. - If the parser cannot parse
T
, it will record an error, returnNone
, and continue.
- If the parser can parse
In any case, the parser will not panic.
Common LL(1) Violations
Option<Option<T>>
- sinceSome(None)
andNone
are indistinguishable.(Option<T>, T)
- since (None, T) and (Some(T), ...) are indistinguishable.