60 #include "util/util.h"
61 #include "util/logging.h"
62 #include "util/strutil.h"
67 #include "re2/stringpiece.h"
71 #pragma warning(disable: 4200)
186 "kEmptyShift disagrees with kEmptyAllFlags");
189 "kMaxCap disagrees with kMaxOnePassCapture");
202 const char** cap,
int ncap) {
203 for (
int i = 2;
i < ncap;
i++)
211 return reinterpret_cast<OneState*
>(nodes + statesize*nodeindex);
215 const StringPiece& const_context,
217 StringPiece*
match,
int nmatch) {
219 LOG(DFATAL) <<
"Cannot use SearchOnePass for unanchored matches.";
230 for (
int i = 0;
i < ncap;
i++)
234 for (
int i = 0;
i < ncap;
i++)
237 StringPiece
context = const_context;
252 const char* bp =
text.data();
253 const char* ep =
text.data() +
text.size();
255 bool matched =
false;
259 for (p = bp;
p < ep;
p++) {
269 nextmatchcond =
state->matchcond;
301 for (
int i = 2;
i < 2*nmatch;
i++)
302 matchcap[i] = cap[i];
303 if (nmatch > 1 && (matchcond &
kCapMask))
329 if (nmatch > 1 && (matchcond &
kCapMask))
331 for (
int i = 2;
i < ncap;
i++)
332 matchcap[i] = cap[i];
341 for (
int i = 0;
i < nmatch;
i++)
343 StringPiece(matchcap[2 * i],
344 static_cast<size_t>(matchcap[2 * i + 1] - matchcap[2 * i]));
398 if (maxnodes >= 65000 ||
dfa_mem_ / 4 / statesize < maxnodes)
410 PODArray<int> nodebyid(
size);
411 memset(nodebyid.data(), 0xFF,
size*
sizeof nodebyid[0]);
416 std::vector<uint8_t> nodes;
420 nodebyid[
start()] = 0;
422 nodes.insert(nodes.end(), statesize, 0);
425 int nodeindex = nodebyid[
id];
426 OneState* node =
IndexToNode(nodes.data(), statesize, nodeindex);
435 bool matched =
false;
444 Prog::Inst* ip =
inst(
id);
445 switch (ip->opcode()) {
447 LOG(DFATAL) <<
"unhandled opcode: " << ip->opcode();
455 if (!
AddQ(&workq,
id+1))
461 int nextindex = nodebyid[ip->out()];
462 if (nextindex == -1) {
463 if (nalloc >= maxnodes) {
466 "Not OnePass: hit node limit %d >= %d", nalloc, maxnodes);
470 AddQ(&tovisit, ip->out());
471 nodebyid[ip->out()] = nalloc;
473 nodes.insert(nodes.end(), statesize, 0);
475 node =
IndexToNode(nodes.data(), statesize, nodeindex);
477 for (
int c = ip->lo(); c <= ip->hi();
c++) {
487 node->action[
b] = newact;
488 }
else if (act != newact) {
491 "Not OnePass: conflict on byte %#x at state %d", c, *
it);
495 if (ip->foldcase()) {
496 Rune lo = std::max<Rune>(ip->lo(),
'a') +
'A' -
'a';
497 Rune hi = std::min<Rune>(ip->hi(),
'z') +
'A' -
'a';
498 for (
int c = lo;
c <= hi;
c++) {
508 node->action[
b] = newact;
509 }
else if (act != newact) {
512 "Not OnePass: conflict on byte %#x at state %d", c, *
it);
521 if (!
AddQ(&workq,
id+1))
532 if (!
AddQ(&workq,
id+1))
550 if (!
AddQ(&workq, ip->out())) {
553 "Not OnePass: multiple paths %d -> %d", *
it, ip->out());
564 "Not OnePass: multiple matches from %d", *
it);
568 node->matchcond =
cond;
573 if (!
AddQ(&workq,
id+1))
588 std::map<int, int> idmap;
589 for (
int i = 0;
i <
size;
i++)
590 if (nodebyid[i] != -1)
591 idmap[nodebyid[
i]] =
i;
596 int nodeindex = nodebyid[
id];
599 OneState* node =
IndexToNode(nodes.data(), statesize, nodeindex);
601 nodeindex,
id, node->matchcond);
606 i, node->action[i] & 0xFFFF,