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