]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/parser/src/output.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / parser / src / output.rs
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 Enter { kind: SyntaxKind },
29 Exit,
30 Error { msg: &'a str },
31 }
32
33 impl Output {
34 pub fn iter(&self) -> impl Iterator<Item = Step<'_>> {
35 self.event.iter().map(|&event| {
36 if event & 0b1 == 0 {
37 return Step::Error { msg: self.error[(event as usize) >> 1].as_str() };
38 }
39 let tag = ((event & 0x0000_00F0) >> 4) as u8;
40 match tag {
41 0 => {
42 let kind: SyntaxKind = (((event & 0xFFFF_0000) >> 16) as u16).into();
43 let n_input_tokens = ((event & 0x0000_FF00) >> 8) as u8;
44 Step::Token { kind, n_input_tokens }
45 }
46 1 => {
47 let kind: SyntaxKind = (((event & 0xFFFF_0000) >> 16) as u16).into();
48 Step::Enter { kind }
49 }
50 2 => Step::Exit,
51 _ => unreachable!(),
52 }
53 })
54 }
55
56 pub(crate) fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
57 let e = ((kind as u16 as u32) << 16) | ((n_tokens as u32) << 8) | 1;
58 self.event.push(e)
59 }
60
61 pub(crate) fn enter_node(&mut self, kind: SyntaxKind) {
62 let e = ((kind as u16 as u32) << 16) | (1 << 4) | 1;
63 self.event.push(e)
64 }
65
66 pub(crate) fn leave_node(&mut self) {
67 let e = 2 << 4 | 1;
68 self.event.push(e)
69 }
70
71 pub(crate) fn error(&mut self, error: String) {
72 let idx = self.error.len();
73 self.error.push(error);
74 let e = (idx as u32) << 1;
75 self.event.push(e);
76 }
77 }