1use std::cmp::Ordering;
2use std::ops::Range;
3
4use bit_matrix::BitMatrix;
5use bit_matrix::row::BitVecSlice;
6use cfg::*;
7
8use events::{MedialItems, PredictedSymbols};
9use forest::{Forest, NullForest};
10use grammar::InternalGrammar;
11use item::{CompletedItem, CompletedItemLinked, Item, Origin};
12pub struct Recognizer<'g, F = NullForest>
20where
21 F: Forest,
22{
23 pub forest: F,
25 pub grammar: &'g InternalGrammar,
27 pub(super) predicted: BitMatrix,
36
37 pub(super) medial: Vec<Item<F::NodeRef>>,
41 pub(super) complete: Vec<CompletedItemLinked<F::NodeRef>>,
49
50 pub(super) indices: Vec<usize>,
55 pub(super) current_medial_start: usize,
58
59 pub(super) earleme: usize,
61
62 pub(super) lookahead_hint: Option<Option<Symbol>>,
63}
64
65impl<'g, F> Recognizer<'g, F>
66where
67 F: Forest,
68{
69 pub fn new(grammar: &'g InternalGrammar, forest: F) -> Recognizer<'g, F> {
72 let mut recognizer = Recognizer {
73 forest,
74 grammar,
75 earleme: 0,
77 indices: vec![0, 0],
79 current_medial_start: 0,
80 predicted: BitMatrix::new(8, grammar.num_syms()),
82 medial: Vec::with_capacity(256),
83 complete: Vec::with_capacity(32),
84 lookahead_hint: None,
85 };
86 recognizer.predict(grammar.start_sym());
87 recognizer
88 }
89
90 pub fn predict(&mut self, symbol: Symbol) {
92 self.predicted[self.earleme].predict(symbol, self.grammar.predict(symbol));
93 }
94
95 pub fn begin_earleme(&mut self) {
96 }
98
99 pub fn scan(&mut self, symbol: Symbol, value: F::LeafValue) {
102 if let Some(internal) = self.grammar.to_internal(symbol) {
104 let earleme = self.earleme as Origin;
105 let node = self.forest.leaf(symbol, earleme + 1, value);
107 self.complete(earleme, internal, node);
108 }
109 }
110
111 #[inline]
112 pub fn lookahead_hint(&mut self, lookahead: Option<Symbol>) {
113 let to_internal = |sym| self.grammar.to_internal(sym).unwrap();
114 self.lookahead_hint = Some(lookahead.map(to_internal));
115 }
116
117 pub fn end_earleme(&mut self) -> bool {
120 if self.is_exhausted() {
121 false
122 } else {
123 self.complete_all_sums_entirely();
125 self.advance_without_completion();
127 true
128 }
129 }
130
131 pub fn advance_without_completion(&mut self) {
135 self.sort_medial_items();
136 self.remove_unary_medial_items();
137 self.remove_unreachable_sets();
138 self.earleme += 1;
139 self.prediction_pass();
142 self.current_medial_start = self.medial.len();
144 self.indices.push(self.current_medial_start);
145 }
146
147 #[inline]
150 pub fn is_exhausted(&self) -> bool {
151 self.medial.len() == self.current_medial_start && self.complete.is_empty()
152 }
153
154 fn sort_medial_items(&mut self) {
156 let grammar = &self.grammar;
157 self.medial[self.current_medial_start..].sort_unstable_by(|a, b| {
160 (grammar.get_rhs1_cmp(a.dot), a.dot, a.origin).cmp(&(
161 grammar.get_rhs1_cmp(b.dot),
162 b.dot,
163 b.origin,
164 ))
165 });
166 }
167
168 fn remove_unary_medial_items(&mut self) {
169 while let Some(&item) = self.medial.last() {
170 if self.grammar.get_rhs1(item.dot).is_some() {
171 break;
172 }
173 self.medial.pop();
174 }
175 }
176
177 fn remove_unreachable_sets(&mut self) {
178 let origin = |item: &Item<F::NodeRef>| item.origin as usize;
179 let max_origin = self.medial[self.current_medial_start..]
180 .iter()
181 .map(origin)
182 .max()
183 .unwrap_or(self.earleme);
184 let diff = self.earleme - max_origin;
185 if diff <= 1 {
186 return;
187 }
188 let drop = diff - 1;
196 let new_medial_start = self.indices[self.indices.len() - 1 - drop];
197 self.indices.truncate(self.indices.len() - drop);
198 let current_medial_length = self.medial.len() - self.current_medial_start;
199 for i in 0..current_medial_length {
200 self.medial[new_medial_start as usize + i] = self.medial[self.current_medial_start + i];
201 }
202 self.medial
203 .truncate(new_medial_start as usize + current_medial_length);
204 self.current_medial_start = new_medial_start as usize;
205 self.earleme -= drop;
206 self.predicted.truncate(self.earleme + 1);
207 for dst in self.predicted[self.earleme].iter_mut() {
208 *dst = 0;
209 }
210 }
211
212 fn prediction_pass(&mut self) {
214 self.predicted.grow(1, false);
216 let iter = self.medial[self.current_medial_start..].iter();
218 let row = &mut self.predicted[self.earleme];
220 for ei in iter {
221 let postdot = self.grammar.get_rhs1(ei.dot).unwrap();
222 row.predict(postdot, self.grammar.predict(postdot));
223 }
224 }
225
226 pub fn complete(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) {
228 debug_assert!(sym != self.grammar.eof());
229 if self.predicted[set_id as usize].get(sym.usize()) {
230 self.complete_medial_items(set_id, sym, rhs_link);
231 self.complete_predictions(set_id, sym, rhs_link);
232 }
233 }
234
235 fn complete_medial_items(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) {
237 let set_range = self.medial_item_set_range(set_id, sym);
239 if let Some(hint) = self.lookahead_hint {
240 for idx in set_range {
241 let dot = self.medial[idx].dot;
247 if !self.grammar.can_follow(self.grammar.get_lhs(dot), hint) {
248 continue;
249 }
250 self.heap_push_linked(CompletedItemLinked {
251 idx: idx as u32,
252 node: Some(rhs_link),
253 });
254 }
255 } else {
256 for idx in set_range {
257 self.heap_push_linked(CompletedItemLinked {
263 idx: idx as u32,
264 node: Some(rhs_link),
265 });
266 }
267 }
268 }
269
270 fn medial_item_set_range(&mut self, set_id: Origin, sym: Symbol) -> Range<usize> {
271 let outer_start = self.indices[set_id as usize];
273 let outer_end = self.indices[set_id as usize + 1];
274 let specific_set = &self.medial[outer_start..outer_end];
275
276 let inner_start = if specific_set.len() >= 16 {
277 let set_idx = specific_set.binary_search_by(|ei| {
280 (self.grammar.get_rhs1(ei.dot), Ordering::Greater).cmp(&(Some(sym), Ordering::Less))
281 });
282 match set_idx {
283 Ok(idx) | Err(idx) => idx,
284 }
285 } else {
286 specific_set
287 .iter()
288 .take_while(|ei| self.grammar.get_rhs1(ei.dot).unwrap() < sym)
289 .count()
290 };
291
292 let inner_end = specific_set[inner_start..]
294 .iter()
295 .take_while(|ei| self.grammar.get_rhs1(ei.dot) == Some(sym))
296 .count();
297 outer_start + inner_start..outer_start + inner_start + inner_end
298 }
299
300 fn complete_predictions(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) {
302 self.complete_unary_predictions(set_id, sym, rhs_link);
306 self.complete_binary_predictions(set_id, sym, rhs_link);
307 }
308
309 fn complete_unary_predictions(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) {
311 for trans in self.grammar.unary_completions(sym) {
312 if self.predicted[set_id as usize].get(trans.symbol.usize()) {
313 if let Some(hint) = self.lookahead_hint {
320 if !self
321 .grammar
322 .can_follow(self.grammar.get_lhs(trans.dot), hint)
323 {
324 continue;
325 }
326 }
327 self.heap_push(CompletedItem {
328 origin: set_id,
329 dot: trans.dot,
330 left_node: rhs_link,
331 right_node: None,
332 });
333 }
334 }
335 }
336
337 fn complete_binary_predictions(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) {
339 for trans in self.grammar.binary_completions(sym) {
340 if self.predicted[set_id as usize].get(trans.symbol.usize()) {
341 if let Some(hint) = self.lookahead_hint {
342 if !self
343 .grammar
344 .first(self.grammar.get_rhs1(trans.dot).unwrap(), hint)
345 {
346 continue;
347 }
348 }
349 self.medial.push(Item {
355 origin: set_id,
356 dot: trans.dot,
357 node: rhs_link,
358 });
359 }
360 }
361 }
362
363 pub fn reset(&mut self) {
365 self.earleme = 0;
366 self.predict(self.grammar.start_sym());
367 self.indices.clear();
369 self.indices.push(0);
370 self.indices.push(0);
371 self.current_medial_start = 0;
373 self.medial.clear();
375 self.complete.clear();
376 }
377
378 pub fn is_finished(&self) -> bool {
383 self.finished_node().is_some()
384 }
385
386 pub fn finished_node(&self) -> Option<F::NodeRef> {
393 if self.grammar.has_trivial_derivation() && self.earleme == 0 {
394 Some(self.forest.nulling(self.grammar.externalized_start_sym()))
395 } else {
396 let has_dot_before_eof = |item: &&Item<_>| item.dot == self.grammar.dot_before_eof();
397 let item_node = |item: &Item<_>| item.node;
398 self.medial.last().filter(has_dot_before_eof).map(item_node)
399 }
400 }
401
402 pub fn predicted_symbols(&self) -> PredictedSymbols {
406 let earleme = self.earleme();
407 PredictedSymbols {
408 iter: self.predicted.iter_row(earleme),
409 idx: 0,
410 }
411 }
412
413 pub fn medial_items(&self) -> MedialItems<F::NodeRef> {
415 let indices_len = self.indices.len();
416 let items_start = self.indices[indices_len - 2];
419 MedialItems {
420 iter: self.medial[items_start..].iter(),
421 }
422 }
423
424 pub fn earleme(&self) -> usize {
428 self.earleme
429 }
430
431 pub fn complete_all_sums_entirely(&mut self) {
435 while let Some(mut completion) = self.next_sum() {
436 completion.complete_entire_sum();
438 }
439 self.lookahead_hint = None;
440 }
441
442 pub fn next_sum<'r>(&'r mut self) -> Option<CompleteSum<'g, 'r, F>> {
444 if let Some(ei) = self.heap_peek() {
445 let lhs_sym = self.grammar.get_lhs(ei.dot);
446 Some(CompleteSum {
447 origin: ei.origin,
448 lhs_sym,
449 recognizer: self,
450 })
451 } else {
452 None
453 }
454 }
455}
456
457pub struct CompleteSum<'g, 'r, F>
459where
460 F: Forest,
461{
462 origin: Origin,
464 lhs_sym: Symbol,
466 recognizer: &'r mut Recognizer<'g, F>,
468}
469
470impl<'g, 'r, F> CompleteSum<'g, 'r, F>
471where
472 F: Forest,
473 'g: 'r,
474{
475 pub fn complete_entire_sum(&mut self) {
477 self.recognizer.forest.begin_sum();
478 while let Some(item) = self.next_summand() {
480 self.push_summand(item);
481 }
482 self.complete_sum();
484 }
485
486 pub fn skip_entire_sum(&mut self) {
488 while let Some(_) = self.next_summand() {}
490 }
491
492 #[inline]
494 pub fn next_summand(&mut self) -> Option<CompletedItem<F::NodeRef>> {
495 if let Some(completion) = self.recognizer.heap_peek() {
496 let completion_lhs_sym = self.recognizer.grammar.get_lhs(completion.dot);
497 if self.origin == completion.origin && self.lhs_sym == completion_lhs_sym {
498 self.recognizer.heap_pop();
499 Some(completion)
500 } else {
501 None
502 }
503 } else {
504 None
505 }
506 }
507
508 #[inline]
510 pub fn push_summand(&mut self, completed_item: CompletedItem<F::NodeRef>) {
511 self.recognizer.forest.push_summand(completed_item);
512 }
513
514 #[inline]
516 pub fn complete_sum(&mut self) -> F::NodeRef {
517 let node = self.recognizer.forest.sum(self.lhs_sym, self.origin);
518 self.recognizer.complete(self.origin, self.lhs_sym, node);
519 node
520 }
521
522 #[inline]
524 pub fn origin(&self) -> Origin {
525 self.origin
526 }
527
528 #[inline]
530 pub fn symbol(&self) -> Symbol {
531 self.lhs_sym
532 }
533}
534
535trait Predict {
536 fn predict(&mut self, sym: Symbol, source: &BitVecSlice);
537}
538
539impl Predict for BitVecSlice {
540 fn predict(&mut self, sym: Symbol, source: &BitVecSlice) {
541 if !self[sym.usize()] {
542 for (dst, &src) in self.iter_mut().zip(source.iter()) {
548 *dst |= src;
549 }
550 }
551 }
552}