Computes the next state given the current state and the current input byte (which may be EOF). If STATE_DEAD is returned, then there is no valid state transition. This implies that no permutation of future input can lead to a match state. STATE_UNKNOWN can never be returned.
(
&mut self,
qcur: &mut SparseSet,
qnext: &mut SparseSet,
mut si: StatePtr,
b: Byte,
)
| 909 | /// |
| 910 | /// STATE_UNKNOWN can never be returned. |
| 911 | fn exec_byte( |
| 912 | &mut self, |
| 913 | qcur: &mut SparseSet, |
| 914 | qnext: &mut SparseSet, |
| 915 | mut si: StatePtr, |
| 916 | b: Byte, |
| 917 | ) -> Option<StatePtr> { |
| 918 | use prog::Inst::*; |
| 919 | |
| 920 | // Initialize a queue with the current DFA state's NFA states. |
| 921 | qcur.clear(); |
| 922 | for ip in self.state(si).inst_ptrs() { |
| 923 | qcur.insert(ip); |
| 924 | } |
| 925 | |
| 926 | // Before inspecting the current byte, we may need to also inspect |
| 927 | // whether the position immediately preceding the current byte |
| 928 | // satisfies the empty assertions found in the current state. |
| 929 | // |
| 930 | // We only need to do this step if there are any empty assertions in |
| 931 | // the current state. |
| 932 | let is_word_last = self.state(si).flags().is_word(); |
| 933 | let is_word = b.is_ascii_word(); |
| 934 | if self.state(si).flags().has_empty() { |
| 935 | // Compute the flags immediately preceding the current byte. |
| 936 | // This means we only care about the "end" or "end line" flags. |
| 937 | // (The "start" flags are computed immediately proceding the |
| 938 | // current byte and is handled below.) |
| 939 | let mut flags = EmptyFlags::default(); |
| 940 | if b.is_eof() { |
| 941 | flags.end = true; |
| 942 | flags.end_line = true; |
| 943 | } else if b.as_byte().map_or(false, |b| b == b'\n') { |
| 944 | flags.end_line = true; |
| 945 | } |
| 946 | if is_word_last == is_word { |
| 947 | flags.not_word_boundary = true; |
| 948 | } else { |
| 949 | flags.word_boundary = true; |
| 950 | } |
| 951 | // Now follow epsilon transitions from every NFA state, but make |
| 952 | // sure we only follow transitions that satisfy our flags. |
| 953 | qnext.clear(); |
| 954 | for &ip in &*qcur { |
| 955 | self.follow_epsilons(usize_to_u32(ip), qnext, flags); |
| 956 | } |
| 957 | mem::swap(qcur, qnext); |
| 958 | } |
| 959 | |
| 960 | // Now we set flags for immediately after the current byte. Since start |
| 961 | // states are processed separately, and are the only states that can |
| 962 | // have the StartText flag set, we therefore only need to worry about |
| 963 | // the StartLine flag here. |
| 964 | // |
| 965 | // We do also keep track of whether this DFA state contains a NFA state |
| 966 | // that is a matching state. This is precisely how we delay the DFA |
| 967 | // matching by one byte in order to process the special EOF sentinel |
| 968 | // byte. Namely, if this DFA state containing a matching NFA state, |
no test coverage detected