diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_syntax/src/parser_api.rs | 17 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl.rs | 55 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 40 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/input.rs | 2 |
4 files changed, 71 insertions, 43 deletions
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs index 0f740963d..3487aef85 100644 --- a/crates/ra_syntax/src/parser_api.rs +++ b/crates/ra_syntax/src/parser_api.rs | |||
@@ -142,11 +142,13 @@ impl Marker { | |||
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | /// Finishes the syntax tree node and assigns `kind` to it. | 145 | /// Finishes the syntax tree node and assigns `kind` to it, |
146 | /// and mark the create a `CompletedMarker` for possible future | ||
147 | /// operation like `.precede()` to deal with forward_parent. | ||
146 | pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { | 148 | pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { |
147 | self.bomb.defuse(); | 149 | self.bomb.defuse(); |
148 | p.0.complete(self.pos, kind); | 150 | p.0.complete(self.pos, kind); |
149 | CompletedMarker(self.pos, kind) | 151 | CompletedMarker::new(self.pos, kind) |
150 | } | 152 | } |
151 | 153 | ||
152 | /// Abandons the syntax tree node. All its children | 154 | /// Abandons the syntax tree node. All its children |
@@ -160,13 +162,22 @@ impl Marker { | |||
160 | pub(crate) struct CompletedMarker(u32, SyntaxKind); | 162 | pub(crate) struct CompletedMarker(u32, SyntaxKind); |
161 | 163 | ||
162 | impl CompletedMarker { | 164 | impl CompletedMarker { |
163 | /// This one is tricky :-) | 165 | fn new(pos: u32, kind: SyntaxKind) -> Self { |
166 | CompletedMarker(pos, kind) | ||
167 | } | ||
168 | |||
164 | /// This method allows to create a new node which starts | 169 | /// This method allows to create a new node which starts |
165 | /// *before* the current one. That is, parser could start | 170 | /// *before* the current one. That is, parser could start |
166 | /// node `A`, then complete it, and then after parsing the | 171 | /// node `A`, then complete it, and then after parsing the |
167 | /// whole `A`, decide that it should have started some node | 172 | /// whole `A`, decide that it should have started some node |
168 | /// `B` before starting `A`. `precede` allows to do exactly | 173 | /// `B` before starting `A`. `precede` allows to do exactly |
169 | /// that. See also docs about `forward_parent` in `Event::Start`. | 174 | /// that. See also docs about `forward_parent` in `Event::Start`. |
175 | /// | ||
176 | /// Given completed events `[START, FINISH]` and its corresponding | ||
177 | /// `CompletedMarker(pos: 0, _)`. | ||
178 | /// Append a new `START` events as `[START, FINISH, NEWSTART]`, | ||
179 | /// then mark `NEWSTART` as `START`'s parent with saving its relative | ||
180 | /// distance to `NEWSTART` into forward_parent(=2 in this case); | ||
170 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { | 181 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { |
171 | Marker::new(p.0.precede(self.0)) | 182 | Marker::new(p.0.precede(self.0)) |
172 | } | 183 | } |
diff --git a/crates/ra_syntax/src/parser_impl.rs b/crates/ra_syntax/src/parser_impl.rs index ce321aecb..01a51cd8d 100644 --- a/crates/ra_syntax/src/parser_impl.rs +++ b/crates/ra_syntax/src/parser_impl.rs | |||
@@ -63,7 +63,7 @@ pub(crate) fn parse_with<S: Sink>( | |||
63 | /// to a separate struct in order not to pollute | 63 | /// to a separate struct in order not to pollute |
64 | /// the public API of the `Parser`. | 64 | /// the public API of the `Parser`. |
65 | pub(crate) struct ParserImpl<'t> { | 65 | pub(crate) struct ParserImpl<'t> { |
66 | inp: &'t ParserInput<'t>, | 66 | parser_input: &'t ParserInput<'t>, |
67 | pos: InputPosition, | 67 | pos: InputPosition, |
68 | events: Vec<Event>, | 68 | events: Vec<Event>, |
69 | steps: Cell<u32>, | 69 | steps: Cell<u32>, |
@@ -72,7 +72,7 @@ pub(crate) struct ParserImpl<'t> { | |||
72 | impl<'t> ParserImpl<'t> { | 72 | impl<'t> ParserImpl<'t> { |
73 | pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { | 73 | pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { |
74 | ParserImpl { | 74 | ParserImpl { |
75 | inp, | 75 | parser_input: inp, |
76 | pos: InputPosition::new(), | 76 | pos: InputPosition::new(), |
77 | events: Vec::new(), | 77 | events: Vec::new(), |
78 | steps: Cell::new(0), | 78 | steps: Cell::new(0), |
@@ -85,10 +85,10 @@ impl<'t> ParserImpl<'t> { | |||
85 | } | 85 | } |
86 | 86 | ||
87 | pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { | 87 | pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { |
88 | let c1 = self.inp.kind(self.pos); | 88 | let c1 = self.parser_input.kind(self.pos); |
89 | let c2 = self.inp.kind(self.pos + 1); | 89 | let c2 = self.parser_input.kind(self.pos + 1); |
90 | if self.inp.token_start_at(self.pos + 1) | 90 | if self.parser_input.token_start_at(self.pos + 1) |
91 | == self.inp.token_start_at(self.pos) + self.inp.len(self.pos) | 91 | == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos) |
92 | { | 92 | { |
93 | Some((c1, c2)) | 93 | Some((c1, c2)) |
94 | } else { | 94 | } else { |
@@ -97,13 +97,14 @@ impl<'t> ParserImpl<'t> { | |||
97 | } | 97 | } |
98 | 98 | ||
99 | pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { | 99 | pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { |
100 | let c1 = self.inp.kind(self.pos); | 100 | let c1 = self.parser_input.kind(self.pos); |
101 | let c2 = self.inp.kind(self.pos + 1); | 101 | let c2 = self.parser_input.kind(self.pos + 1); |
102 | let c3 = self.inp.kind(self.pos + 2); | 102 | let c3 = self.parser_input.kind(self.pos + 2); |
103 | if self.inp.token_start_at(self.pos + 1) | 103 | if self.parser_input.token_start_at(self.pos + 1) |
104 | == self.inp.token_start_at(self.pos) + self.inp.len(self.pos) | 104 | == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos) |
105 | && self.inp.token_start_at(self.pos + 2) | 105 | && self.parser_input.token_start_at(self.pos + 2) |
106 | == self.inp.token_start_at(self.pos + 1) + self.inp.len(self.pos + 1) | 106 | == self.parser_input.token_start_at(self.pos + 1) |
107 | + self.parser_input.token_len(self.pos + 1) | ||
107 | { | 108 | { |
108 | Some((c1, c2, c3)) | 109 | Some((c1, c2, c3)) |
109 | } else { | 110 | } else { |
@@ -111,29 +112,27 @@ impl<'t> ParserImpl<'t> { | |||
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
115 | /// Get the syntax kind of the nth token. | ||
114 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { | 116 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { |
115 | let steps = self.steps.get(); | 117 | let steps = self.steps.get(); |
116 | if steps > 10_000_000 { | 118 | assert!(steps <= 10_000_000, "the parser seems stuck"); |
117 | panic!("the parser seems stuck"); | ||
118 | } | ||
119 | self.steps.set(steps + 1); | 119 | self.steps.set(steps + 1); |
120 | 120 | ||
121 | self.inp.kind(self.pos + n) | 121 | self.parser_input.kind(self.pos + n) |
122 | } | 122 | } |
123 | 123 | ||
124 | pub(super) fn at_kw(&self, t: &str) -> bool { | 124 | pub(super) fn at_kw(&self, t: &str) -> bool { |
125 | self.inp.text(self.pos) == t | 125 | self.parser_input.token_text(self.pos) == t |
126 | } | 126 | } |
127 | 127 | ||
128 | /// Start parsing right behind the last event. | ||
128 | pub(super) fn start(&mut self) -> u32 { | 129 | pub(super) fn start(&mut self) -> u32 { |
129 | let pos = self.events.len() as u32; | 130 | let pos = self.events.len() as u32; |
130 | self.event(Event::Start { | 131 | self.push_event(Event::tombstone()); |
131 | kind: TOMBSTONE, | ||
132 | forward_parent: None, | ||
133 | }); | ||
134 | pos | 132 | pos |
135 | } | 133 | } |
136 | 134 | ||
135 | /// Advances the parser by one token unconditionally. | ||
137 | pub(super) fn bump(&mut self) { | 136 | pub(super) fn bump(&mut self) { |
138 | let kind = self.nth(0); | 137 | let kind = self.nth(0); |
139 | if kind == EOF { | 138 | if kind == EOF { |
@@ -156,15 +155,17 @@ impl<'t> ParserImpl<'t> { | |||
156 | 155 | ||
157 | fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { | 156 | fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { |
158 | self.pos += u32::from(n_raw_tokens); | 157 | self.pos += u32::from(n_raw_tokens); |
159 | self.event(Event::Token { kind, n_raw_tokens }); | 158 | self.push_event(Event::Token { kind, n_raw_tokens }); |
160 | } | 159 | } |
161 | 160 | ||
161 | /// Append one Error event to the back of events. | ||
162 | pub(super) fn error(&mut self, msg: String) { | 162 | pub(super) fn error(&mut self, msg: String) { |
163 | self.event(Event::Error { | 163 | self.push_event(Event::Error { |
164 | msg: ParseError(msg), | 164 | msg: ParseError(msg), |
165 | }) | 165 | }) |
166 | } | 166 | } |
167 | 167 | ||
168 | /// Complete an event with appending a `Finish` event. | ||
168 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { | 169 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { |
169 | match self.events[pos as usize] { | 170 | match self.events[pos as usize] { |
170 | Event::Start { | 171 | Event::Start { |
@@ -174,9 +175,10 @@ impl<'t> ParserImpl<'t> { | |||
174 | } | 175 | } |
175 | _ => unreachable!(), | 176 | _ => unreachable!(), |
176 | } | 177 | } |
177 | self.event(Event::Finish); | 178 | self.push_event(Event::Finish); |
178 | } | 179 | } |
179 | 180 | ||
181 | /// Ignore the dummy `Start` event. | ||
180 | pub(super) fn abandon(&mut self, pos: u32) { | 182 | pub(super) fn abandon(&mut self, pos: u32) { |
181 | let idx = pos as usize; | 183 | let idx = pos as usize; |
182 | if idx == self.events.len() - 1 { | 184 | if idx == self.events.len() - 1 { |
@@ -190,6 +192,7 @@ impl<'t> ParserImpl<'t> { | |||
190 | } | 192 | } |
191 | } | 193 | } |
192 | 194 | ||
195 | /// Save the relative distance of a completed event to its forward_parent. | ||
193 | pub(super) fn precede(&mut self, pos: u32) -> u32 { | 196 | pub(super) fn precede(&mut self, pos: u32) -> u32 { |
194 | let new_pos = self.start(); | 197 | let new_pos = self.start(); |
195 | match self.events[pos as usize] { | 198 | match self.events[pos as usize] { |
@@ -204,7 +207,7 @@ impl<'t> ParserImpl<'t> { | |||
204 | new_pos | 207 | new_pos |
205 | } | 208 | } |
206 | 209 | ||
207 | fn event(&mut self, event: Event) { | 210 | fn push_event(&mut self, event: Event) { |
208 | self.events.push(event) | 211 | self.events.push(event) |
209 | } | 212 | } |
210 | } | 213 | } |
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()) { |