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