diff options
author | csmoe <[email protected]> | 2019-01-01 08:09:51 +0000 |
---|---|---|
committer | csmoe <[email protected]> | 2019-01-04 04:21:47 +0000 |
commit | df591a1e48a876653f1f48ed595d1754470d116f (patch) | |
tree | 423a619b45a6c9aacdc09275a731b3255743531e /crates/ra_syntax/src/parser_impl | |
parent | b01e707dba7810c3d28c82a84dec9064cc01d3c8 (diff) |
doc parsing events
Diffstat (limited to 'crates/ra_syntax/src/parser_impl')
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 40 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/input.rs | 2 |
2 files changed, 28 insertions, 14 deletions
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs index d6299b5e3..835b2c78d 100644 --- a/crates/ra_syntax/src/parser_impl/event.rs +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -36,7 +36,7 @@ pub(crate) enum Event { | |||
36 | /// | 36 | /// |
37 | /// For left-recursive syntactic constructs, the parser produces | 37 | /// For left-recursive syntactic constructs, the parser produces |
38 | /// a child node before it sees a parent. `forward_parent` | 38 | /// a child node before it sees a parent. `forward_parent` |
39 | /// exists to allow to tweak parent-child relationships. | 39 | /// saves the position of current event's parent. |
40 | /// | 40 | /// |
41 | /// Consider this path | 41 | /// Consider this path |
42 | /// | 42 | /// |
@@ -84,6 +84,15 @@ pub(crate) enum Event { | |||
84 | }, | 84 | }, |
85 | } | 85 | } |
86 | 86 | ||
87 | impl Event { | ||
88 | pub(crate) fn tombstone() -> Self { | ||
89 | Event::Start { | ||
90 | kind: TOMBSTONE, | ||
91 | forward_parent: None, | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
87 | pub(super) struct EventProcessor<'a, S: Sink> { | 96 | pub(super) struct EventProcessor<'a, S: Sink> { |
88 | sink: S, | 97 | sink: S, |
89 | text_pos: TextUnit, | 98 | text_pos: TextUnit, |
@@ -110,17 +119,12 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
110 | } | 119 | } |
111 | } | 120 | } |
112 | 121 | ||
122 | /// Generate the syntax tree with the control of events. | ||
113 | pub(super) fn process(mut self) -> S { | 123 | pub(super) fn process(mut self) -> S { |
114 | fn tombstone() -> Event { | ||
115 | Event::Start { | ||
116 | kind: TOMBSTONE, | ||
117 | forward_parent: None, | ||
118 | } | ||
119 | } | ||
120 | let mut forward_parents = Vec::new(); | 124 | let mut forward_parents = Vec::new(); |
121 | 125 | ||
122 | for i in 0..self.events.len() { | 126 | for i in 0..self.events.len() { |
123 | match mem::replace(&mut self.events[i], tombstone()) { | 127 | match mem::replace(&mut self.events[i], Event::tombstone()) { |
124 | Event::Start { | 128 | Event::Start { |
125 | kind: TOMBSTONE, .. | 129 | kind: TOMBSTONE, .. |
126 | } => (), | 130 | } => (), |
@@ -129,12 +133,18 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
129 | kind, | 133 | kind, |
130 | forward_parent, | 134 | forward_parent, |
131 | } => { | 135 | } => { |
136 | // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, | ||
137 | // in the normal control flow, the parent-child relation: `A -> B -> C`, | ||
138 | // while with the magic forward_parent, it writes: `C <- B <- A`. | ||
139 | |||
140 | // append `A` into parents. | ||
132 | forward_parents.push(kind); | 141 | forward_parents.push(kind); |
133 | let mut idx = i; | 142 | let mut idx = i; |
134 | let mut fp = forward_parent; | 143 | let mut fp = forward_parent; |
135 | while let Some(fwd) = fp { | 144 | while let Some(fwd) = fp { |
136 | idx += fwd as usize; | 145 | idx += fwd as usize; |
137 | fp = match mem::replace(&mut self.events[idx], tombstone()) { | 146 | // append `A`'s forward_parent `B` |
147 | fp = match mem::replace(&mut self.events[idx], Event::tombstone()) { | ||
138 | Event::Start { | 148 | Event::Start { |
139 | kind, | 149 | kind, |
140 | forward_parent, | 150 | forward_parent, |
@@ -144,14 +154,16 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
144 | } | 154 | } |
145 | _ => unreachable!(), | 155 | _ => unreachable!(), |
146 | }; | 156 | }; |
157 | // append `B`'s forward_parent `C` in the next stage. | ||
147 | } | 158 | } |
159 | |||
148 | for kind in forward_parents.drain(..).rev() { | 160 | for kind in forward_parents.drain(..).rev() { |
149 | self.start(kind); | 161 | self.start(kind); |
150 | } | 162 | } |
151 | } | 163 | } |
152 | Event::Finish => { | 164 | Event::Finish => { |
153 | let last = i == self.events.len() - 1; | 165 | let is_last = i == self.events.len() - 1; |
154 | self.finish(last); | 166 | self.finish(is_last); |
155 | } | 167 | } |
156 | Event::Token { kind, n_raw_tokens } => { | 168 | Event::Token { kind, n_raw_tokens } => { |
157 | self.eat_trivias(); | 169 | self.eat_trivias(); |
@@ -171,6 +183,7 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
171 | self.sink | 183 | self.sink |
172 | } | 184 | } |
173 | 185 | ||
186 | /// Add the node into syntax tree but discard the comments/whitespaces. | ||
174 | fn start(&mut self, kind: SyntaxKind) { | 187 | fn start(&mut self, kind: SyntaxKind) { |
175 | if kind == SOURCE_FILE { | 188 | if kind == SOURCE_FILE { |
176 | self.sink.start_branch(kind); | 189 | self.sink.start_branch(kind); |
@@ -198,8 +211,8 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
198 | self.eat_n_trivias(n_attached_trivias); | 211 | self.eat_n_trivias(n_attached_trivias); |
199 | } | 212 | } |
200 | 213 | ||
201 | fn finish(&mut self, last: bool) { | 214 | fn finish(&mut self, is_last: bool) { |
202 | if last { | 215 | if is_last { |
203 | self.eat_trivias() | 216 | self.eat_trivias() |
204 | } | 217 | } |
205 | self.sink.finish_branch(); | 218 | self.sink.finish_branch(); |
@@ -235,6 +248,7 @@ fn n_attached_trivias<'a>( | |||
235 | kind: SyntaxKind, | 248 | kind: SyntaxKind, |
236 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, | 249 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, |
237 | ) -> usize { | 250 | ) -> usize { |
251 | // FIXME: parse attached trivias of CONST_DEF/TYPE_DEF | ||
238 | match kind { | 252 | match kind { |
239 | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => { | 253 | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => { |
240 | let mut res = 0; | 254 | let mut res = 0; |
diff --git a/crates/ra_syntax/src/parser_impl/input.rs b/crates/ra_syntax/src/parser_impl/input.rs index 083a7aa15..7fde5b3ab 100644 --- a/crates/ra_syntax/src/parser_impl/input.rs +++ b/crates/ra_syntax/src/parser_impl/input.rs | |||
@@ -70,7 +70,7 @@ impl<'t> ParserInput<'t> { | |||
70 | self.start_offsets[idx] | 70 | self.start_offsets[idx] |
71 | } | 71 | } |
72 | 72 | ||
73 | /// Get the raw text of a toen at given input position. | 73 | /// Get the raw text of a token at given input position. |
74 | pub fn token_text(&self, pos: InputPosition) -> &'t str { | 74 | pub fn token_text(&self, pos: InputPosition) -> &'t str { |
75 | let idx = pos.0 as usize; | 75 | let idx = pos.0 as usize; |
76 | if !(idx < self.tokens.len()) { | 76 | if !(idx < self.tokens.len()) { |