Skip to content

Commit 4e458e3

Browse files
committed
Created infrastructure for new incremental parser
1 parent 23b6e25 commit 4e458e3

File tree

4 files changed

+628
-498
lines changed

4 files changed

+628
-498
lines changed

src/components/rg/src/green.rs

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
use crate::{red::ReparseInnerResult, text::TextLength};
2+
use std::sync::Arc;
3+
4+
#[derive(Clone, Debug)]
5+
pub struct GreenNodeId(usize);
6+
7+
#[derive(Clone, Debug)]
8+
pub enum GreenKind {
9+
Error,
10+
Whitespace,
11+
Punct(char),
12+
Null,
13+
True,
14+
False,
15+
Number,
16+
String,
17+
Array,
18+
Value,
19+
}
20+
21+
#[derive(Copy, Clone, Debug)]
22+
pub enum Reparse {
23+
Value,
24+
Array,
25+
}
26+
27+
impl GreenKind {
28+
pub fn can_reparse(&self) -> Option<Reparse> {
29+
match self {
30+
GreenKind::Error => None,
31+
GreenKind::Whitespace => None,
32+
GreenKind::Punct(_) => None,
33+
GreenKind::Null => None,
34+
GreenKind::True => None,
35+
GreenKind::False => None,
36+
GreenKind::Number => None,
37+
GreenKind::String => None,
38+
GreenKind::Array => Some(Reparse::Array),
39+
GreenKind::Value => Some(Reparse::Value),
40+
}
41+
}
42+
}
43+
44+
#[derive(Clone, Debug)]
45+
pub struct GreenNode {
46+
pub(crate) kind: GreenKind,
47+
pub(crate) content_bytes: TextLength,
48+
pub(crate) children: Vec<Arc<GreenNode>>,
49+
pub(crate) text: Option<String>,
50+
}
51+
52+
impl GreenNode {
53+
pub fn new_leaf(kind: GreenKind, text: String) -> Arc<GreenNode> {
54+
Arc::new(GreenNode {
55+
kind,
56+
content_bytes: TextLength(text.len()),
57+
children: vec![],
58+
text: Some(text),
59+
})
60+
}
61+
62+
pub fn new_parent(kind: GreenKind, children: Vec<Arc<GreenNode>>) -> Arc<GreenNode> {
63+
Arc::new(GreenNode {
64+
kind,
65+
content_bytes: children.iter().map(|child| child.content_bytes).sum(),
66+
children,
67+
text: None,
68+
})
69+
}
70+
71+
pub fn new_punct(c: char) -> Arc<GreenNode> {
72+
Arc::new(GreenNode {
73+
kind: GreenKind::Punct(c),
74+
content_bytes: TextLength(c.len_utf8()),
75+
children: vec![],
76+
text: Some(c.into()),
77+
})
78+
}
79+
80+
pub fn new_error(rest: String) -> Arc<GreenNode> {
81+
Arc::new(GreenNode {
82+
kind: GreenKind::Error,
83+
content_bytes: TextLength(rest.len()),
84+
children: vec![],
85+
text: Some(rest),
86+
})
87+
}
88+
89+
pub fn print(&self, depth: usize) {
90+
let padding = " ".repeat(depth * 2);
91+
match &self.text {
92+
Some(leaf) => {
93+
println!("{}{:?}: {:?}", padding, self.kind, leaf);
94+
}
95+
None => {
96+
println!("{}{:?}", padding, self.kind);
97+
for child in self.children.iter() {
98+
child.print(depth + 1);
99+
}
100+
}
101+
}
102+
}
103+
104+
pub fn flatten(&self) -> String {
105+
let mut builder = String::with_capacity(128);
106+
self.flatten_into(&mut builder);
107+
builder
108+
}
109+
110+
pub fn flatten_into(&self, s: &mut String) {
111+
self.text.as_ref().map(|text| s.push_str(text));
112+
113+
for child in self.children.iter() {
114+
child.flatten_into(s);
115+
}
116+
}
117+
118+
pub fn parse_root(content: &str) -> Arc<GreenNode> {
119+
let parsed = Self::parse_value(content);
120+
121+
if parsed.consumed.0 != content.len() {
122+
let error = Self::new_error(content[parsed.consumed.0..].into());
123+
Self::new_parent(GreenKind::Value, vec![parsed.green, error])
124+
} else {
125+
parsed.green
126+
}
127+
}
128+
129+
pub fn parse_whitespace(content: &str) -> Option<ParseResult> {
130+
let content_bytes = content
131+
.chars()
132+
.take_while(|c| c.is_ascii_whitespace())
133+
.map(|c| TextLength(c.len_utf8()))
134+
.sum::<TextLength>();
135+
136+
if content_bytes.0 != 0 {
137+
Some(ParseResult {
138+
green: Self::new_leaf(GreenKind::Whitespace, content[..content_bytes.0].into()),
139+
consumed: content_bytes,
140+
})
141+
} else {
142+
None
143+
}
144+
}
145+
146+
pub fn parse_keyword(content: &str, kind: GreenKind, kw: &str) -> Option<ParseResult> {
147+
if content.starts_with(kw) {
148+
Some(ParseResult {
149+
green: Self::new_leaf(kind, kw.into()),
150+
consumed: TextLength(kw.len()),
151+
})
152+
} else {
153+
None
154+
}
155+
}
156+
157+
pub fn parse_punct(content: &str) -> Option<ParseResult> {
158+
for c in [',', '[', ']', '{', '}', ':'] {
159+
if content.starts_with(c) {
160+
return Some(ParseResult {
161+
green: Self::new_leaf(GreenKind::Punct(c), c.into()),
162+
consumed: TextLength(c.len_utf8()),
163+
});
164+
}
165+
}
166+
None
167+
}
168+
169+
pub fn parse_number(content: &str) -> Option<ParseResult> {
170+
let content_bytes = content
171+
.chars()
172+
.take_while(|c| c.is_ascii_digit())
173+
.map(|c| TextLength(c.len_utf8()))
174+
.sum::<TextLength>();
175+
176+
if content_bytes.0 != 0 {
177+
Some(ParseResult {
178+
green: Self::new_leaf(GreenKind::Number, content[..content_bytes.0].into()),
179+
consumed: content_bytes,
180+
})
181+
} else {
182+
None
183+
}
184+
}
185+
186+
pub fn parse_string(content: &str) -> Option<ParseResult> {
187+
let mut chars = content.chars();
188+
189+
if chars.next() != Some('"') {
190+
return None;
191+
}
192+
193+
let mut has_end = false;
194+
let mut content_bytes = (&mut chars)
195+
.take_while(|c| {
196+
if *c == '"' {
197+
has_end = true;
198+
false
199+
} else {
200+
true
201+
}
202+
})
203+
.map(|c| TextLength(c.len_utf8()))
204+
.sum::<TextLength>();
205+
206+
content_bytes += TextLength(1 + has_end as usize);
207+
208+
if !has_end {
209+
return Some(ParseResult {
210+
green: Self::new_error(content[content_bytes.0..].into()),
211+
consumed: content_bytes,
212+
});
213+
}
214+
215+
Some(ParseResult {
216+
green: Self::new_leaf(GreenKind::String, content[..content_bytes.0].into()),
217+
consumed: content_bytes,
218+
})
219+
}
220+
221+
pub fn parse_value(mut content: &str) -> ParseResult {
222+
let mut children = Vec::new();
223+
224+
if let Some(ws) = Self::parse_whitespace(&content) {
225+
children.push(ws.green);
226+
content = &content[ws.consumed.0..];
227+
}
228+
229+
if let Some(inner) = Self::parse_array(content) {
230+
children.push(inner.green);
231+
content = &content[inner.consumed.0..];
232+
} else if let Some(inner) = Self::parse_string(content) {
233+
children.push(inner.green);
234+
content = &content[inner.consumed.0..];
235+
} else if let Some(inner) = Self::parse_number(content) {
236+
children.push(inner.green);
237+
content = &content[inner.consumed.0..];
238+
} else if let Some(inner) = Self::parse_keyword(content, GreenKind::True, "true") {
239+
children.push(inner.green);
240+
content = &content[inner.consumed.0..];
241+
} else if let Some(inner) = Self::parse_keyword(content, GreenKind::False, "false") {
242+
children.push(inner.green);
243+
content = &content[inner.consumed.0..];
244+
} else if let Some(inner) = Self::parse_keyword(content, GreenKind::Null, "null") {
245+
children.push(inner.green);
246+
content = &content[inner.consumed.0..];
247+
} else if let Some(inner) = Self::parse_punct(content) {
248+
children.push(inner.green);
249+
content = &content[inner.consumed.0..];
250+
} else {
251+
children.push(Self::new_error(content.into()));
252+
content = &content[content.len()..];
253+
}
254+
255+
if let Some(ws) = Self::parse_whitespace(&content) {
256+
children.push(ws.green);
257+
content = &content[ws.consumed.0..];
258+
}
259+
260+
ParseResult {
261+
consumed: children.iter().map(|child| child.content_bytes).sum(),
262+
green: Self::new_parent(GreenKind::Value, children),
263+
}
264+
}
265+
266+
pub fn parse_array(mut content: &str) -> Option<ParseResult> {
267+
let mut chars = content.chars();
268+
let mut children = Vec::new();
269+
270+
if chars.next() != Some('[') {
271+
return None;
272+
}
273+
274+
children.push(Self::new_punct('['));
275+
content = &content[1..];
276+
277+
if content.starts_with(']') {
278+
children.push(Self::new_punct(']'));
279+
return Some(ParseResult {
280+
green: Self::new_parent(GreenKind::Array, children),
281+
consumed: TextLength(2),
282+
});
283+
}
284+
285+
loop {
286+
// Missing closing bracket
287+
if content.is_empty() {
288+
children.push(Self::new_error(content.into()));
289+
290+
return Some(ParseResult {
291+
consumed: children.iter().map(|child| child.content_bytes).sum(),
292+
green: Self::new_parent(GreenKind::Array, children),
293+
});
294+
}
295+
296+
let value = Self::parse_value(content);
297+
298+
children.push(value.green);
299+
content = &content[value.consumed.0..];
300+
301+
if content.starts_with(',') {
302+
children.push(Self::new_punct(','));
303+
content = &content[1..];
304+
continue;
305+
} else if content.starts_with(']') {
306+
children.push(Self::new_punct(']'));
307+
content = &content[1..];
308+
break;
309+
} else {
310+
// Missing comma or bracket
311+
children.push(Self::new_error(content.into()));
312+
content = &content[content.len()..];
313+
break;
314+
}
315+
}
316+
317+
Some(ParseResult {
318+
consumed: children.iter().map(|child| child.content_bytes).sum(),
319+
green: Self::new_parent(GreenKind::Array, children),
320+
})
321+
}
322+
323+
pub fn reparse_as(reparse: Reparse, content: &str) -> ReparseInnerResult {
324+
let parsed = match reparse {
325+
Reparse::Value => Self::parse_value(content),
326+
Reparse::Array => {
327+
if let Some(array) = Self::parse_array(content) {
328+
array
329+
} else {
330+
Self::parse_value(content)
331+
}
332+
}
333+
};
334+
335+
if parsed.consumed.0 != content.len() {
336+
ReparseInnerResult::ReparseParent
337+
} else {
338+
ReparseInnerResult::Reparsed(parsed.green)
339+
}
340+
}
341+
}
342+
343+
#[derive(Clone, Debug)]
344+
pub struct ParseResult {
345+
green: Arc<GreenNode>,
346+
consumed: TextLength,
347+
}

0 commit comments

Comments
 (0)