/rust/registry/src/index.crates.io-1949cf8c6b5b557f/antlr4rust-0.6.0/src/prediction_context.rs
Line | Count | Source |
1 | | use std::borrow::Cow; |
2 | | use std::collections::HashMap; |
3 | | use std::fmt::{Display, Error, Formatter}; |
4 | | use std::hash::{BuildHasher, Hash, Hasher}; |
5 | | use std::ops::Deref; |
6 | | |
7 | | use std::sync::{Arc, RwLock}; |
8 | | |
9 | | use murmur3::murmur3_32::MurmurHasher; |
10 | | |
11 | | use crate::atn::ATN; |
12 | | use crate::dfa::ScopeExt; |
13 | | use crate::parser::ParserNodeType; |
14 | | use crate::parser_atn_simulator::MergeCache; |
15 | | |
16 | | use crate::prediction_context::PredictionContext::{Array, Singleton}; |
17 | | use crate::rule_context::RuleContext; |
18 | | |
19 | | use crate::transition::RuleTransition; |
20 | | |
21 | | pub const PREDICTION_CONTEXT_EMPTY_RETURN_STATE: i32 = 0x7FFFFFFF; |
22 | | |
23 | | #[cfg(test)] |
24 | | mod test; |
25 | | |
26 | | //todo make return states ATNStateRef |
27 | | #[derive(Eq, Clone, Debug)] |
28 | | pub enum PredictionContext { |
29 | | Singleton(SingletonPredictionContext), |
30 | | Array(ArrayPredictionContext), |
31 | | } |
32 | | |
33 | | impl PartialEq for PredictionContext { |
34 | 8.57M | fn eq(&self, other: &Self) -> bool { |
35 | 8.57M | match (self, other) { |
36 | 0 | (Array(s), Array(o)) => *s == *o, |
37 | 8.57M | (Singleton(s), Singleton(o)) => *s == *o, |
38 | 0 | _ => false, |
39 | | } |
40 | 8.57M | } |
41 | | } |
42 | | |
43 | | #[derive(Eq, Clone, Debug)] |
44 | | pub struct ArrayPredictionContext { |
45 | | cached_hash: i32, |
46 | | return_states: Vec<i32>, |
47 | | parents: Vec<Option<Arc<PredictionContext>>>, |
48 | | } |
49 | | |
50 | | impl PartialEq for ArrayPredictionContext { |
51 | | #[inline(always)] |
52 | 0 | fn eq(&self, other: &Self) -> bool { |
53 | 0 | self.cached_hash == other.cached_hash |
54 | 0 | && self.return_states == other.return_states |
55 | 0 | && self.parents.iter().zip(other.parents.iter()).all(opt_eq) |
56 | 0 | } |
57 | | } |
58 | | |
59 | | #[inline(always)] |
60 | 5.16M | fn opt_eq( |
61 | 5.16M | arg: ( |
62 | 5.16M | &Option<Arc<PredictionContext>>, |
63 | 5.16M | &Option<Arc<PredictionContext>>, |
64 | 5.16M | ), |
65 | 5.16M | ) -> bool { |
66 | 68.6k | match arg { |
67 | 5.09M | (Some(s), Some(o)) => Arc::ptr_eq(s, o) || *s == *o, |
68 | 68.6k | (None, None) => true, |
69 | 0 | _ => false, |
70 | | } |
71 | 5.16M | } |
72 | | |
73 | | #[derive(Eq, Clone, Debug)] |
74 | | pub struct SingletonPredictionContext { |
75 | | cached_hash: i32, |
76 | | return_state: i32, |
77 | | parent_ctx: Option<Arc<PredictionContext>>, |
78 | | } |
79 | | |
80 | | impl PartialEq for SingletonPredictionContext { |
81 | | #[inline(always)] |
82 | 8.57M | fn eq(&self, other: &Self) -> bool { |
83 | 8.57M | self.cached_hash == other.cached_hash |
84 | 5.16M | && self.return_state == other.return_state |
85 | 5.16M | && opt_eq((&self.parent_ctx, &other.parent_ctx)) |
86 | 8.57M | } |
87 | | } |
88 | | |
89 | | impl SingletonPredictionContext { |
90 | | #[inline(always)] |
91 | 5.06M | fn is_empty(&self) -> bool { |
92 | 5.06M | self.return_state == PREDICTION_CONTEXT_EMPTY_RETURN_STATE && self.parent_ctx.is_none() |
93 | 5.06M | } |
94 | | } |
95 | | |
96 | | impl Display for PredictionContext { |
97 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { |
98 | 0 | match self { |
99 | 0 | Singleton(s) => { |
100 | 0 | if s.return_state == PREDICTION_CONTEXT_EMPTY_RETURN_STATE { |
101 | 0 | f.write_str("$") |
102 | 0 | } else if let Some(parent) = &s.parent_ctx { |
103 | 0 | f.write_fmt(format_args!("{} {}", s.return_state, parent)) |
104 | | } else { |
105 | 0 | f.write_fmt(format_args!("{}", s.return_state)) |
106 | | } |
107 | | } |
108 | 0 | Array(arr) => { |
109 | 0 | f.write_str("[")?; |
110 | 0 | for i in 0..arr.return_states.len() { |
111 | 0 | if i > 0 { |
112 | 0 | f.write_str(", ")?; |
113 | 0 | } |
114 | 0 | if arr.return_states[i] == PREDICTION_CONTEXT_EMPTY_RETURN_STATE { |
115 | 0 | f.write_str("$")?; |
116 | 0 | } |
117 | 0 | f.write_str(&arr.return_states[i].to_string())?; |
118 | 0 | if let Some(parent) = &arr.parents[i] { |
119 | 0 | f.write_fmt(format_args!(" {}", parent))?; |
120 | | } else { |
121 | 0 | f.write_str(" null")?; |
122 | | } |
123 | | } |
124 | | |
125 | 0 | f.write_str("]") |
126 | | } |
127 | | } |
128 | 0 | } |
129 | | } |
130 | | |
131 | | //impl PartialEq for PredictionContext { |
132 | | // fn eq(&self, other: &Self) -> bool { |
133 | | // self.hash_code() == other.hash_code() |
134 | | // } |
135 | | //} |
136 | | |
137 | | impl Hash for PredictionContext { |
138 | 22.4M | fn hash<H: Hasher>(&self, state: &mut H) { |
139 | 22.4M | state.write_i32(self.hash_code()) |
140 | 22.4M | } <antlr4rust::prediction_context::PredictionContext as core::hash::Hash>::hash::<murmur3::murmur3_32::MurmurHasher> Line | Count | Source | 138 | 3.67M | fn hash<H: Hasher>(&self, state: &mut H) { | 139 | 3.67M | state.write_i32(self.hash_code()) | 140 | 3.67M | } |
<antlr4rust::prediction_context::PredictionContext as core::hash::Hash>::hash::<std::hash::random::DefaultHasher> Line | Count | Source | 138 | 18.7M | fn hash<H: Hasher>(&self, state: &mut H) { | 139 | 18.7M | state.write_i32(self.hash_code()) | 140 | 18.7M | } |
|
141 | | } |
142 | | |
143 | | lazy_static! { |
144 | | pub static ref EMPTY_PREDICTION_CONTEXT: Arc<PredictionContext> = |
145 | | Arc::new(PredictionContext::new_empty()); |
146 | | } |
147 | | |
148 | | impl PredictionContext { |
149 | 0 | pub fn new_array( |
150 | 0 | parents: Vec<Option<Arc<PredictionContext>>>, |
151 | 0 | return_states: Vec<i32>, |
152 | 0 | ) -> PredictionContext { |
153 | 0 | PredictionContext::Array(ArrayPredictionContext { |
154 | 0 | cached_hash: 0, |
155 | 0 | parents, |
156 | 0 | return_states, |
157 | 0 | }) |
158 | 0 | } |
159 | | |
160 | 25.0M | pub fn new_singleton( |
161 | 25.0M | parent_ctx: Option<Arc<PredictionContext>>, |
162 | 25.0M | return_state: i32, |
163 | 25.0M | ) -> PredictionContext { |
164 | 25.0M | PredictionContext::Singleton(SingletonPredictionContext { |
165 | 25.0M | cached_hash: 0, |
166 | 25.0M | parent_ctx, |
167 | 25.0M | return_state, |
168 | 25.0M | }) |
169 | 25.0M | .modify_with(|x| x.calc_hash()) |
170 | 25.0M | } |
171 | | |
172 | 2 | pub fn new_empty() -> PredictionContext { |
173 | 2 | let mut ctx = PredictionContext::Singleton(SingletonPredictionContext { |
174 | 2 | cached_hash: 0, |
175 | 2 | parent_ctx: None, |
176 | 2 | return_state: PREDICTION_CONTEXT_EMPTY_RETURN_STATE, |
177 | 2 | }); |
178 | 2 | ctx.calc_hash(); |
179 | 2 | ctx |
180 | 2 | } |
181 | | |
182 | 47.3M | pub fn calc_hash(&mut self) { |
183 | 47.3M | let mut hasher = MurmurHasher::default(); |
184 | 47.3M | match self { |
185 | | PredictionContext::Singleton(SingletonPredictionContext { |
186 | 47.3M | parent_ctx, |
187 | 47.3M | return_state, |
188 | | .. |
189 | | }) => { |
190 | 47.3M | hasher.write_i32(match parent_ctx { |
191 | 28 | None => 0, |
192 | 47.3M | Some(x) => x.hash_code(), |
193 | | }); |
194 | 47.3M | hasher.write_i32(*return_state as i32); |
195 | | } |
196 | | PredictionContext::Array(ArrayPredictionContext { |
197 | 0 | parents, |
198 | 0 | return_states, |
199 | | .. |
200 | | }) => { |
201 | 0 | parents.iter().for_each(|x| { |
202 | 0 | hasher.write_i32(match x { |
203 | 0 | None => 0, |
204 | 0 | Some(x) => x.hash_code(), |
205 | | }) |
206 | 0 | }); |
207 | 0 | return_states |
208 | 0 | .iter() |
209 | 0 | .for_each(|x| hasher.write_i32(*x as i32)); |
210 | | } // PredictionContext::Empty { .. } => {} |
211 | | }; |
212 | | |
213 | 47.3M | let hash = hasher.finish() as i32; |
214 | | |
215 | 47.3M | match self { |
216 | 47.3M | PredictionContext::Singleton(SingletonPredictionContext { cached_hash, .. }) |
217 | 0 | | PredictionContext::Array(ArrayPredictionContext { cached_hash, .. }) |
218 | | // | PredictionContext::Empty { cached_hash, .. } |
219 | 47.3M | => *cached_hash = hash, |
220 | | }; |
221 | 47.3M | } |
222 | | |
223 | 3.72M | pub fn get_parent(&self, index: usize) -> Option<&Arc<PredictionContext>> { |
224 | 3.72M | match self { |
225 | 3.72M | PredictionContext::Singleton(singleton) => { |
226 | | // assert_eq!(index, 0); |
227 | 3.72M | singleton.parent_ctx.as_ref() |
228 | | } |
229 | 0 | PredictionContext::Array(array) => array.parents[index].as_ref(), |
230 | | } |
231 | 3.72M | } |
232 | | |
233 | 15.2M | pub fn get_return_state(&self, index: usize) -> i32 { |
234 | 15.2M | match self { |
235 | 15.2M | PredictionContext::Singleton(SingletonPredictionContext { return_state, .. }) => { |
236 | 15.2M | *return_state |
237 | | } |
238 | 0 | PredictionContext::Array(ArrayPredictionContext { return_states, .. }) => { |
239 | 0 | return_states[index] |
240 | | } |
241 | | } |
242 | 15.2M | } |
243 | | |
244 | 11.3M | pub fn length(&self) -> usize { |
245 | 11.3M | match self { |
246 | 11.3M | PredictionContext::Singleton { .. } => 1, |
247 | 0 | PredictionContext::Array(ArrayPredictionContext { return_states, .. }) => { |
248 | 0 | return_states.len() |
249 | | } |
250 | | } |
251 | 11.3M | } |
252 | | |
253 | | #[inline(always)] |
254 | 5.06M | pub fn is_empty(&self) -> bool { |
255 | 5.06M | if let PredictionContext::Singleton(singleton) = self { |
256 | 5.06M | return singleton.is_empty(); |
257 | 0 | } |
258 | 0 | self.get_return_state(0) == PREDICTION_CONTEXT_EMPTY_RETURN_STATE |
259 | 5.06M | } |
260 | | |
261 | | #[inline(always)] |
262 | 2.86M | pub fn has_empty_path(&self) -> bool { |
263 | 2.86M | self.get_return_state(self.length() - 1) == PREDICTION_CONTEXT_EMPTY_RETURN_STATE |
264 | 2.86M | } |
265 | | |
266 | | #[inline(always)] |
267 | 69.7M | pub fn hash_code(&self) -> i32 { |
268 | 69.7M | match self { |
269 | 69.7M | PredictionContext::Singleton(SingletonPredictionContext { cached_hash, .. }) |
270 | 69.7M | | PredictionContext::Array(ArrayPredictionContext { cached_hash, .. }) => *cached_hash, |
271 | | } |
272 | 69.7M | } |
273 | | |
274 | 0 | fn to_array(&self) -> Cow<'_, ArrayPredictionContext> { |
275 | 0 | match self { |
276 | 0 | PredictionContext::Singleton(s) => Cow::Owned(ArrayPredictionContext { |
277 | 0 | cached_hash: 0, |
278 | 0 | parents: vec![s.parent_ctx.clone()], |
279 | 0 | return_states: vec![s.return_state], |
280 | 0 | }), |
281 | 0 | PredictionContext::Array(arr) => Cow::Borrowed(arr), |
282 | | } |
283 | 0 | } |
284 | | |
285 | | #[inline(always)] |
286 | 22.2M | pub fn alloc(mut self) -> Arc<PredictionContext> { |
287 | 22.2M | self.calc_hash(); |
288 | 22.2M | Arc::new(self) |
289 | 22.2M | } |
290 | | |
291 | 317 | pub fn merge( |
292 | 317 | a: &Arc<PredictionContext>, |
293 | 317 | b: &Arc<PredictionContext>, |
294 | 317 | root_is_wildcard: bool, |
295 | 317 | merge_cache: &mut Option<&mut MergeCache>, |
296 | 317 | // eq_hash:&mut HashSet<(*const PredictionContext,*const PredictionContext)> |
297 | 317 | ) -> Arc<PredictionContext> { |
298 | 317 | if Arc::ptr_eq(a, b) || **a == **b { |
299 | 317 | return a.clone(); |
300 | 0 | } |
301 | | |
302 | 0 | if let Some(cache) = merge_cache { |
303 | 0 | if let Some(old) = cache |
304 | 0 | .get(&(a.clone(), b.clone())) |
305 | 0 | .or_else(|| cache.get(&(b.clone(), a.clone()))) |
306 | | { |
307 | | // if let Some(old) = cache.get(a) |
308 | | // .and_then(|it|it.get(b)) |
309 | | // .or_else(||cache.get(b).and_then(|it|it.get(a))){ |
310 | 0 | return old.clone(); |
311 | 0 | } |
312 | 0 | } |
313 | | // println!("merging {} {}",a,b); |
314 | | |
315 | 0 | let r = match (a.deref(), b.deref()) { |
316 | 0 | (PredictionContext::Singleton(sa), PredictionContext::Singleton(sb)) => { |
317 | | // println!("single result = {}",result); |
318 | 0 | Self::merge_singletons(sa, sb, root_is_wildcard, merge_cache) |
319 | | } |
320 | 0 | (sa, sb) => { |
321 | 0 | if root_is_wildcard { |
322 | 0 | if sa.is_empty() { |
323 | 0 | return EMPTY_PREDICTION_CONTEXT.clone(); |
324 | 0 | } |
325 | 0 | if sb.is_empty() { |
326 | 0 | return EMPTY_PREDICTION_CONTEXT.clone(); |
327 | 0 | } |
328 | 0 | } |
329 | | |
330 | 0 | let result = |
331 | 0 | Self::merge_arrays(sa.to_array(), sb.to_array(), root_is_wildcard, merge_cache) |
332 | 0 | .alloc(); |
333 | | |
334 | | // println!("array result = {}",result); |
335 | | |
336 | 0 | if &*result == sa { |
337 | 0 | a.clone() |
338 | 0 | } else if &*result == sb { |
339 | 0 | b.clone() |
340 | | } else { |
341 | 0 | result //.alloc() |
342 | | } |
343 | | } |
344 | | }; |
345 | 0 | assert_ne!(r.hash_code(), 0); |
346 | 0 | if let Some(cache) = merge_cache { |
347 | 0 | // cache.entry(a.clone()).or_insert_with(||HashMap::new()) |
348 | 0 | // .insert(b.clone(),r.clone()); |
349 | 0 | cache.insert((a.clone(), b.clone()), r.clone()); |
350 | 0 | } |
351 | 0 | r |
352 | 317 | } |
353 | | |
354 | 0 | fn merge_singletons( |
355 | 0 | a: &SingletonPredictionContext, |
356 | 0 | b: &SingletonPredictionContext, |
357 | 0 | root_is_wildcard: bool, |
358 | 0 | merge_cache: &mut Option<&mut MergeCache>, |
359 | 0 | ) -> Arc<PredictionContext> { |
360 | 0 | Self::merge_root(a, b, root_is_wildcard).unwrap_or_else(|| { |
361 | 0 | if a.return_state == b.return_state { |
362 | 0 | let parent = Self::merge( |
363 | 0 | a.parent_ctx.as_ref().unwrap(), |
364 | 0 | b.parent_ctx.as_ref().unwrap(), |
365 | 0 | root_is_wildcard, |
366 | 0 | merge_cache, |
367 | | ); |
368 | 0 | if Arc::ptr_eq(&parent, a.parent_ctx.as_ref().unwrap()) { |
369 | 0 | Singleton(a.clone()) |
370 | 0 | } else if Arc::ptr_eq(&parent, b.parent_ctx.as_ref().unwrap()) { |
371 | 0 | Singleton(b.clone()) |
372 | | } else { |
373 | 0 | Self::new_singleton(Some(parent), a.return_state) |
374 | | } |
375 | | } else { |
376 | 0 | let parents = if a.parent_ctx == b.parent_ctx { |
377 | 0 | vec![a.parent_ctx.clone(), a.parent_ctx.clone()] |
378 | | } else { |
379 | 0 | vec![a.parent_ctx.clone(), b.parent_ctx.clone()] |
380 | | }; |
381 | 0 | let mut result = ArrayPredictionContext { |
382 | 0 | cached_hash: -1, |
383 | 0 | parents, |
384 | 0 | return_states: vec![a.return_state, b.return_state], |
385 | 0 | }; |
386 | | // if !result.return_states.is_sorted() |
387 | 0 | if !result.return_states.windows(2).all(|x| x[0] <= x[1]) { |
388 | 0 | result.parents.swap(0, 1); |
389 | 0 | result.return_states.swap(0, 1); |
390 | 0 | } |
391 | 0 | Array(result) |
392 | | } |
393 | 0 | .alloc() |
394 | 0 | }) |
395 | 0 | } |
396 | | |
397 | 0 | fn merge_root( |
398 | 0 | a: &SingletonPredictionContext, |
399 | 0 | b: &SingletonPredictionContext, |
400 | 0 | root_is_wildcard: bool, |
401 | 0 | ) -> Option<Arc<PredictionContext>> { |
402 | 0 | if root_is_wildcard { |
403 | 0 | if a.is_empty() || b.is_empty() { |
404 | 0 | return Some(EMPTY_PREDICTION_CONTEXT.clone()); |
405 | 0 | } |
406 | | } else { |
407 | 0 | if a.is_empty() && b.is_empty() { |
408 | 0 | return Some(EMPTY_PREDICTION_CONTEXT.clone()); |
409 | 0 | } |
410 | 0 | if a.is_empty() { |
411 | 0 | return Some( |
412 | 0 | Self::new_array( |
413 | 0 | vec![b.parent_ctx.clone(), None], |
414 | 0 | vec![b.return_state, PREDICTION_CONTEXT_EMPTY_RETURN_STATE], |
415 | 0 | ) |
416 | 0 | .alloc(), |
417 | 0 | ); |
418 | 0 | } |
419 | 0 | if b.is_empty() { |
420 | 0 | return Some( |
421 | 0 | Self::new_array( |
422 | 0 | vec![a.parent_ctx.clone(), None], |
423 | 0 | vec![a.return_state, PREDICTION_CONTEXT_EMPTY_RETURN_STATE], |
424 | 0 | ) |
425 | 0 | .alloc(), |
426 | 0 | ); |
427 | 0 | } |
428 | | } |
429 | | |
430 | 0 | None |
431 | 0 | } |
432 | | |
433 | 0 | fn merge_arrays( |
434 | 0 | a: Cow<'_, ArrayPredictionContext>, |
435 | 0 | b: Cow<'_, ArrayPredictionContext>, |
436 | 0 | root_is_wildcard: bool, |
437 | 0 | merge_cache: &mut Option<&mut MergeCache>, |
438 | 0 | ) -> PredictionContext { |
439 | | // let a = a.deref(); |
440 | | // let b = b.deref(); |
441 | 0 | let mut merged = ArrayPredictionContext { |
442 | 0 | cached_hash: -1, |
443 | 0 | parents: Vec::with_capacity(a.return_states.len() + b.return_states.len()), |
444 | 0 | return_states: Vec::with_capacity(a.return_states.len() + b.return_states.len()), |
445 | 0 | }; |
446 | 0 | let mut i = 0; |
447 | 0 | let mut j = 0; |
448 | | |
449 | 0 | while i < a.parents.len() && j < b.parents.len() { |
450 | 0 | let a_parent = a.parents[i].as_ref(); |
451 | 0 | let b_parent = b.parents[j].as_ref(); |
452 | 0 | if a.return_states[i] == b.return_states[j] { |
453 | 0 | let payload = a.return_states[i]; |
454 | 0 | let both = payload == PREDICTION_CONTEXT_EMPTY_RETURN_STATE |
455 | 0 | && a_parent.is_none() |
456 | 0 | && b_parent.is_none(); |
457 | 0 | let ax_ax = a_parent.is_some() && b_parent.is_some() && a_parent == b_parent; |
458 | | |
459 | 0 | if both || ax_ax { |
460 | 0 | merged.return_states.push(payload); |
461 | 0 | merged.parents.push(a_parent.cloned()); |
462 | 0 | } else { |
463 | 0 | let merged_parent = Self::merge( |
464 | 0 | a_parent.unwrap(), |
465 | 0 | b_parent.unwrap(), |
466 | 0 | root_is_wildcard, |
467 | 0 | merge_cache, |
468 | 0 | ); |
469 | 0 | merged.return_states.push(payload); |
470 | 0 | merged.parents.push(Some(merged_parent)); |
471 | 0 | } |
472 | 0 | i += 1; |
473 | 0 | j += 1; |
474 | 0 | } else if a.return_states[i] < b.return_states[j] { |
475 | 0 | merged.return_states.push(a.return_states[i]); |
476 | 0 | merged.parents.push(a_parent.cloned()); |
477 | 0 | i += 1; |
478 | 0 | } else { |
479 | 0 | merged.return_states.push(b.return_states[j]); |
480 | 0 | merged.parents.push(b_parent.cloned()); |
481 | 0 | j += 1; |
482 | 0 | } |
483 | | } |
484 | | |
485 | 0 | if i < a.return_states.len() { |
486 | 0 | for p in i..a.return_states.len() { |
487 | 0 | merged.parents.push(a.parents[p].clone()); |
488 | 0 | merged.return_states.push(a.return_states[p]); |
489 | 0 | } |
490 | 0 | } |
491 | 0 | if j < b.return_states.len() { |
492 | 0 | for p in j..b.return_states.len() { |
493 | 0 | merged.parents.push(b.parents[p].clone()); |
494 | 0 | merged.return_states.push(b.return_states[p]); |
495 | 0 | } |
496 | 0 | } |
497 | | |
498 | 0 | if merged.parents.len() < a.return_states.len() + b.return_states.len() { |
499 | 0 | if merged.parents.len() == 1 { |
500 | 0 | Self::new_singleton(merged.parents[0].clone(), merged.return_states[0]); |
501 | 0 | } |
502 | 0 | merged.return_states.shrink_to_fit(); |
503 | 0 | merged.parents.shrink_to_fit(); |
504 | 0 | } |
505 | | |
506 | 0 | PredictionContext::combine_common_parents(&mut merged); |
507 | | |
508 | | // if &m == a.deref(){ return ; } |
509 | | // if &m == b.deref(){ return ; } |
510 | | |
511 | 0 | Array(merged) |
512 | 0 | } |
513 | | |
514 | 22.5M | pub fn from_rule_context<'input, Ctx: ParserNodeType<'input>>( |
515 | 22.5M | atn: &ATN, |
516 | 22.5M | outer_context: &Ctx::Type, |
517 | 22.5M | ) -> Arc<PredictionContext> { |
518 | 22.5M | if outer_context.get_parent_ctx().is_none() || outer_context.is_empty() |
519 | | /*ptr::eq(outer_context, empty_ctx().as_ref())*/ |
520 | | { |
521 | 223k | return EMPTY_PREDICTION_CONTEXT.clone(); |
522 | 22.2M | } |
523 | | |
524 | 22.2M | let parent = PredictionContext::from_rule_context::<Ctx>( |
525 | 22.2M | atn, |
526 | 22.2M | outer_context.get_parent_ctx().unwrap().deref(), |
527 | | ); |
528 | | |
529 | 22.2M | let transition = atn.states[outer_context.get_invoking_state() as usize] |
530 | 22.2M | .get_transitions() |
531 | 22.2M | .first() |
532 | 22.2M | .unwrap() |
533 | 22.2M | .deref() |
534 | 22.2M | .cast::<RuleTransition>(); |
535 | | |
536 | 22.2M | PredictionContext::new_singleton(Some(parent), transition.follow_state as i32).alloc() |
537 | 22.5M | } <antlr4rust::prediction_context::PredictionContext>::from_rule_context::<cel::parser::gen::celparser::CELParserContextType> Line | Count | Source | 514 | 22.5M | pub fn from_rule_context<'input, Ctx: ParserNodeType<'input>>( | 515 | 22.5M | atn: &ATN, | 516 | 22.5M | outer_context: &Ctx::Type, | 517 | 22.5M | ) -> Arc<PredictionContext> { | 518 | 22.5M | if outer_context.get_parent_ctx().is_none() || outer_context.is_empty() | 519 | | /*ptr::eq(outer_context, empty_ctx().as_ref())*/ | 520 | | { | 521 | 223k | return EMPTY_PREDICTION_CONTEXT.clone(); | 522 | 22.2M | } | 523 | | | 524 | 22.2M | let parent = PredictionContext::from_rule_context::<Ctx>( | 525 | 22.2M | atn, | 526 | 22.2M | outer_context.get_parent_ctx().unwrap().deref(), | 527 | | ); | 528 | | | 529 | 22.2M | let transition = atn.states[outer_context.get_invoking_state() as usize] | 530 | 22.2M | .get_transitions() | 531 | 22.2M | .first() | 532 | 22.2M | .unwrap() | 533 | 22.2M | .deref() | 534 | 22.2M | .cast::<RuleTransition>(); | 535 | | | 536 | 22.2M | PredictionContext::new_singleton(Some(parent), transition.follow_state as i32).alloc() | 537 | 22.5M | } |
Unexecuted instantiation: <antlr4rust::prediction_context::PredictionContext>::from_rule_context::<antlr4rust::rule_context::EmptyContextType<antlr4rust::token_factory::CommonTokenFactory>> |
538 | | |
539 | 0 | fn combine_common_parents(array: &mut ArrayPredictionContext) { |
540 | 0 | let mut uniq_parents = |
541 | 0 | HashMap::<Option<Arc<PredictionContext>>, Option<Arc<PredictionContext>>>::new(); |
542 | 0 | for p in 0..array.parents.len() { |
543 | 0 | let parent = array.parents[p].as_ref().cloned(); |
544 | 0 | if !uniq_parents.contains_key(&parent) { |
545 | 0 | uniq_parents.insert(parent.clone(), parent.clone()); |
546 | 0 | } |
547 | | } |
548 | | |
549 | 0 | array.parents.iter_mut().for_each(|parent| { |
550 | 0 | *parent = (*uniq_parents.get(parent).unwrap()).clone(); |
551 | 0 | }); |
552 | 0 | } |
553 | | } |
554 | | |
555 | | // |
556 | | // fn get_cached_base_prediction_context(context PredictionContext, contextCache: * PredictionContextCache, visited: map[PredictionContext]PredictionContext) -> PredictionContext { unimplemented!() } |
557 | | |
558 | | ///Public for implementation reasons |
559 | | #[derive(Debug)] |
560 | | pub struct PredictionContextCache { |
561 | | //todo test dashmap |
562 | | cache: RwLock<HashMap<Arc<PredictionContext>, Arc<PredictionContext>, MurmurHasherBuilder>>, |
563 | | } |
564 | | |
565 | | #[doc(hidden)] |
566 | | #[derive(Debug)] |
567 | | pub struct MurmurHasherBuilder {} |
568 | | |
569 | | impl BuildHasher for MurmurHasherBuilder { |
570 | | type Hasher = MurmurHasher; |
571 | | |
572 | 42.8M | fn build_hasher(&self) -> Self::Hasher { |
573 | 42.8M | MurmurHasher::default() |
574 | 42.8M | } |
575 | | } |
576 | | |
577 | | impl PredictionContextCache { |
578 | | #[doc(hidden)] |
579 | 20.0k | pub fn new() -> PredictionContextCache { |
580 | 20.0k | PredictionContextCache { |
581 | 20.0k | cache: RwLock::new(HashMap::with_hasher(MurmurHasherBuilder {})), |
582 | 20.0k | } |
583 | 20.0k | } |
584 | | |
585 | | #[doc(hidden)] |
586 | 1.52k | pub fn get_shared_context( |
587 | 1.52k | &self, |
588 | 1.52k | context: &Arc<PredictionContext>, |
589 | 1.52k | visited: &mut HashMap<*const PredictionContext, Arc<PredictionContext>>, |
590 | 1.52k | ) -> Arc<PredictionContext> { |
591 | 1.52k | if context.is_empty() { |
592 | 1.05k | return context.clone(); |
593 | 467 | } |
594 | | |
595 | 467 | if let Some(old) = visited.get(&(context.deref() as *const PredictionContext)) { |
596 | 0 | return old.clone(); |
597 | 467 | } |
598 | | |
599 | 467 | if let Some(old) = self.cache.read().unwrap().get(context) { |
600 | 437 | return old.clone(); |
601 | 30 | } |
602 | 30 | let mut parents = Vec::with_capacity(context.length()); |
603 | 30 | let mut changed = false; |
604 | 30 | for i in 0..parents.len() { |
605 | 0 | let parent = self.get_shared_context(context.get_parent(i).unwrap(), visited); |
606 | 0 | if changed || &parent != context.get_parent(i).unwrap() { |
607 | 0 | if !changed { |
608 | 0 | for j in 0..i { |
609 | 0 | parents.push(context.get_parent(j).cloned()) |
610 | | } |
611 | 0 | changed = true; |
612 | 0 | } |
613 | 0 | parents.push(Some(parent.clone())) |
614 | 0 | } |
615 | | } |
616 | 30 | if !changed { |
617 | 30 | self.cache |
618 | 30 | .write() |
619 | 30 | .unwrap() |
620 | 30 | .insert(context.clone(), context.clone()); |
621 | 30 | visited.insert(context.deref(), context.clone()); |
622 | 30 | return context.clone(); |
623 | 0 | } |
624 | | |
625 | 0 | let updated = if parents.is_empty() { |
626 | 0 | return EMPTY_PREDICTION_CONTEXT.clone(); |
627 | 0 | } else if parents.len() == 1 { |
628 | 0 | PredictionContext::new_singleton(parents[0].clone(), context.get_return_state(0)) |
629 | 0 | } else if let Array(array) = context.deref() { |
630 | 0 | PredictionContext::new_array(parents, array.return_states.clone()) |
631 | | } else { |
632 | 0 | unreachable!() |
633 | | }; |
634 | | |
635 | 0 | let updated = Arc::new(updated); |
636 | 0 | self.cache |
637 | 0 | .write() |
638 | 0 | .unwrap() |
639 | 0 | .insert(updated.clone(), updated.clone()); |
640 | 0 | visited.insert(context.deref(), updated.clone()); |
641 | 0 | visited.insert(updated.deref(), updated.clone()); |
642 | | |
643 | 0 | updated |
644 | 1.52k | } |
645 | | |
646 | | #[doc(hidden)] |
647 | 0 | pub fn length(&self) -> usize { |
648 | 0 | self.cache.read().unwrap().len() |
649 | 0 | } |
650 | | } |