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