Tries instruction id at string position p. Returns true if a match is found.
| 180 | // Tries instruction id at string position p. |
| 181 | // Returns true if a match is found. |
| 182 | bool Backtracker::Try(int id, const char* p) { |
| 183 | // Pick out byte at current position. If at end of string, |
| 184 | // have to explore in hope of finishing a match. Use impossible byte -1. |
| 185 | int c = -1; |
| 186 | if (p < text_.data() + text_.size()) |
| 187 | c = *p & 0xFF; |
| 188 | |
| 189 | Prog::Inst* ip = prog_->inst(id); |
| 190 | switch (ip->opcode()) { |
| 191 | default: |
| 192 | LOG(FATAL) << "Unexpected opcode: " << (int)ip->opcode(); |
| 193 | return false; // not reached |
| 194 | |
| 195 | case kInstAltMatch: |
| 196 | // Ignored. |
| 197 | return false; |
| 198 | |
| 199 | case kInstByteRange: |
| 200 | if (ip->Matches(c)) |
| 201 | return Visit(ip->out(), p+1); |
| 202 | return false; |
| 203 | |
| 204 | case kInstCapture: |
| 205 | if (0 <= ip->cap() && |
| 206 | ip->cap() < static_cast<int>(arraysize(cap_))) { |
| 207 | // Capture p to register, but save old value. |
| 208 | const char* q = cap_[ip->cap()]; |
| 209 | cap_[ip->cap()] = p; |
| 210 | bool ret = Visit(ip->out(), p); |
| 211 | // Restore old value as we backtrack. |
| 212 | cap_[ip->cap()] = q; |
| 213 | return ret; |
| 214 | } |
| 215 | return Visit(ip->out(), p); |
| 216 | |
| 217 | case kInstEmptyWidth: |
| 218 | if (ip->empty() & ~Prog::EmptyFlags(context_, p)) |
| 219 | return false; |
| 220 | return Visit(ip->out(), p); |
| 221 | |
| 222 | case kInstNop: |
| 223 | return Visit(ip->out(), p); |
| 224 | |
| 225 | case kInstMatch: |
| 226 | // We found a match. If it's the best so far, record the |
| 227 | // parameters in the caller's submatch_ array. |
| 228 | if (endmatch_ && p != context_.data() + context_.size()) |
| 229 | return false; |
| 230 | cap_[1] = p; |
| 231 | if (submatch_[0].data() == NULL || |
| 232 | (longest_ && p > submatch_[0].data() + submatch_[0].size())) { |
| 233 | // First match so far - or better match. |
| 234 | for (int i = 0; i < nsubmatch_; i++) |
| 235 | submatch_[i] = StringPiece( |
| 236 | cap_[2 * i], static_cast<size_t>(cap_[2 * i + 1] - cap_[2 * i])); |
| 237 | } |
| 238 | return true; |
| 239 |