Executes the Pike VM defined by the program. The idea is to execute threads in parallel, at each step executing them from the highest priority thread to the lowest one. In contrast to most regular expression engines, the Thompson/Pike one gets away with linear complexity because the string is ma
(char[] characters, int start, int end,
boolean anchorStart, boolean anchorEnd, Result result)
| 288 | * @return whether a match was found |
| 289 | */ |
| 290 | public boolean matches(char[] characters, int start, int end, |
| 291 | boolean anchorStart, boolean anchorEnd, Result result) |
| 292 | { |
| 293 | ThreadQueue current = new ThreadQueue(); |
| 294 | ThreadQueue next = new ThreadQueue(); |
| 295 | |
| 296 | // initialize the first thread |
| 297 | int startPC = anchorStart ? findPrefixLength : 0; |
| 298 | ThreadQueue queued = new ThreadQueue(startPC); |
| 299 | |
| 300 | boolean foundMatch = false; |
| 301 | int step = end > start ? +1 : -1; |
| 302 | for (int i = start; i != end + step; i += step) { |
| 303 | if (queued.isEmpty()) { |
| 304 | // no threads left |
| 305 | return foundMatch; |
| 306 | } |
| 307 | |
| 308 | char c = i != end ? characters[i] : 0; |
| 309 | int pc = -1; |
| 310 | for (;;) { |
| 311 | pc = current.next(pc); |
| 312 | if (pc < 0) { |
| 313 | pc = queued.queueOneImmediately(current); |
| 314 | } |
| 315 | if (pc < 0) { |
| 316 | break; |
| 317 | } |
| 318 | |
| 319 | // pc == program.length is a match! |
| 320 | if (pc == program.length) { |
| 321 | if (anchorEnd && i != end) { |
| 322 | continue; |
| 323 | } |
| 324 | if (result == null) { |
| 325 | // only interested in a match, no need to go on |
| 326 | return true; |
| 327 | } |
| 328 | current.setResult(result); |
| 329 | |
| 330 | // now that we found a match, even higher-priority matches must match |
| 331 | // at the same start offset |
| 332 | if (!anchorStart) { |
| 333 | next.mustStartMatchAt(current.startOffset(pc)); |
| 334 | } |
| 335 | foundMatch = true; |
| 336 | break; |
| 337 | } |
| 338 | |
| 339 | int opcode = program[pc]; |
| 340 | switch (opcode) { |
| 341 | case DOT: |
| 342 | if (c != '\0' && c != '\r' && c != '\n') { |
| 343 | current.queueNext(pc, pc + 1, next); |
| 344 | } |
| 345 | break; |
| 346 | case DOTALL: |
| 347 | current.queueNext(pc, pc + 1, next); |
no test coverage detected