The main backtracking loop starting at the given input position.
(&mut self, start: InputAt)
| 181 | |
| 182 | /// The main backtracking loop starting at the given input position. |
| 183 | fn backtrack(&mut self, start: InputAt) -> bool { |
| 184 | // N.B. We use an explicit stack to avoid recursion. |
| 185 | // To avoid excessive pushing and popping, most transitions are handled |
| 186 | // in the `step` helper function, which only pushes to the stack when |
| 187 | // there's a capture or a branch. |
| 188 | let mut matched = false; |
| 189 | self.m.jobs.push(Job::Inst { ip: 0, at: start }); |
| 190 | while let Some(job) = self.m.jobs.pop() { |
| 191 | match job { |
| 192 | Job::Inst { ip, at } => { |
| 193 | if self.step(ip, at) { |
| 194 | // Only quit if we're matching one regex. |
| 195 | // If we're matching a regex set, then mush on and |
| 196 | // try to find other matches (if we want them). |
| 197 | if self.prog.matches.len() == 1 { |
| 198 | return true; |
| 199 | } |
| 200 | matched = true; |
| 201 | } |
| 202 | } |
| 203 | Job::SaveRestore { slot, old_pos } => { |
| 204 | if slot < self.slots.len() { |
| 205 | self.slots[slot] = old_pos; |
| 206 | } |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | matched |
| 211 | } |
| 212 | |
| 213 | fn step(&mut self, mut ip: InstPtr, mut at: InputAt) -> bool { |
| 214 | use prog::Inst::*; |