MCPcopy Create free account
hub / github.com/davidblewett/rure-python / c_repeat_range

Method c_repeat_range

regex/src/compile.rs:589–636  ·  view source on GitHub ↗
(
        &mut self,
        expr: &Hir,
        greedy: bool,
        min: u32,
        max: u32,
    )

Source from the content-addressed store, hash-verified

587 }
588
589 fn c_repeat_range(
590 &mut self,
591 expr: &Hir,
592 greedy: bool,
593 min: u32,
594 max: u32,
595 ) -> Result {
596 let (min, max) = (u32_to_usize(min), u32_to_usize(max));
597 let patch_concat = self.c_concat(iter::repeat(expr).take(min))?;
598 let initial_entry = patch_concat.entry;
599 if min == max {
600 return Ok(patch_concat);
601 }
602 // It is much simpler to compile, e.g., `a{2,5}` as:
603 //
604 // aaa?a?a?
605 //
606 // But you end up with a sequence of instructions like this:
607 //
608 // 0: 'a'
609 // 1: 'a',
610 // 2: split(3, 4)
611 // 3: 'a'
612 // 4: split(5, 6)
613 // 5: 'a'
614 // 6: split(7, 8)
615 // 7: 'a'
616 // 8: MATCH
617 //
618 // This is *incredibly* inefficient because the splits end
619 // up forming a chain, which has to be resolved everything a
620 // transition is followed.
621 let mut holes = vec![];
622 let mut prev_hole = patch_concat.hole;
623 for _ in min..max {
624 self.fill_to_next(prev_hole);
625 let split = self.push_split_hole();
626 let Patch { hole, entry } = self.c(expr)?;
627 prev_hole = hole;
628 if greedy {
629 holes.push(self.fill_split(split, Some(entry), None));
630 } else {
631 holes.push(self.fill_split(split, None, Some(entry)));
632 }
633 }
634 holes.push(prev_hole);
635 Ok(Patch { hole: Hole::Many(holes), entry: initial_entry })
636 }
637
638 fn fill(&mut self, hole: Hole, goto: InstPtr) {
639 match hole {

Callers 1

c_repeatMethod · 0.80

Calls 7

u32_to_usizeFunction · 0.85
c_concatMethod · 0.80
fill_to_nextMethod · 0.80
push_split_holeMethod · 0.80
cMethod · 0.80
fill_splitMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected