synkit_core/traits/parse.rs
1use super::peek::Peek;
2use super::stream::TokenStream;
3
4/// Trait for types that can be parsed from a token stream.
5///
6/// This is the primary trait for defining how AST nodes are constructed
7/// from tokens. Implementations consume tokens from the stream and
8/// return either a parsed value or an error.
9///
10/// # Associated Types
11///
12/// - `Token`: The token type this parser consumes (e.g., `MyTok`)
13/// - `Error`: The error type for parse failures (e.g., `MyParseError`)
14///
15/// # Implementation Guidelines
16///
17/// 1. Use `stream.peek::<T>()` to check token types without consuming
18/// 2. Use `stream.parse::<T>()` to recursively parse nested structures
19/// 3. Use `stream.fork()` for backtracking lookahead
20/// 4. Return errors early with `?` operator
21///
22/// # Example
23///
24/// ```ignore
25/// use synkit::{Parse, Peek, TokenStream};
26///
27/// struct BinaryExpr {
28/// left: Box<Expr>,
29/// op: Operator,
30/// right: Box<Expr>,
31/// }
32///
33/// impl Parse for BinaryExpr {
34/// type Token = MyTok;
35/// type Error = ParseError;
36///
37/// fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
38/// where
39/// S: TokenStream<Token = Self::Token>,
40/// {
41/// let left = stream.parse()?;
42/// let op = stream.parse()?;
43/// let right = stream.parse()?;
44/// Ok(BinaryExpr { left, op, right })
45/// }
46/// }
47/// ```
48///
49/// # Blanket Implementations
50///
51/// - `Option<T>`: Parses `Some(T)` if `T::peek()` succeeds, else `None`
52/// - `Box<T>`: Delegates to `T::parse()` and boxes the result
53pub trait Parse: Sized {
54 /// The token type consumed by this parser.
55 type Token: Clone;
56 /// The error type for parse failures.
57 type Error;
58
59 /// Parse a value from the token stream.
60 ///
61 /// # Arguments
62 ///
63 /// * `stream` - The token stream to parse from
64 ///
65 /// # Returns
66 ///
67 /// * `Ok(Self)` - Successfully parsed value
68 /// * `Err(Self::Error)` - Parse failure with error details
69 fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
70 where
71 S: TokenStream<Token = Self::Token>;
72}
73
74impl<T> Parse for Option<T>
75where
76 T: Parse + Peek<Token = <T as Parse>::Token>,
77{
78 type Token = <T as Parse>::Token;
79 type Error = T::Error;
80
81 fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
82 where
83 S: TokenStream<Token = Self::Token>,
84 {
85 if stream.peek::<T>() {
86 Ok(Some(T::parse(stream)?))
87 } else {
88 Ok(None)
89 }
90 }
91}
92
93impl<T: Parse> Parse for Box<T> {
94 type Token = T::Token;
95 type Error = T::Error;
96
97 fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
98 where
99 S: TokenStream<Token = Self::Token>,
100 {
101 Ok(Box::new(T::parse(stream)?))
102 }
103}