aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorcsmoe <[email protected]>2019-01-01 08:09:51 +0000
committercsmoe <[email protected]>2019-01-04 04:21:47 +0000
commitdf591a1e48a876653f1f48ed595d1754470d116f (patch)
tree423a619b45a6c9aacdc09275a731b3255743531e /crates/ra_syntax/src
parentb01e707dba7810c3d28c82a84dec9064cc01d3c8 (diff)
doc parsing events
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/parser_api.rs17
-rw-r--r--crates/ra_syntax/src/parser_impl.rs55
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs40
-rw-r--r--crates/ra_syntax/src/parser_impl/input.rs2
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 {
160pub(crate) struct CompletedMarker(u32, SyntaxKind); 162pub(crate) struct CompletedMarker(u32, SyntaxKind);
161 163
162impl CompletedMarker { 164impl 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`.
65pub(crate) struct ParserImpl<'t> { 65pub(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> {
72impl<'t> ParserImpl<'t> { 72impl<'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
87impl Event {
88 pub(crate) fn tombstone() -> Self {
89 Event::Start {
90 kind: TOMBSTONE,
91 forward_parent: None,
92 }
93 }
94}
95
87pub(super) struct EventProcessor<'a, S: Sink> { 96pub(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()) {