A parsing engine
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add fixes for genericity

+92 -12
+13 -2
gearley-recognizer/src/perf_hint.rs
··· 12 12 13 13 pub trait PerfHint { 14 14 const LOOKAHEAD: bool; 15 + const LEO: bool; 15 16 type Symbol; 16 - fn completion_capacity(&self) -> usize; 17 - fn medial_capacity(&self) -> Vec2dCapacity; 17 + 18 + fn completion_capacity(&self) -> usize { 19 + 32 20 + } 21 + 22 + fn medial_capacity(&self) -> Vec2dCapacity { 23 + Vec2dCapacity { 24 + chart_capacity: 512, 25 + indices_capacity: 128, 26 + } 27 + } 18 28 } 19 29 20 30 pub struct DefaultPerfHint { ··· 82 92 83 93 impl PerfHint for DefaultPerfHint { 84 94 const LOOKAHEAD: bool = true; 95 + const LEO: bool = true; 85 96 type Symbol = Symbol; 86 97 87 98 fn completion_capacity(&self) -> usize {
+75 -7
gearley-recognizer/src/recognizer.rs
··· 117 117 118 118 pub fn begin_earleme(&mut self) { 119 119 self.medial.next_set(); 120 - self.leo.next_set(); 120 + if P::LEO { 121 + self.leo.next_set(); 122 + } 121 123 if cfg!(feature = "log") { 122 124 let earleme = self.earleme(); 123 125 let rows = format!("{:?}", self.predicted.sub_matrix(earleme..earleme + 1)); ··· 190 192 pub fn advance_after_completion(&mut self) { 191 193 self.sort_medial_items(); 192 194 self.remove_unreachable_sets(); 195 + if P::LEO { 196 + self.add_leo_items(); 197 + } 193 198 trace!("recognizer.medial: Vec {:?}", self.medial.last()); 194 199 // `earleme` is now at least 1. 195 200 // Prediction pass. ··· 218 223 }); 219 224 } 220 225 226 + fn add_leo_items(&mut self) { 227 + let medial = self.medial.last(); 228 + for idx in 0 .. medial.len() { 229 + let rhs1 = self.grammar.get_rhs1(medial[idx].dot).unwrap(); 230 + let last = self.grammar.get_rhs1(medial[idx.saturating_sub(1)].dot).unwrap(); 231 + let next = self.grammar.get_rhs1(medial[idx + (idx != medial.len() - 1) as usize].dot).unwrap(); 232 + if (rhs1 != last || idx == 0) && (rhs1 != next || idx == medial.len() - 1) { 233 + // this item is unique 234 + // this item has a node 235 + let item = medial[idx]; 236 + if self.grammar.is_right_recursive(rhs1) { 237 + let leo_set = &self.leo[item.origin as usize]; 238 + let leo_idx = leo_set.binary_search_by_key(&rhs1, |&leo_item| self.grammar.get_rhs1(leo_item.dot).unwrap()); 239 + match leo_idx { 240 + Err(_) => { 241 + self.leo.push_item(item); 242 + } 243 + Ok(idx) => { 244 + let mut new_leo_item = leo_set[idx]; 245 + new_leo_item.node = self.forest.leo_product(new_leo_item.node, item.node); 246 + self.leo.push_item(new_leo_item); 247 + } 248 + } 249 + } 250 + } 251 + } 252 + } 253 + 221 254 fn remove_unreachable_sets(&mut self) { 222 255 let origin = |item: &Item<F::NodeRef>| item.origin as usize; 223 256 let max_origin = self ··· 257 290 // ------------------------------ 258 291 self.predicted.truncate(new_earleme + 1); 259 292 self.medial.truncate(new_earleme + 1); 293 + self.leo.truncate(new_earleme + 1); 260 294 debug_assert_eq!(self.medial.len(), new_earleme + 2); 261 295 debug_assert_eq!(self.earleme(), new_earleme); 262 296 } ··· 395 429 // to A ::= g42 • c 396 430 self.complete_generated_binary_predictions(set_id, sym, rhs_link); 397 431 } else if self.predicted[set_id as usize].get(sym.usize()) { 398 - // New item, either completed or medial. 432 + // New item, completed. 399 433 // from A ::= B • C 400 434 // to A ::= B C • 401 - self.complete_medial_items(set_id, sym, rhs_link); 402 - // New item, either completed or medial. 403 - // from A ::= • B c 404 - // to A ::= B • c 405 - self.complete_predictions(set_id, sym, rhs_link); 435 + if !P::LEO || !self.complete_leo(set_id, sym, rhs_link) { 436 + // New item, completed. 437 + // from A ::= B • C 438 + // to A ::= B C • 439 + self.complete_medial_items(set_id, sym, rhs_link); 440 + // New item, either completed or medial. 441 + // from A ::= • B c 442 + // to A ::= B • c 443 + self.complete_predictions(set_id, sym, rhs_link); 444 + } 406 445 } 407 446 } 408 447 ··· 523 562 } 524 563 self.medial 525 564 .truncate_chart(self.medial.item_count() - (self.medial.last().len() - binary)); 565 + } 566 + 567 + fn complete_leo(&mut self, set_id: Origin, sym: Symbol, rhs_link: F::NodeRef) -> bool { 568 + if !self.grammar.is_right_recursive(sym) { 569 + return false; 570 + } 571 + let leo_set = &self.leo[set_id as usize]; 572 + let maybe_found = leo_set.binary_search_by_key(&Some(sym), |ei| { 573 + self.grammar.get_rhs1(ei.dot) 574 + }); 575 + if let Ok(idx) = maybe_found { 576 + // let medial_set = &self.medial[set_id as usize]; 577 + // let medial_idx = medial_set.binary_search_by_key(&sym, |ei| { 578 + // self.grammar.get_rhs1(ei.dot).unwrap() 579 + // }).unwrap(); 580 + // medial_set[medial_idx].node 581 + // LEO node 582 + // rep • ----rr-- 583 + // rep --rr-- 584 + // rep • rr 585 + // rep 586 + // 587 + let mut leo_item = leo_set[idx]; 588 + leo_item.node = self.forest.leo_product(leo_item.node, rhs_link); 589 + self.complete.heap_push(leo_item); 590 + true 591 + } else { 592 + false 593 + } 526 594 } 527 595 528 596 /// Attempt to complete a predicted item with a postdot gensym.
+3 -2
gearley-utils/src/parse.rs
··· 8 8 use gearley_forest::Forest; 9 9 use gearley_forest::NullForest; 10 10 use gearley_grammar::Grammar; 11 - use gearley_recognizer::{Recognizer, lookahead::Lookahead}; 11 + use gearley_recognizer::{lookahead::Lookahead, perf_hint::PerfHint, Recognizer}; 12 12 13 13 pub trait RecognizerParseExt { 14 14 fn parse(&mut self, tokens: &[Symbol]) -> Result<bool, ParseError>; ··· 57 57 } 58 58 } 59 59 60 - impl<G, F> RecognizerParseExt for Recognizer<G, F> 60 + impl<G, F, P> RecognizerParseExt for Recognizer<G, F, P> 61 61 where 62 62 Self: Debug, 63 63 G: Grammar, 64 64 F: Forest, 65 + P: PerfHint, 65 66 { 66 67 #[inline] 67 68 fn parse(&mut self, tokens: &[Symbol]) -> Result<bool, ParseError> {
+1 -1
gearley-wasm/src/lib.rs
··· 12 12 use cfg_grammar::SymbolBitSet; 13 13 use cfg_load::advanced::{AdvancedGrammar, LexerMap}; 14 14 15 - use std::cell::RefCell;wrapping_sub 15 + use std::cell::RefCell; 16 16 use std::sync::LazyLock; 17 17 use std::sync::mpsc; 18 18 use std::panic;