aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parsing/parser_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parsing/parser_impl.rs')
-rw-r--r--crates/ra_syntax/src/parsing/parser_impl.rs200
1 files changed, 0 insertions, 200 deletions
diff --git a/crates/ra_syntax/src/parsing/parser_impl.rs b/crates/ra_syntax/src/parsing/parser_impl.rs
deleted file mode 100644
index 8cce1ab01..000000000
--- a/crates/ra_syntax/src/parsing/parser_impl.rs
+++ /dev/null
@@ -1,200 +0,0 @@
1mod event;
2mod input;
3
4use std::cell::Cell;
5
6use crate::{
7 SmolStr,
8 syntax_error::{ParseError, SyntaxError},
9 parsing::{
10 lexer::Token,
11 parser_api::Parser,
12 parser_impl::{
13 event::{Event, EventProcessor},
14 input::{InputPosition, ParserInput},
15 },
16 },
17};
18
19use crate::SyntaxKind::{self, EOF, TOMBSTONE};
20
21pub(super) trait Sink {
22 type Tree;
23
24 /// Adds new leaf to the current branch.
25 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
26
27 /// Start new branch and make it current.
28 fn start_branch(&mut self, kind: SyntaxKind);
29
30 /// Finish current branch and restore previous
31 /// branch as current.
32 fn finish_branch(&mut self);
33
34 fn error(&mut self, error: SyntaxError);
35
36 /// Complete tree building. Make sure that
37 /// `start_branch` and `finish_branch` calls
38 /// are paired!
39 fn finish(self) -> Self::Tree;
40}
41
42/// Parse a sequence of tokens into the representative node tree
43pub(super) fn parse_with<S: Sink>(
44 sink: S,
45 text: &str,
46 tokens: &[Token],
47 parser: fn(&mut Parser),
48) -> S::Tree {
49 let mut events = {
50 let input = input::ParserInput::new(text, tokens);
51 let parser_impl = ParserImpl::new(&input);
52 let mut parser_api = Parser(parser_impl);
53 parser(&mut parser_api);
54 parser_api.0.into_events()
55 };
56 EventProcessor::new(sink, text, tokens, &mut events).process().finish()
57}
58
59/// Implementation details of `Parser`, extracted
60/// to a separate struct in order not to pollute
61/// the public API of the `Parser`.
62pub(super) struct ParserImpl<'t> {
63 parser_input: &'t ParserInput<'t>,
64 pos: InputPosition,
65 events: Vec<Event>,
66 steps: Cell<u32>,
67}
68
69impl<'t> ParserImpl<'t> {
70 fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> {
71 ParserImpl {
72 parser_input: inp,
73 pos: InputPosition::new(),
74 events: Vec::new(),
75 steps: Cell::new(0),
76 }
77 }
78
79 fn into_events(self) -> Vec<Event> {
80 assert_eq!(self.nth(0), EOF);
81 self.events
82 }
83
84 pub(super) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
85 let c1 = self.parser_input.kind(self.pos);
86 let c2 = self.parser_input.kind(self.pos + 1);
87 if self.parser_input.token_start_at(self.pos + 1)
88 == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos)
89 {
90 Some((c1, c2))
91 } else {
92 None
93 }
94 }
95
96 pub(super) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
97 let c1 = self.parser_input.kind(self.pos);
98 let c2 = self.parser_input.kind(self.pos + 1);
99 let c3 = self.parser_input.kind(self.pos + 2);
100 if self.parser_input.token_start_at(self.pos + 1)
101 == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos)
102 && self.parser_input.token_start_at(self.pos + 2)
103 == self.parser_input.token_start_at(self.pos + 1)
104 + self.parser_input.token_len(self.pos + 1)
105 {
106 Some((c1, c2, c3))
107 } else {
108 None
109 }
110 }
111
112 /// Get the syntax kind of the nth token.
113 pub(super) fn nth(&self, n: u32) -> SyntaxKind {
114 let steps = self.steps.get();
115 assert!(steps <= 10_000_000, "the parser seems stuck");
116 self.steps.set(steps + 1);
117
118 self.parser_input.kind(self.pos + n)
119 }
120
121 pub(super) fn at_kw(&self, t: &str) -> bool {
122 self.parser_input.token_text(self.pos) == t
123 }
124
125 /// Start parsing right behind the last event.
126 pub(super) fn start(&mut self) -> u32 {
127 let pos = self.events.len() as u32;
128 self.push_event(Event::tombstone());
129 pos
130 }
131
132 /// Advances the parser by one token unconditionally.
133 pub(super) fn bump(&mut self) {
134 let kind = self.nth(0);
135 if kind == EOF {
136 return;
137 }
138 self.do_bump(kind, 1);
139 }
140
141 pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
142 if self.nth(0) == EOF {
143 // TODO: panic!?
144 return;
145 }
146 self.do_bump(kind, 1);
147 }
148
149 pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
150 self.do_bump(kind, n);
151 }
152
153 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
154 self.pos += u32::from(n_raw_tokens);
155 self.push_event(Event::Token { kind, n_raw_tokens });
156 }
157
158 /// Append one Error event to the back of events.
159 pub(super) fn error(&mut self, msg: String) {
160 self.push_event(Event::Error { msg: ParseError(msg) })
161 }
162
163 /// Complete an event with appending a `Finish` event.
164 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
165 match self.events[pos as usize] {
166 Event::Start { kind: ref mut slot, .. } => {
167 *slot = kind;
168 }
169 _ => unreachable!(),
170 }
171 self.push_event(Event::Finish);
172 }
173
174 /// Ignore the dummy `Start` event.
175 pub(super) fn abandon(&mut self, pos: u32) {
176 let idx = pos as usize;
177 if idx == self.events.len() - 1 {
178 match self.events.pop() {
179 Some(Event::Start { kind: TOMBSTONE, forward_parent: None }) => (),
180 _ => unreachable!(),
181 }
182 }
183 }
184
185 /// Save the relative distance of a completed event to its forward_parent.
186 pub(super) fn precede(&mut self, pos: u32) -> u32 {
187 let new_pos = self.start();
188 match self.events[pos as usize] {
189 Event::Start { ref mut forward_parent, .. } => {
190 *forward_parent = Some(new_pos - pos);
191 }
192 _ => unreachable!(),
193 }
194 new_pos
195 }
196
197 fn push_event(&mut self, event: Event) {
198 self.events.push(event)
199 }
200}