fn follow_epsilons(
        &mut self,
        ip: InstPtr,
        q: &mut SparseSet,
        flags: EmptyFlags,
    ) {
        use prog::Inst::*;
        use prog::EmptyLook::*;

        // We need to traverse the NFA to follow epsilon transitions, so avoid
        // recursion with an explicit stack.
        self.cache.stack.push(ip);
        while let Some(ip) = self.cache.stack.pop() {
            // Don't visit states we've already added.
            if q.contains_ip(ip as usize) {
                continue;
            }
            q.add(ip as usize);
            match self.prog[ip as usize] {
                Char(_) | Ranges(_) => unreachable!(),
                Match(_) | Bytes(_) => {}
                EmptyLook(ref inst) => {
                    // Only follow empty assertion states if our flags satisfy
                    // the assertion.
                    match inst.look {
                        StartLine if flags.start_line => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        EndLine if flags.end_line => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        StartText if flags.start => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        EndText if flags.end => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        WordBoundaryAscii if flags.word_boundary => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        NotWordBoundaryAscii if flags.not_word_boundary => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        StartLine | EndLine | StartText | EndText => {}
                        WordBoundaryAscii | NotWordBoundaryAscii => {}
                        // The DFA doesn't support Unicode word boundaries. :-(
                        WordBoundary | NotWordBoundary => unreachable!(),
                    }
                }
                Save(ref inst) => self.cache.stack.push(inst.goto as InstPtr),
                Split(ref inst) => {
                    self.cache.stack.push(inst.goto2 as InstPtr);
                    self.cache.stack.push(inst.goto1 as InstPtr);
                }
            }
        }
    }
/// Follows the epsilon transitions starting at (and including) `ip`. The
/// resulting states are inserted into the ordered set `q`.
///
/// Conditional epsilon transitions (i.e., empty width assertions) are only
/// followed if they are satisfied by the given flags, which should
/// represent the flags set at the current location in the input.
///
/// If the current location corresponds to the empty string, then only the
/// end line and/or end text flags may be set. If the current location
/// corresponds to a real byte in the input, then only the start line
/// and/or start text flags may be set.
///
/// As an exception to the above, when finding the initial state, any of
/// the above flags may be set:
///
/// If matching starts at the beginning of the input, then start text and
/// start line should be set. If the input is empty, then end text and end
/// line should also be set.
///
/// If matching starts after the beginning of the input, then only start
/// line should be set if the preceding byte is `\n`. End line should never
/// be set in this case. (Even if the proceding byte is a `\n`, it will
/// be handled in a subsequent DFA state.)
Follows the epsilon transitions starting at (and including) `ip`. The
resulting states are inserted into the ordered set `q`.

Conditional epsilon transitions  are only
followed if they are satisfied by the given flags, which should
represent the flags set at the current location in the input.

If the current location corresponds to the empty string, then only the
end line and/or end text flags may be set. If the current location
corresponds to a real byte in the input, then only the start line
and/or start text flags may be set.

As an exception to the above, when finding the initial state, any of
the above flags may be set.

If matching starts at the beginning of the input, then start text and
start line should be set. If the input is empty, then end text and end
line should also be set.

If matching starts after the beginning of the input, then only start
line should be set if the preceding byte is `\n`. End line should never
be set in this case. (Even if the proceding byte is a `\n`, it will
be handled in a subsequent DFA state.)
Follows the epsilon transitions starting at ( and including ) ` ip ` . The resulting states are inserted into the ordered set ` q ` . Conditional epsilon transitions are only followed if they are satisfied by the given flags which should represent the flags set at the current location in the input . If the current location corresponds to the empty string then only the end line and / or end text flags may be set . If the current location corresponds to a real byte in the input then only the start line and / or start text flags may be set . As an exception to the above when finding the initial state any of the above flags may be set . If matching starts at the beginning of the input then start text and start line should be set . If the input is empty then end text and end line should also be set . If matching starts after the beginning of the input then only start line should be set if the preceding byte is ` \ n ` . End line should never be set in this case . ( Even if the proceding byte is a ` \ n ` it will be handled in a subsequent DFA state . )
fn follow_epsilons(
        &mut self,
        ip: InstPtr,
        q: &mut SparseSet,
        flags: EmptyFlags,
    ) {
        use prog::Inst::*;
        use prog::EmptyLook::*;
        // We need to traverse the NFA to follow epsilon transitions, so avoid
        // recursion with an explicit stack.
        self.cache.stack.push(ip);
        while let Some(ip) = self.cache.stack.pop() {
            // Don't visit states we've already added.
            if q.contains_ip(ip as usize) {
                continue;
            }
            q.add(ip as usize);
            match self.prog[ip as usize] {
                Char(_) | Ranges(_) => unreachable!(),
                Match(_) | Bytes(_) => {}
                EmptyLook(ref inst) => {
                    // Only follow empty assertion states if our flags satisfy
                    // the assertion.
                    match inst.look {
                        StartLine if flags.start_line => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        EndLine if flags.end_line => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        StartText if flags.start => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        EndText if flags.end => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        WordBoundaryAscii if flags.word_boundary => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        NotWordBoundaryAscii if flags.not_word_boundary => {
                            self.cache.stack.push(inst.goto as InstPtr);
                        }
                        StartLine | EndLine | StartText | EndText => {}
                        WordBoundaryAscii | NotWordBoundaryAscii => {}
                        // The DFA doesn't support Unicode word boundaries. :-(
                        WordBoundary | NotWordBoundary => unreachable!(),
                    }
                }
                Save(ref inst) => self.cache.stack.push(inst.goto as InstPtr),
                Split(ref inst) => {
                    self.cache.stack.push(inst.goto2 as InstPtr);
                    self.cache.stack.push(inst.goto1 as InstPtr);
                }
            }
        }
    }
fn follow_epsilons ( & mut self , ip : InstPtr , q : & mut SparseSet , flags : EmptyFlags , ) { use prog :: Inst :: * ; use prog :: EmptyLook :: * ; // We need to traverse the NFA to follow epsilon transitions, so avoid // recursion with an explicit stack. self . cache . stack . push ( ip ) ; while let Some ( ip ) = self . cache . stack . pop ( ) { // Don't visit states we've already added. if q . contains_ip ( ip as usize ) { continue ; } q . add ( ip as usize ) ; match self . prog [ ip as usize ] { Char ( _ ) | Ranges ( _ ) => unreachable ! ( ) , Match ( _ ) | Bytes ( _ ) => { } EmptyLook ( ref inst ) => { // Only follow empty assertion states if our flags satisfy // the assertion. match inst . look { StartLine if flags . start_line => { self . cache . stack . push ( inst . goto as InstPtr ) ; } EndLine if flags . end_line => { self . cache . stack . push ( inst . goto as InstPtr ) ; } StartText if flags . start => { self . cache . stack . push ( inst . goto as InstPtr ) ; } EndText if flags . end => { self . cache . stack . push ( inst . goto as InstPtr ) ; } WordBoundaryAscii if flags . word_boundary => { self . cache . stack . push ( inst . goto as InstPtr ) ; } NotWordBoundaryAscii if flags . not_word_boundary => { self . cache . stack . push ( inst . goto as InstPtr ) ; } StartLine | EndLine | StartText | EndText => { } WordBoundaryAscii | NotWordBoundaryAscii => { } // The DFA doesn't support Unicode word boundaries. :-( WordBoundary | NotWordBoundary => unreachable ! ( ) , } } Save ( ref inst ) => self . cache . stack . push ( inst . goto as InstPtr ) , Split ( ref inst ) => { self . cache . stack . push ( inst . goto2 as InstPtr ) ; self . cache . stack . push ( inst . goto1 as InstPtr ) ; } } } }
Follows the epsilon transitions starting at (and including) `ip`.
Follows the epsilon transitions starting at ( and including ) ` ip ` .
&mut self
ip
InstPtr
q
&mut SparseSet
flags
EmptyFlags
&mut self
ip
InstPtr
q
&mut SparseSet
flags
EmptyFlags