1use std::borrow::Borrow;
2use std::fmt::Debug;
3use std::hash::Hash;
4use std::ops::{Deref, DerefMut};
5
6use logos::{Lexer, Logos};
7pub use parser::*;
8
9mod a_star;
10pub use a_star::Fingerprint;
11pub use a_star::ParseMode;
12pub use a_star::ParserTrait;
13pub mod list;
14pub mod model;
15pub mod format;
16pub mod jsonld;
17pub mod n3;
18pub mod ntriples;
19mod parser;
20pub mod sparql;
21pub mod trig;
22pub mod turtle;
23pub mod util;
24
25#[derive(Debug, Clone)]
26pub struct Spanned<T>(pub T, pub std::ops::Range<usize>);
27impl<T> Default for Spanned<T>
28where
29 T: Default,
30{
31 fn default() -> Self {
32 Self(T::default(), 0..1)
33 }
34}
35impl Borrow<str> for Spanned<String> {
36 #[inline]
37 fn borrow(&self) -> &str {
38 &self[..]
39 }
40}
41
42impl<T> Deref for Spanned<T> {
43 type Target = T;
44
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49
50impl<T> DerefMut for Spanned<T> {
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.0
53 }
54}
55impl<T: PartialEq> PartialEq for Spanned<T> {
56 fn eq(&self, other: &Self) -> bool {
57 self.0.eq(&other.0)
58 }
59}
60impl<T: std::hash::Hash> std::hash::Hash for Spanned<T> {
61 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
62 self.0.hash(state)
63 }
64}
65impl<T: PartialEq> Eq for Spanned<T> {}
66
67impl<T> Spanned<T> {
68 pub fn into_value(self) -> T {
69 self.0
70 }
71 pub fn into_span(self) -> std::ops::Range<usize> {
72 self.1
73 }
74 pub fn value(&self) -> &T {
75 &self.0
76 }
77 pub fn value_mut(&mut self) -> &mut T {
78 &mut self.0
79 }
80 pub fn span(&self) -> &std::ops::Range<usize> {
81 &self.1
82 }
83
84 pub fn map<O>(self, f: impl Fn(T) -> O) -> Spanned<O> {
85 Spanned(f(self.0), self.1)
86 }
87 pub fn map_ref<'a, O: 'a>(&'a self, f: impl Fn(&'a T) -> O) -> Spanned<O> {
88 Spanned(f(&self.0), self.1.clone())
89 }
90 pub fn as_ref(&self) -> Spanned<&T> {
91 Spanned(&self.0, self.1.clone())
92 }
93 pub fn try_map_ref<'a, O>(&'a self, f: impl FnOnce(&'a T) -> Option<O>) -> Option<Spanned<O>> {
94 f(&self.0).map(|v| Spanned(v, self.1.clone()))
95 }
96 pub fn try_map<O>(self, f: impl FnOnce(T) -> Option<O>) -> Option<Spanned<O>> {
97 f(self.0).map(|v| Spanned(v, self.1))
98 }
99}
100
101impl<T> Spanned<Option<T>> {
102 pub fn transpose(self) -> Option<Spanned<T>> {
103 self.0.map(|inner| Spanned(inner, self.1))
104 }
105}
106
107pub fn spanned<T>(t: T, span: std::ops::Range<usize>) -> Spanned<T> {
108 Spanned(t, span)
109}
110
111pub trait TokenTrait:
112 Debug + Clone + Into<rowan::SyntaxKind> + From<rowan::SyntaxKind> + PartialEq + Eq + Hash + 'static
113{
114 const ERROR: Self;
115 const ROOT: Self;
116
117 fn branch(&self) -> u32;
118
119 fn skips(&self) -> bool;
120
121 fn starting_tokens(&self) -> &'static [Self];
122 fn ending_tokens(&self) -> &'static [Self];
123
124 fn min_error_for_token(&self, _tok: &Self) -> isize {
133 0
134 }
135
136
137 fn max_error_value(&self) -> isize {
145 2
146 }
147
148 fn min_completion_cost(&self) -> isize {
153 self.max_error_value()
154 }
155
156 fn deletion_cost(&self) -> isize {
162 self.max_error_value() * 5
163 }
164
165 fn bracket_delta(&self) -> i8 {
173 0
174 }
175}
176
177pub fn tokenize<'a, K>(text: &'a str) -> Vec<FatToken<K>>
178where
179 K: TokenTrait + Logos<'a, Source = str>,
180 <K as Logos<'a>>::Extras: Default,
181{
182 let mut lexer: Lexer<'a, K> = Lexer::new(text);
183 let mut tokens: Vec<FatToken<K>> = Vec::new();
184 while let Some(t) = lexer.next() {
185 let kind = t.unwrap_or(K::ERROR);
186 let span = lexer.span();
187 if kind == K::ERROR {
188 if let Some(last) = tokens.last_mut() {
189 if last.kind == K::ERROR {
190 let start = last.range.start;
191 last.extend_to(span.end, text[start..span.end].to_string());
192 continue;
193 }
194 }
195 }
196 tokens.push(FatToken::new(kind, span.clone(), text[span].to_string()));
197 }
198 tokens
199}
200
201pub fn parse<'a, T: a_star::ParserTrait + 'static>(
202 root: T,
203 text: &'a str,
204) -> (Parse, Vec<FatToken<T::Kind>>)
205where
206 T::Kind: Logos<'a, Source = str>,
207 <<T as a_star::ParserTrait>::Kind as Logos<'a>>::Extras: Default,
208{
209 let mut tokens = tokenize::<T::Kind>(text);
210 let list = a_star::a_star(
211 root,
212 &tokens,
213 IncrementalBias::default(),
214 a_star::DEFAULT_MAX_ITERATIONS,
215 );
216 let parse = Parse::from_steps(&mut tokens, list);
217 (parse, tokens)
218}
219
220pub fn parse_fast<'a, T: a_star::ParserTrait + 'static>(
228 root: T,
229 text: &'a str,
230) -> Option<(Parse, Vec<FatToken<T::Kind>>)>
231where
232 T::Kind: Logos<'a, Source = str>,
233 <<T as a_star::ParserTrait>::Kind as Logos<'a>>::Extras: Default,
234{
235 let mut tokens = tokenize::<T::Kind>(text);
236 let list = a_star::a_star_fast(root, &tokens)?;
237 let parse = Parse::from_steps(&mut tokens, list);
238 Some((parse, tokens))
239}
240
241pub struct PrevToken {
244 pub text: String,
245 pub fingerprint: Option<Fingerprint>,
246 pub depth: u8,
250}
251
252pub struct PrevParseInfo {
254 pub tokens: Vec<PrevToken>,
255 pub had_errors: bool,
261}
262
263#[derive(Debug, Clone, Copy)]
269pub struct IncrementalBias {
270 pub strength: isize,
274}
275
276impl Default for IncrementalBias {
277 fn default() -> Self {
278 Self { strength: 1 }
279 }
280}
281
282pub fn parse_incremental<'a, T: a_star::ParserTrait + Clone + 'static>(
295 root: T,
296 text: &'a str,
297 prev: Option<&PrevParseInfo>,
298 bias: IncrementalBias,
299) -> (Parse, PrevParseInfo)
300where
301 T::Kind: Logos<'a, Source = str>,
302 <<T as a_star::ParserTrait>::Kind as Logos<'a>>::Extras: Default,
303{
304 if let Some((parse, tokens)) = parse_fast(root.clone(), text) {
306 let mut depth = 0i32;
307 let prev_info = PrevParseInfo {
308 tokens: tokens.iter().map(|t| {
309 let d = depth.clamp(0, 255) as u8;
310 depth += t.kind.bracket_delta() as i32;
311 t.to_prev_token(d)
312 }).collect(),
313 had_errors: false,
314 };
315 return (parse, prev_info);
316 }
317
318 let mut tokens = tokenize::<T::Kind>(text);
319
320 if let Some(prev) = prev {
321 let old_texts: Vec<&str> = prev.tokens.iter().map(|t| t.text.as_str()).collect();
323 let new_texts: Vec<&str> = tokens.iter().map(|t| t.text()).collect();
324
325 use similar::{Algorithm, DiffOp, capture_diff_slices};
327 let ops = capture_diff_slices(Algorithm::Myers, &old_texts, &new_texts);
328 let mut new_to_old = std::collections::HashMap::<usize, usize>::new();
329 for op in &ops {
330 if let DiffOp::Equal {
331 old_index,
332 new_index,
333 len,
334 } = op
335 {
336 for i in 0..*len {
337 new_to_old.insert(new_index + i, old_index + i);
338 }
339 }
340 }
341
342 for (new_idx, tok) in tokens.iter_mut().enumerate() {
348 if let Some(&old_idx) = new_to_old.get(&new_idx) {
349 if let Some(prev_tok) = prev.tokens.get(old_idx) {
350 tok.set_old_kind(prev_tok.fingerprint);
351 tok.set_old_depth(Some(prev_tok.depth));
352 }
353 }
354 }
355 }
356
357 let list = a_star::a_star(root, &tokens, bias, a_star::DEFAULT_MAX_ITERATIONS);
358 let parse = Parse::from_steps(&mut tokens, list);
359 let had_errors = parse.errors.len() > 0;
360 let mut depth: i32 = 0;
362 let prev = PrevParseInfo {
363 tokens: tokens
364 .iter()
365 .map(|t| {
366 let d = depth.clamp(0, 255) as u8;
367 depth += t.kind.bracket_delta() as i32;
368 t.to_prev_token(d)
369 })
370 .collect(),
371 had_errors,
372 };
373 (parse, prev)
374}