• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! See [`Output`]
2 
3 use crate::SyntaxKind;
4 
5 /// Output of the parser -- a DFS traversal of a concrete syntax tree.
6 ///
7 /// Use the [`Output::iter`] method to iterate over traversal steps and consume
8 /// a syntax tree.
9 ///
10 /// In a sense, this is just a sequence of [`SyntaxKind`]-colored parenthesis
11 /// interspersed into the original [`crate::Input`]. The output is fundamentally
12 /// coordinated with the input and `n_input_tokens` refers to the number of
13 /// times [`crate::Input::push`] was called.
14 #[derive(Default)]
15 pub struct Output {
16     /// 32-bit encoding of events. If LSB is zero, then that's an index into the
17     /// error vector. Otherwise, it's one of the thee other variants, with data encoded as
18     ///
19     ///     |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover|
20     ///
21     event: Vec<u32>,
22     error: Vec<String>,
23 }
24 
25 #[derive(Debug)]
26 pub enum Step<'a> {
27     Token { kind: SyntaxKind, n_input_tokens: u8 },
28     FloatSplit { ends_in_dot: bool },
29     Enter { kind: SyntaxKind },
30     Exit,
31     Error { msg: &'a str },
32 }
33 
34 impl Output {
35     const EVENT_MASK: u32 = 0b1;
36     const TAG_MASK: u32 = 0x0000_00F0;
37     const N_INPUT_TOKEN_MASK: u32 = 0x0000_FF00;
38     const KIND_MASK: u32 = 0xFFFF_0000;
39 
40     const ERROR_SHIFT: u32 = Self::EVENT_MASK.trailing_ones();
41     const TAG_SHIFT: u32 = Self::TAG_MASK.trailing_zeros();
42     const N_INPUT_TOKEN_SHIFT: u32 = Self::N_INPUT_TOKEN_MASK.trailing_zeros();
43     const KIND_SHIFT: u32 = Self::KIND_MASK.trailing_zeros();
44 
45     const TOKEN_EVENT: u8 = 0;
46     const ENTER_EVENT: u8 = 1;
47     const EXIT_EVENT: u8 = 2;
48     const SPLIT_EVENT: u8 = 3;
49 
iter(&self) -> impl Iterator<Item = Step<'_>>50     pub fn iter(&self) -> impl Iterator<Item = Step<'_>> {
51         self.event.iter().map(|&event| {
52             if event & Self::EVENT_MASK == 0 {
53                 return Step::Error {
54                     msg: self.error[(event as usize) >> Self::ERROR_SHIFT].as_str(),
55                 };
56             }
57             let tag = ((event & Self::TAG_MASK) >> Self::TAG_SHIFT) as u8;
58             match tag {
59                 Self::TOKEN_EVENT => {
60                     let kind: SyntaxKind =
61                         (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into();
62                     let n_input_tokens =
63                         ((event & Self::N_INPUT_TOKEN_MASK) >> Self::N_INPUT_TOKEN_SHIFT) as u8;
64                     Step::Token { kind, n_input_tokens }
65                 }
66                 Self::ENTER_EVENT => {
67                     let kind: SyntaxKind =
68                         (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into();
69                     Step::Enter { kind }
70                 }
71                 Self::EXIT_EVENT => Step::Exit,
72                 Self::SPLIT_EVENT => {
73                     Step::FloatSplit { ends_in_dot: event & Self::N_INPUT_TOKEN_MASK != 0 }
74                 }
75                 _ => unreachable!(),
76             }
77         })
78     }
79 
token(&mut self, kind: SyntaxKind, n_tokens: u8)80     pub(crate) fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
81         let e = ((kind as u16 as u32) << Self::KIND_SHIFT)
82             | ((n_tokens as u32) << Self::N_INPUT_TOKEN_SHIFT)
83             | Self::EVENT_MASK;
84         self.event.push(e)
85     }
86 
float_split_hack(&mut self, ends_in_dot: bool)87     pub(crate) fn float_split_hack(&mut self, ends_in_dot: bool) {
88         let e = (Self::SPLIT_EVENT as u32) << Self::TAG_SHIFT
89             | ((ends_in_dot as u32) << Self::N_INPUT_TOKEN_SHIFT)
90             | Self::EVENT_MASK;
91         self.event.push(e);
92     }
93 
enter_node(&mut self, kind: SyntaxKind)94     pub(crate) fn enter_node(&mut self, kind: SyntaxKind) {
95         let e = ((kind as u16 as u32) << Self::KIND_SHIFT)
96             | ((Self::ENTER_EVENT as u32) << Self::TAG_SHIFT)
97             | Self::EVENT_MASK;
98         self.event.push(e)
99     }
100 
leave_node(&mut self)101     pub(crate) fn leave_node(&mut self) {
102         let e = (Self::EXIT_EVENT as u32) << Self::TAG_SHIFT | Self::EVENT_MASK;
103         self.event.push(e)
104     }
105 
error(&mut self, error: String)106     pub(crate) fn error(&mut self, error: String) {
107         let idx = self.error.len();
108         self.error.push(error);
109         let e = (idx as u32) << Self::ERROR_SHIFT;
110         self.event.push(e);
111     }
112 }
113