aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parser_impl
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-10-08 13:44:00 +0100
committerAleksey Kladov <[email protected]>2018-10-08 13:44:00 +0100
commit86a7ac2d31e97c42a9da8d8fd539b5a0de0fa795 (patch)
tree17d16374b28e3221cfb793340b32aabe2f4fd1dd /crates/ra_syntax/src/parser_impl
parent3c12d38a32f5c87e87d9dbced774453216086bab (diff)
Simplify event processing
Diffstat (limited to 'crates/ra_syntax/src/parser_impl')
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs148
-rw-r--r--crates/ra_syntax/src/parser_impl/mod.rs25
2 files changed, 100 insertions, 73 deletions
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs
index 9fd56b996..48f37c57c 100644
--- a/crates/ra_syntax/src/parser_impl/event.rs
+++ b/crates/ra_syntax/src/parser_impl/event.rs
@@ -9,6 +9,7 @@
9//! this stream to a real tree. 9//! this stream to a real tree.
10use std::mem; 10use std::mem;
11use { 11use {
12 TextUnit, TextRange, SmolStr,
12 lexer::Token, 13 lexer::Token,
13 parser_impl::Sink, 14 parser_impl::Sink,
14 SyntaxKind::{self, TOMBSTONE}, 15 SyntaxKind::{self, TOMBSTONE},
@@ -78,77 +79,104 @@ pub(crate) enum Event {
78 }, 79 },
79} 80}
80 81
82pub(super) struct EventProcessor<'a, S: Sink> {
83 sink: S,
84 text_pos: TextUnit,
85 text: &'a str,
86 token_pos: usize,
87 tokens: &'a [Token],
88 events: &'a mut [Event],
89}
81 90
82pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], mut events: Vec<Event>) { 91impl<'a, S: Sink> EventProcessor<'a, S> {
83 fn tombstone() -> Event { 92 pub(super) fn new(sink: S, text: &'a str, tokens: &'a[Token], events: &'a mut [Event]) -> EventProcessor<'a, S> {
84 Event::Start { kind: TOMBSTONE, forward_parent: None } 93 EventProcessor {
94 sink,
95 text_pos: 0.into(),
96 text,
97 token_pos: 0,
98 tokens,
99 events
100 }
85 } 101 }
86 let eat_ws = |idx: &mut usize, builder: &mut S| { 102
87 while let Some(token) = tokens.get(*idx) { 103 pub(super) fn process(mut self) -> S {
88 if !token.kind.is_trivia() { 104 fn tombstone() -> Event {
89 break; 105 Event::Start { kind: TOMBSTONE, forward_parent: None }
90 }
91 builder.leaf(token.kind, token.len);
92 *idx += 1
93 } 106 }
94 }; 107 let mut depth = 0;
108 let mut forward_parents = Vec::new();
95 109
96 let events: &mut [Event] = &mut events; 110 for i in 0..self.events.len() {
97 let mut depth = 0; 111 match mem::replace(&mut self.events[i], tombstone()) {
98 let mut forward_parents = Vec::new(); 112 Event::Start {
99 let mut next_tok_idx = 0; 113 kind: TOMBSTONE, ..
100 for i in 0..events.len() { 114 } => (),
101 match mem::replace(&mut events[i], tombstone()) {
102 Event::Start {
103 kind: TOMBSTONE, ..
104 } => (),
105 115
106 Event::Start { kind, forward_parent } => { 116 Event::Start { kind, forward_parent } => {
107 forward_parents.push(kind); 117 forward_parents.push(kind);
108 let mut idx = i; 118 let mut idx = i;
109 let mut fp = forward_parent; 119 let mut fp = forward_parent;
110 while let Some(fwd) = fp { 120 while let Some(fwd) = fp {
111 idx += fwd as usize; 121 idx += fwd as usize;
112 fp = match mem::replace(&mut events[idx], tombstone()) { 122 fp = match mem::replace(&mut self.events[idx], tombstone()) {
113 Event::Start { 123 Event::Start {
114 kind, 124 kind,
115 forward_parent, 125 forward_parent,
116 } => { 126 } => {
117 forward_parents.push(kind); 127 forward_parents.push(kind);
118 forward_parent 128 forward_parent
119 }, 129 },
120 _ => unreachable!(), 130 _ => unreachable!(),
121 }; 131 };
132 }
133 for kind in forward_parents.drain(..).rev() {
134 if depth > 0 {
135 self.eat_ws();
136 }
137 depth += 1;
138 self.sink.start_internal(kind);
139 }
122 } 140 }
123 for kind in forward_parents.drain(..).rev() { 141 Event::Finish => {
124 if depth > 0 { 142 depth -= 1;
125 eat_ws(&mut next_tok_idx, builder); 143 if depth == 0 {
144 self.eat_ws();
126 } 145 }
127 depth += 1; 146
128 builder.start_internal(kind); 147 self.sink.finish_internal();
129 } 148 }
130 } 149 Event::Token {
131 Event::Finish => { 150 kind,
132 depth -= 1; 151 mut n_raw_tokens,
133 if depth == 0 { 152 } => {
134 eat_ws(&mut next_tok_idx, builder); 153 self.eat_ws();
154 let mut len = 0.into();
155 for _ in 0..n_raw_tokens {
156 len += self.tokens[self.token_pos].len;
157 }
158 self.leaf(kind, len, n_raw_tokens as usize);
135 } 159 }
136 160 Event::Error { msg } => self.sink.error(msg, self.text_pos),
137 builder.finish_internal();
138 } 161 }
139 Event::Token { 162 }
140 kind, 163 self.sink
141 mut n_raw_tokens, 164 }
142 } => { 165
143 eat_ws(&mut next_tok_idx, builder); 166 fn eat_ws(&mut self) {
144 let mut len = 0.into(); 167 while let Some(&token) = self.tokens.get(self.token_pos) {
145 for _ in 0..n_raw_tokens { 168 if !token.kind.is_trivia() {
146 len += tokens[next_tok_idx].len; 169 break;
147 next_tok_idx += 1;
148 }
149 builder.leaf(kind, len);
150 } 170 }
151 Event::Error { msg } => builder.error(msg), 171 self.leaf(token.kind, token.len, 1);
152 } 172 }
153 } 173 }
174
175 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) {
176 let range = TextRange::offset_len(self.text_pos, len);
177 let text: SmolStr = self.text[range].into();
178 self.text_pos += len;
179 self.token_pos += n_tokens;
180 self.sink.leaf(kind, text);
181 }
154} 182}
diff --git a/crates/ra_syntax/src/parser_impl/mod.rs b/crates/ra_syntax/src/parser_impl/mod.rs
index b343b404f..8d74cef0e 100644
--- a/crates/ra_syntax/src/parser_impl/mod.rs
+++ b/crates/ra_syntax/src/parser_impl/mod.rs
@@ -4,45 +4,44 @@ mod input;
4use std::cell::Cell; 4use std::cell::Cell;
5 5
6use { 6use {
7 TextUnit, SmolStr,
7 lexer::Token, 8 lexer::Token,
8 parser_api::Parser, 9 parser_api::Parser,
9 parser_impl::{ 10 parser_impl::{
10 event::{process, Event}, 11 event::{EventProcessor, Event},
11 input::{InputPosition, ParserInput}, 12 input::{InputPosition, ParserInput},
12 }, 13 },
13 TextUnit,
14}; 14};
15 15
16use SyntaxKind::{self, EOF, TOMBSTONE}; 16use SyntaxKind::{self, EOF, TOMBSTONE};
17 17
18pub(crate) trait Sink<'a> { 18pub(crate) trait Sink {
19 type Tree; 19 type Tree;
20 20
21 fn new(text: &'a str) -> Self; 21 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
22
23 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
24 fn start_internal(&mut self, kind: SyntaxKind); 22 fn start_internal(&mut self, kind: SyntaxKind);
25 fn finish_internal(&mut self); 23 fn finish_internal(&mut self);
26 fn error(&mut self, err: String); 24 fn error(&mut self, message: String, offset: TextUnit);
27 fn finish(self) -> Self::Tree; 25 fn finish(self) -> Self::Tree;
28} 26}
29 27
30/// Parse a sequence of tokens into the representative node tree 28/// Parse a sequence of tokens into the representative node tree
31pub(crate) fn parse_with<'a, S: Sink<'a>>( 29pub(crate) fn parse_with<S: Sink>(
32 text: &'a str, 30 sink: S,
31 text: &str,
33 tokens: &[Token], 32 tokens: &[Token],
34 parser: fn(&mut Parser), 33 parser: fn(&mut Parser),
35) -> S::Tree { 34) -> S::Tree {
36 let events = { 35 let mut events = {
37 let input = input::ParserInput::new(text, tokens); 36 let input = input::ParserInput::new(text, tokens);
38 let parser_impl = ParserImpl::new(&input); 37 let parser_impl = ParserImpl::new(&input);
39 let mut parser_api = Parser(parser_impl); 38 let mut parser_api = Parser(parser_impl);
40 parser(&mut parser_api); 39 parser(&mut parser_api);
41 parser_api.0.into_events() 40 parser_api.0.into_events()
42 }; 41 };
43 let mut sink = S::new(text); 42 EventProcessor::new(sink, text, tokens, &mut events)
44 process(&mut sink, tokens, events); 43 .process()
45 sink.finish() 44 .finish()
46} 45}
47 46
48/// Implementation details of `Parser`, extracted 47/// Implementation details of `Parser`, extracted