parse_emit_walkthrough/
parse_emit_walkthrough.rs1use m2_syn::{
2 IdentToken, Lex, Parse, ParseStream, Span, Spanned, TokenParseError, TokenStream, TokenTree,
3 parse2, quote_m2,
4};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7struct Name(IdentToken);
8
9impl Parse for Name {
10 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
11 let Some(token) = input.next_token() else {
12 return Err(TokenParseError::UnexpectedEnd {
13 expected: "identifier",
14 span: Span::detached(),
15 });
16 };
17
18 let span = token.span();
19 match token {
20 TokenTree::Ident(identifier) => Ok(Self(identifier)),
21 token => Err(TokenParseError::UnexpectedToken {
22 expected: "identifier",
23 found: token.spelling().unwrap_or("group or trivia").to_owned(),
24 span,
25 }),
26 }
27 }
28}
29
30impl Lex for Name {
31 fn to_tokens(&self, output: &mut TokenStream) {
32 self.0.to_tokens(output);
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37struct Addition {
38 left: Name,
39 operator: m2_syn::Token![+],
40 right: Name,
41}
42
43impl Parse for Addition {
44 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
45 Ok(Self {
46 left: Name::parse(input)?,
47 operator: Parse::parse(input)?,
48 right: Name::parse(input)?,
49 })
50 }
51}
52
53impl Lex for Addition {
54 fn to_tokens(&self, output: &mut TokenStream) {
55 output.extend(self.left.to_token_stream());
56 output.extend(self.operator.to_token_stream());
57 output.extend(self.right.to_token_stream());
58 }
59}
60
61fn main() -> Result<(), TokenParseError> {
62 let quoted = quote_m2!(left + right);
63 println!("1. quote_m2! produced:\n{quoted:#?}\n");
64
65 let parsed: Addition = parse2(quoted)?;
66 println!("2. Parse produced:\n{parsed:#?}\n");
67
68 let emitted = parsed.to_token_stream();
69 println!("3. Lex produced:\n{emitted:#?}\n");
70 println!("4. Display merged those tokens as: {emitted}");
71
72 let reparsed: Addition = parse2(emitted)?;
73 assert_eq!(reparsed, parsed);
74
75 Ok(())
76}