use std::{fmt::Debug, hash::Hash, time::Instant};
use lrtable::{Action, StIdx};
use num_traits::{AsPrimitive, PrimInt, Unsigned};
use parser::{AStackType, ParseRepair, Parser, Recoverer};
struct Panic;
pub(crate) fn recoverer<
'a,
StorageT: 'static + Debug + Hash + PrimInt + Unsigned,
ActionT: 'static
>(
_: &'a Parser<StorageT, ActionT>
) -> Box<Recoverer<StorageT, ActionT> + 'a>
where
usize: AsPrimitive<StorageT>,
u32: AsPrimitive<StorageT>
{
Box::new(Panic)
}
impl<StorageT: 'static + Debug + Hash + PrimInt + Unsigned, ActionT: 'static>
Recoverer<StorageT, ActionT> for Panic
where
usize: AsPrimitive<StorageT>,
u32: AsPrimitive<StorageT>
{
fn recover(
&self,
finish_by: Instant,
parser: &Parser<StorageT, ActionT>,
in_laidx: usize,
in_pstack: &mut Vec<StIdx>,
_: &mut Vec<AStackType<ActionT, StorageT>>
) -> (usize, Vec<Vec<ParseRepair<StorageT>>>) {
let iter_pstack = in_pstack.clone();
for laidx in in_laidx..parser.lexemes.len() + 1 {
if Instant::now() >= finish_by {
break;
}
for (st_i, st) in iter_pstack.iter().enumerate().rev() {
match parser.stable.action(*st, parser.next_tidx(laidx)) {
Action::Error => (),
_ => {
let mut rprs = Vec::with_capacity(laidx - in_laidx);
for j in in_laidx..laidx {
rprs.push(ParseRepair::Delete(parser.next_lexeme(j)));
}
in_pstack.drain(st_i + 1..);
return (laidx, vec![rprs]);
}
}
}
}
(in_laidx, vec![])
}
}