Try a search from instruction id0 in state p0. Return whether it succeeded.
| 136 | // Try a search from instruction id0 in state p0. |
| 137 | // Return whether it succeeded. |
| 138 | bool BitState::TrySearch(int id0, const char* p0) { |
| 139 | bool matched = false; |
| 140 | const char* end = text_.data() + text_.size(); |
| 141 | njob_ = 0; |
| 142 | // Push() no longer checks ShouldVisit(), |
| 143 | // so we must perform the check ourselves. |
| 144 | if (ShouldVisit(id0, p0)) |
| 145 | Push(id0, p0); |
| 146 | while (njob_ > 0) { |
| 147 | // Pop job off stack. |
| 148 | --njob_; |
| 149 | int id = job_[njob_].id; |
| 150 | int& rle = job_[njob_].rle; |
| 151 | const char* p = job_[njob_].p; |
| 152 | |
| 153 | if (id < 0) { |
| 154 | // Undo the Capture. |
| 155 | cap_[prog_->inst(-id)->cap()] = p; |
| 156 | continue; |
| 157 | } |
| 158 | |
| 159 | if (rle > 0) { |
| 160 | p += rle; |
| 161 | // Revivify job on stack. |
| 162 | --rle; |
| 163 | ++njob_; |
| 164 | } |
| 165 | |
| 166 | Loop: |
| 167 | // Visit id, p. |
| 168 | Prog::Inst* ip = prog_->inst(id); |
| 169 | switch (ip->opcode()) { |
| 170 | default: |
| 171 | LOG(DFATAL) << "Unexpected opcode: " << ip->opcode(); |
| 172 | return false; |
| 173 | |
| 174 | case kInstFail: |
| 175 | break; |
| 176 | |
| 177 | case kInstAltMatch: |
| 178 | if (ip->greedy(prog_)) { |
| 179 | // out1 is the Match instruction. |
| 180 | id = ip->out1(); |
| 181 | p = end; |
| 182 | goto Loop; |
| 183 | } |
| 184 | if (longest_) { |
| 185 | // ip must be non-greedy... |
| 186 | // out is the Match instruction. |
| 187 | id = ip->out(); |
| 188 | p = end; |
| 189 | goto Loop; |
| 190 | } |
| 191 | goto Next; |
| 192 | |
| 193 | case kInstByteRange: { |
| 194 | int c = -1; |
| 195 | if (p < end) |