bloaty/third_party/re2/re2/onepass.cc
Go to the documentation of this file.
1 // Copyright 2008 The RE2 Authors. All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 // Tested by search_test.cc.
6 //
7 // Prog::SearchOnePass is an efficient implementation of
8 // regular expression search with submatch tracking for
9 // what I call "one-pass regular expressions". (An alternate
10 // name might be "backtracking-free regular expressions".)
11 //
12 // One-pass regular expressions have the property that
13 // at each input byte during an anchored match, there may be
14 // multiple alternatives but only one can proceed for any
15 // given input byte.
16 //
17 // For example, the regexp /x*yx*/ is one-pass: you read
18 // x's until a y, then you read the y, then you keep reading x's.
19 // At no point do you have to guess what to do or back up
20 // and try a different guess.
21 //
22 // On the other hand, /x*x/ is not one-pass: when you're
23 // looking at an input "x", it's not clear whether you should
24 // use it to extend the x* or as the final x.
25 //
26 // More examples: /([^ ]*) (.*)/ is one-pass; /(.*) (.*)/ is not.
27 // /(\d+)-(\d+)/ is one-pass; /(\d+).(\d+)/ is not.
28 //
29 // A simple intuition for identifying one-pass regular expressions
30 // is that it's always immediately obvious when a repetition ends.
31 // It must also be immediately obvious which branch of an | to take:
32 //
33 // /x(y|z)/ is one-pass, but /(xy|xz)/ is not.
34 //
35 // The NFA-based search in nfa.cc does some bookkeeping to
36 // avoid the need for backtracking and its associated exponential blowup.
37 // But if we have a one-pass regular expression, there is no
38 // possibility of backtracking, so there is no need for the
39 // extra bookkeeping. Hence, this code.
40 //
41 // On a one-pass regular expression, the NFA code in nfa.cc
42 // runs at about 1/20 of the backtracking-based PCRE speed.
43 // In contrast, the code in this file runs at about the same
44 // speed as PCRE.
45 //
46 // One-pass regular expressions get used a lot when RE is
47 // used for parsing simple strings, so it pays off to
48 // notice them and handle them efficiently.
49 //
50 // See also Anne Brüggemann-Klein and Derick Wood,
51 // "One-unambiguous regular languages", Information and Computation 142(2).
52 
53 #include <stdint.h>
54 #include <string.h>
55 #include <algorithm>
56 #include <map>
57 #include <string>
58 #include <vector>
59 
60 #include "util/util.h"
61 #include "util/logging.h"
62 #include "util/pod_array.h"
63 #include "util/sparse_set.h"
64 #include "util/strutil.h"
65 #include "util/utf.h"
66 #include "re2/prog.h"
67 #include "re2/stringpiece.h"
68 
69 // Silence "zero-sized array in struct/union" warning for OneState::action.
70 #ifdef _MSC_VER
71 #pragma warning(disable: 4200)
72 #endif
73 
74 namespace re2 {
75 
76 static const bool ExtraDebug = false;
77 
78 // The key insight behind this implementation is that the
79 // non-determinism in an NFA for a one-pass regular expression
80 // is contained. To explain what that means, first a
81 // refresher about what regular expression programs look like
82 // and how the usual NFA execution runs.
83 //
84 // In a regular expression program, only the kInstByteRange
85 // instruction processes an input byte c and moves on to the
86 // next byte in the string (it does so if c is in the given range).
87 // The kInstByteRange instructions correspond to literal characters
88 // and character classes in the regular expression.
89 //
90 // The kInstAlt instructions are used as wiring to connect the
91 // kInstByteRange instructions together in interesting ways when
92 // implementing | + and *.
93 // The kInstAlt instruction forks execution, like a goto that
94 // jumps to ip->out() and ip->out1() in parallel. Each of the
95 // resulting computation paths is called a thread.
96 //
97 // The other instructions -- kInstEmptyWidth, kInstMatch, kInstCapture --
98 // are interesting in their own right but like kInstAlt they don't
99 // advance the input pointer. Only kInstByteRange does.
100 //
101 // The automaton execution in nfa.cc runs all the possible
102 // threads of execution in lock-step over the input. To process
103 // a particular byte, each thread gets run until it either dies
104 // or finds a kInstByteRange instruction matching the byte.
105 // If the latter happens, the thread stops just past the
106 // kInstByteRange instruction (at ip->out()) and waits for
107 // the other threads to finish processing the input byte.
108 // Then, once all the threads have processed that input byte,
109 // the whole process repeats. The kInstAlt state instruction
110 // might create new threads during input processing, but no
111 // matter what, all the threads stop after a kInstByteRange
112 // and wait for the other threads to "catch up".
113 // Running in lock step like this ensures that the NFA reads
114 // the input string only once.
115 //
116 // Each thread maintains its own set of capture registers
117 // (the string positions at which it executed the kInstCapture
118 // instructions corresponding to capturing parentheses in the
119 // regular expression). Repeated copying of the capture registers
120 // is the main performance bottleneck in the NFA implementation.
121 //
122 // A regular expression program is "one-pass" if, no matter what
123 // the input string, there is only one thread that makes it
124 // past a kInstByteRange instruction at each input byte. This means
125 // that there is in some sense only one active thread throughout
126 // the execution. Other threads might be created during the
127 // processing of an input byte, but they are ephemeral: only one
128 // thread is left to start processing the next input byte.
129 // This is what I meant above when I said the non-determinism
130 // was "contained".
131 //
132 // To execute a one-pass regular expression program, we can build
133 // a DFA (no non-determinism) that has at most as many states as
134 // the NFA (compare this to the possibly exponential number of states
135 // in the general case). Each state records, for each possible
136 // input byte, the next state along with the conditions required
137 // before entering that state -- empty-width flags that must be true
138 // and capture operations that must be performed. It also records
139 // whether a set of conditions required to finish a match at that
140 // point in the input rather than process the next byte.
141 
142 // A state in the one-pass NFA - just an array of actions indexed
143 // by the bytemap_[] of the next input byte. (The bytemap
144 // maps next input bytes into equivalence classes, to reduce
145 // the memory footprint.)
146 struct OneState {
147  uint32_t matchcond; // conditions to match right now.
149 };
150 
151 // The uint32_t conditions in the action are a combination of
152 // condition and capture bits and the next state. The bottom 16 bits
153 // are the condition and capture bits, and the top 16 are the index of
154 // the next state.
155 //
156 // Bits 0-5 are the empty-width flags from prog.h.
157 // Bit 6 is kMatchWins, which means the match takes
158 // priority over moving to next in a first-match search.
159 // The remaining bits mark capture registers that should
160 // be set to the current input position. The capture bits
161 // start at index 2, since the search loop can take care of
162 // cap[0], cap[1] (the overall match position).
163 // That means we can handle up to 5 capturing parens: $1 through $4, plus $0.
164 // No input position can satisfy both kEmptyWordBoundary
165 // and kEmptyNonWordBoundary, so we can use that as a sentinel
166 // instead of needing an extra bit.
167 
168 static const int kIndexShift = 16; // number of bits below index
169 static const int kEmptyShift = 6; // number of empty flags in prog.h
170 static const int kRealCapShift = kEmptyShift + 1;
171 static const int kRealMaxCap = (kIndexShift - kRealCapShift) / 2 * 2;
172 
173 // Parameters used to skip over cap[0], cap[1].
174 static const int kCapShift = kRealCapShift - 2;
175 static const int kMaxCap = kRealMaxCap + 2;
176 
177 static const uint32_t kMatchWins = 1 << kEmptyShift;
178 static const uint32_t kCapMask = ((1 << kRealMaxCap) - 1) << kRealCapShift;
179 
181 
182 // Check, at compile time, that prog.h agrees with math above.
183 // This function is never called.
185  static_assert((1<<kEmptyShift)-1 == kEmptyAllFlags,
186  "kEmptyShift disagrees with kEmptyAllFlags");
187  // kMaxCap counts pointers, kMaxOnePassCapture counts pairs.
188  static_assert(kMaxCap == Prog::kMaxOnePassCapture*2,
189  "kMaxCap disagrees with kMaxOnePassCapture");
190 }
191 
192 static bool Satisfy(uint32_t cond, const StringPiece& context, const char* p) {
193  uint32_t satisfied = Prog::EmptyFlags(context, p);
194  if (cond & kEmptyAllFlags & ~satisfied)
195  return false;
196  return true;
197 }
198 
199 // Apply the capture bits in cond, saving p to the appropriate
200 // locations in cap[].
201 static void ApplyCaptures(uint32_t cond, const char* p,
202  const char** cap, int ncap) {
203  for (int i = 2; i < ncap; i++)
204  if (cond & (1 << kCapShift << i))
205  cap[i] = p;
206 }
207 
208 // Computes the OneState* for the given nodeindex.
209 static inline OneState* IndexToNode(uint8_t* nodes, int statesize,
210  int nodeindex) {
211  return reinterpret_cast<OneState*>(nodes + statesize*nodeindex);
212 }
213 
215  const StringPiece& const_context,
216  Anchor anchor, MatchKind kind,
217  StringPiece* match, int nmatch) {
218  if (anchor != kAnchored && kind != kFullMatch) {
219  LOG(DFATAL) << "Cannot use SearchOnePass for unanchored matches.";
220  return false;
221  }
222 
223  // Make sure we have at least cap[1],
224  // because we use it to tell if we matched.
225  int ncap = 2*nmatch;
226  if (ncap < 2)
227  ncap = 2;
228 
229  const char* cap[kMaxCap];
230  for (int i = 0; i < ncap; i++)
231  cap[i] = NULL;
232 
233  const char* matchcap[kMaxCap];
234  for (int i = 0; i < ncap; i++)
235  matchcap[i] = NULL;
236 
237  StringPiece context = const_context;
238  if (context.data() == NULL)
239  context = text;
240  if (anchor_start() && context.begin() != text.begin())
241  return false;
242  if (anchor_end() && context.end() != text.end())
243  return false;
244  if (anchor_end())
245  kind = kFullMatch;
246 
247  uint8_t* nodes = onepass_nodes_.data();
248  int statesize = sizeof(OneState) + bytemap_range()*sizeof(uint32_t);
249  // start() is always mapped to the zeroth OneState.
250  OneState* state = IndexToNode(nodes, statesize, 0);
252  const char* bp = text.data();
253  const char* ep = text.data() + text.size();
254  const char* p;
255  bool matched = false;
256  matchcap[0] = bp;
257  cap[0] = bp;
258  uint32_t nextmatchcond = state->matchcond;
259  for (p = bp; p < ep; p++) {
260  int c = bytemap[*p & 0xFF];
261  uint32_t matchcond = nextmatchcond;
262  uint32_t cond = state->action[c];
263 
264  // Determine whether we can reach act->next.
265  // If so, advance state and nextmatchcond.
266  if ((cond & kEmptyAllFlags) == 0 || Satisfy(cond, context, p)) {
267  uint32_t nextindex = cond >> kIndexShift;
268  state = IndexToNode(nodes, statesize, nextindex);
269  nextmatchcond = state->matchcond;
270  } else {
271  state = NULL;
272  nextmatchcond = kImpossible;
273  }
274 
275  // This code section is carefully tuned.
276  // The goto sequence is about 10% faster than the
277  // obvious rewrite as a large if statement in the
278  // ASCIIMatchRE2 and DotMatchRE2 benchmarks.
279 
280  // Saving the match capture registers is expensive.
281  // Is this intermediate match worth thinking about?
282 
283  // Not if we want a full match.
284  if (kind == kFullMatch)
285  goto skipmatch;
286 
287  // Not if it's impossible.
288  if (matchcond == kImpossible)
289  goto skipmatch;
290 
291  // Not if the possible match is beaten by the certain
292  // match at the next byte. When this test is useless
293  // (e.g., HTTPPartialMatchRE2) it slows the loop by
294  // about 10%, but when it avoids work (e.g., DotMatchRE2),
295  // it cuts the loop execution by about 45%.
296  if ((cond & kMatchWins) == 0 && (nextmatchcond & kEmptyAllFlags) == 0)
297  goto skipmatch;
298 
299  // Finally, the match conditions must be satisfied.
300  if ((matchcond & kEmptyAllFlags) == 0 || Satisfy(matchcond, context, p)) {
301  for (int i = 2; i < 2*nmatch; i++)
302  matchcap[i] = cap[i];
303  if (nmatch > 1 && (matchcond & kCapMask))
304  ApplyCaptures(matchcond, p, matchcap, ncap);
305  matchcap[1] = p;
306  matched = true;
307 
308  // If we're in longest match mode, we have to keep
309  // going and see if we find a longer match.
310  // In first match mode, we can stop if the match
311  // takes priority over the next state for this input byte.
312  // That bit is per-input byte and thus in cond, not matchcond.
313  if (kind == kFirstMatch && (cond & kMatchWins))
314  goto done;
315  }
316 
317  skipmatch:
318  if (state == NULL)
319  goto done;
320  if ((cond & kCapMask) && nmatch > 1)
321  ApplyCaptures(cond, p, cap, ncap);
322  }
323 
324  // Look for match at end of input.
325  {
326  uint32_t matchcond = state->matchcond;
327  if (matchcond != kImpossible &&
328  ((matchcond & kEmptyAllFlags) == 0 || Satisfy(matchcond, context, p))) {
329  if (nmatch > 1 && (matchcond & kCapMask))
330  ApplyCaptures(matchcond, p, cap, ncap);
331  for (int i = 2; i < ncap; i++)
332  matchcap[i] = cap[i];
333  matchcap[1] = p;
334  matched = true;
335  }
336  }
337 
338 done:
339  if (!matched)
340  return false;
341  for (int i = 0; i < nmatch; i++)
342  match[i] =
343  StringPiece(matchcap[2 * i],
344  static_cast<size_t>(matchcap[2 * i + 1] - matchcap[2 * i]));
345  return true;
346 }
347 
348 
349 // Analysis to determine whether a given regexp program is one-pass.
350 
351 // If ip is not on workq, adds ip to work queue and returns true.
352 // If ip is already on work queue, does nothing and returns false.
353 // If ip is NULL, does nothing and returns true (pretends to add it).
354 typedef SparseSet Instq;
355 static bool AddQ(Instq *q, int id) {
356  if (id == 0)
357  return true;
358  if (q->contains(id))
359  return false;
360  q->insert(id);
361  return true;
362 }
363 
364 struct InstCond {
365  int id;
367 };
368 
369 // Returns whether this is a one-pass program; that is,
370 // returns whether it is safe to use SearchOnePass on this program.
371 // These conditions must be true for any instruction ip:
372 //
373 // (1) for any other Inst nip, there is at most one input-free
374 // path from ip to nip.
375 // (2) there is at most one kInstByte instruction reachable from
376 // ip that matches any particular byte c.
377 // (3) there is at most one input-free path from ip to a kInstMatch
378 // instruction.
379 //
380 // This is actually just a conservative approximation: it might
381 // return false when the answer is true, when kInstEmptyWidth
382 // instructions are involved.
383 // Constructs and saves corresponding one-pass NFA on success.
385  if (did_onepass_)
386  return onepass_nodes_.data() != NULL;
387  did_onepass_ = true;
388 
389  if (start() == 0) // no match
390  return false;
391 
392  // Steal memory for the one-pass NFA from the overall DFA budget.
393  // Willing to use at most 1/4 of the DFA budget (heuristic).
394  // Limit max node count to 65000 as a conservative estimate to
395  // avoid overflowing 16-bit node index in encoding.
396  int maxnodes = 2 + inst_count(kInstByteRange);
397  int statesize = sizeof(OneState) + bytemap_range()*sizeof(uint32_t);
398  if (maxnodes >= 65000 || dfa_mem_ / 4 / statesize < maxnodes)
399  return false;
400 
401  // Flood the graph starting at the start state, and check
402  // that in each reachable state, each possible byte leads
403  // to a unique next state.
406  inst_count(kInstNop) + 1; // + 1 for start inst
408 
409  int size = this->size();
410  PODArray<int> nodebyid(size); // indexed by ip
411  memset(nodebyid.data(), 0xFF, size*sizeof nodebyid[0]);
412 
413  // Originally, nodes was a uint8_t[maxnodes*statesize], but that was
414  // unnecessarily optimistic: why allocate a large amount of memory
415  // upfront for a large program when it is unlikely to be one-pass?
416  std::vector<uint8_t> nodes;
417 
418  Instq tovisit(size), workq(size);
419  AddQ(&tovisit, start());
420  nodebyid[start()] = 0;
421  int nalloc = 1;
422  nodes.insert(nodes.end(), statesize, 0);
423  for (Instq::iterator it = tovisit.begin(); it != tovisit.end(); ++it) {
424  int id = *it;
425  int nodeindex = nodebyid[id];
426  OneState* node = IndexToNode(nodes.data(), statesize, nodeindex);
427 
428  // Flood graph using manual stack, filling in actions as found.
429  // Default is none.
430  for (int b = 0; b < bytemap_range_; b++)
431  node->action[b] = kImpossible;
432  node->matchcond = kImpossible;
433 
434  workq.clear();
435  bool matched = false;
436  int nstack = 0;
437  stack[nstack].id = id;
438  stack[nstack++].cond = 0;
439  while (nstack > 0) {
440  int id = stack[--nstack].id;
441  uint32_t cond = stack[nstack].cond;
442 
443  Loop:
444  Prog::Inst* ip = inst(id);
445  switch (ip->opcode()) {
446  default:
447  LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
448  break;
449 
450  case kInstAltMatch:
451  // TODO(rsc): Ignoring kInstAltMatch optimization.
452  // Should implement it in this engine, but it's subtle.
453  DCHECK(!ip->last());
454  // If already on work queue, (1) is violated: bail out.
455  if (!AddQ(&workq, id+1))
456  goto fail;
457  id = id+1;
458  goto Loop;
459 
460  case kInstByteRange: {
461  int nextindex = nodebyid[ip->out()];
462  if (nextindex == -1) {
463  if (nalloc >= maxnodes) {
464  if (ExtraDebug)
465  LOG(ERROR) << StringPrintf(
466  "Not OnePass: hit node limit %d >= %d", nalloc, maxnodes);
467  goto fail;
468  }
469  nextindex = nalloc;
470  AddQ(&tovisit, ip->out());
471  nodebyid[ip->out()] = nalloc;
472  nalloc++;
473  nodes.insert(nodes.end(), statesize, 0);
474  // Update node because it might have been invalidated.
475  node = IndexToNode(nodes.data(), statesize, nodeindex);
476  }
477  for (int c = ip->lo(); c <= ip->hi(); c++) {
478  int b = bytemap_[c];
479  // Skip any bytes immediately after c that are also in b.
480  while (c < 256-1 && bytemap_[c+1] == b)
481  c++;
482  uint32_t act = node->action[b];
483  uint32_t newact = (nextindex << kIndexShift) | cond;
484  if (matched)
485  newact |= kMatchWins;
486  if ((act & kImpossible) == kImpossible) {
487  node->action[b] = newact;
488  } else if (act != newact) {
489  if (ExtraDebug)
490  LOG(ERROR) << StringPrintf(
491  "Not OnePass: conflict on byte %#x at state %d", c, *it);
492  goto fail;
493  }
494  }
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++) {
499  int b = bytemap_[c];
500  // Skip any bytes immediately after c that are also in b.
501  while (c < 256-1 && bytemap_[c+1] == b)
502  c++;
503  uint32_t act = node->action[b];
504  uint32_t newact = (nextindex << kIndexShift) | cond;
505  if (matched)
506  newact |= kMatchWins;
507  if ((act & kImpossible) == kImpossible) {
508  node->action[b] = newact;
509  } else if (act != newact) {
510  if (ExtraDebug)
511  LOG(ERROR) << StringPrintf(
512  "Not OnePass: conflict on byte %#x at state %d", c, *it);
513  goto fail;
514  }
515  }
516  }
517 
518  if (ip->last())
519  break;
520  // If already on work queue, (1) is violated: bail out.
521  if (!AddQ(&workq, id+1))
522  goto fail;
523  id = id+1;
524  goto Loop;
525  }
526 
527  case kInstCapture:
528  case kInstEmptyWidth:
529  case kInstNop:
530  if (!ip->last()) {
531  // If already on work queue, (1) is violated: bail out.
532  if (!AddQ(&workq, id+1))
533  goto fail;
534  stack[nstack].id = id+1;
535  stack[nstack++].cond = cond;
536  }
537 
538  if (ip->opcode() == kInstCapture && ip->cap() < kMaxCap)
539  cond |= (1 << kCapShift) << ip->cap();
540  if (ip->opcode() == kInstEmptyWidth)
541  cond |= ip->empty();
542 
543  // kInstCapture and kInstNop always proceed to ip->out().
544  // kInstEmptyWidth only sometimes proceeds to ip->out(),
545  // but as a conservative approximation we assume it always does.
546  // We could be a little more precise by looking at what c
547  // is, but that seems like overkill.
548 
549  // If already on work queue, (1) is violated: bail out.
550  if (!AddQ(&workq, ip->out())) {
551  if (ExtraDebug)
552  LOG(ERROR) << StringPrintf(
553  "Not OnePass: multiple paths %d -> %d\n", *it, ip->out());
554  goto fail;
555  }
556  id = ip->out();
557  goto Loop;
558 
559  case kInstMatch:
560  if (matched) {
561  // (3) is violated
562  if (ExtraDebug)
563  LOG(ERROR) << StringPrintf(
564  "Not OnePass: multiple matches from %d\n", *it);
565  goto fail;
566  }
567  matched = true;
568  node->matchcond = cond;
569 
570  if (ip->last())
571  break;
572  // If already on work queue, (1) is violated: bail out.
573  if (!AddQ(&workq, id+1))
574  goto fail;
575  id = id+1;
576  goto Loop;
577 
578  case kInstFail:
579  break;
580  }
581  }
582  }
583 
584  if (ExtraDebug) { // For debugging, dump one-pass NFA to LOG(ERROR).
585  LOG(ERROR) << "bytemap:\n" << DumpByteMap();
586  LOG(ERROR) << "prog:\n" << Dump();
587 
588  std::map<int, int> idmap;
589  for (int i = 0; i < size; i++)
590  if (nodebyid[i] != -1)
591  idmap[nodebyid[i]] = i;
592 
593  std::string dump;
594  for (Instq::iterator it = tovisit.begin(); it != tovisit.end(); ++it) {
595  int id = *it;
596  int nodeindex = nodebyid[id];
597  if (nodeindex == -1)
598  continue;
599  OneState* node = IndexToNode(nodes.data(), statesize, nodeindex);
600  dump += StringPrintf("node %d id=%d: matchcond=%#x\n",
601  nodeindex, id, node->matchcond);
602  for (int i = 0; i < bytemap_range_; i++) {
603  if ((node->action[i] & kImpossible) == kImpossible)
604  continue;
605  dump += StringPrintf(" %d cond %#x -> %d id=%d\n",
606  i, node->action[i] & 0xFFFF,
607  node->action[i] >> kIndexShift,
608  idmap[node->action[i] >> kIndexShift]);
609  }
610  }
611  LOG(ERROR) << "nodes:\n" << dump;
612  }
613 
614  dfa_mem_ -= nalloc*statesize;
615  onepass_nodes_ = PODArray<uint8_t>(nalloc*statesize);
616  memmove(onepass_nodes_.data(), nodes.data(), nalloc*statesize);
617  return true;
618 
619 fail:
620  return false;
621 }
622 
623 } // namespace re2
re2::kInstFail
@ kInstFail
Definition: bloaty/third_party/re2/re2/prog.h:37
re2::Prog::did_onepass_
bool did_onepass_
Definition: bloaty/third_party/re2/re2/prog.h:399
re2::Prog::Inst::hi
int hi()
Definition: bloaty/third_party/re2/re2/prog.h:88
regen-readme.it
it
Definition: regen-readme.py:15
re2::OneState::matchcond
uint32_t matchcond
Definition: bloaty/third_party/re2/re2/onepass.cc:147
re2::Prog::SearchOnePass
bool SearchOnePass(const StringPiece &text, const StringPiece &context, Anchor anchor, MatchKind kind, StringPiece *match, int nmatch)
Definition: bloaty/third_party/re2/re2/onepass.cc:214
pod_array.h
memset
return memset(p, 0, total)
re2::kEmptyShift
static const int kEmptyShift
Definition: bloaty/third_party/re2/re2/onepass.cc:169
re2::Prog::kFullMatch
@ kFullMatch
Definition: bloaty/third_party/re2/re2/prog.h:195
re2::Prog::Inst
Definition: bloaty/third_party/re2/re2/prog.h:62
re2::Prog::Anchor
Anchor
Definition: bloaty/third_party/re2/re2/prog.h:175
match
unsigned char match[65280+2]
Definition: bloaty/third_party/zlib/examples/gun.c:165
string.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
re2::Satisfy
static bool Satisfy(uint32_t cond, const StringPiece &context, const char *p)
Definition: bloaty/third_party/re2/re2/onepass.cc:192
re2::PODArray::data
T * data() const
Definition: bloaty/third_party/re2/util/pod_array.h:24
re2::OneState::action
uint32_t action[]
Definition: bloaty/third_party/re2/re2/onepass.cc:148
re2::Prog::Inst::empty
EmptyOp empty()
Definition: bloaty/third_party/re2/re2/prog.h:92
re2
Definition: bloaty/third_party/re2/re2/bitmap256.h:17
re2::Prog::bytemap_range
int bytemap_range()
Definition: bloaty/third_party/re2/re2/prog.h:218
re2::Instq
SparseSet Instq
Definition: bloaty/third_party/re2/re2/onepass.cc:354
re2::Prog::Inst::cap
int cap()
Definition: bloaty/third_party/re2/re2/prog.h:86
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
re2::ApplyCaptures
static void ApplyCaptures(uint32_t cond, const char *p, const char **cap, int ncap)
Definition: bloaty/third_party/re2/re2/onepass.cc:201
re2::kInstEmptyWidth
@ kInstEmptyWidth
Definition: bloaty/third_party/re2/re2/prog.h:34
re2::Prog::inst_count
int inst_count(InstOp op)
Definition: bloaty/third_party/re2/re2/prog.h:208
sparse_set.h
re2::kCapShift
static const int kCapShift
Definition: bloaty/third_party/re2/re2/onepass.cc:174
re2::Prog::MatchKind
MatchKind
Definition: bloaty/third_party/re2/re2/prog.h:192
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
re2::SparseSetT::clear
void clear()
Definition: bloaty/third_party/re2/util/sparse_set.h:117
re2::kEmptyWordBoundary
@ kEmptyWordBoundary
Definition: bloaty/third_party/re2/re2/prog.h:47
re2::Prog::DumpByteMap
std::string DumpByteMap()
Definition: bloaty/third_party/re2/re2/prog.cc:175
re2::SparseSetT
Definition: bloaty/third_party/re2/util/sparse_set.h:69
re2::kInstCapture
@ kInstCapture
Definition: bloaty/third_party/re2/re2/prog.h:33
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
re2::InstCond
Definition: bloaty/third_party/re2/re2/onepass.cc:364
re2::kEmptyNonWordBoundary
@ kEmptyNonWordBoundary
Definition: bloaty/third_party/re2/re2/prog.h:48
re2::Prog::anchor_end
bool anchor_end()
Definition: bloaty/third_party/re2/re2/prog.h:216
LOG
#define LOG(severity)
Definition: bloaty/third_party/re2/util/logging.h:53
re2::AddQ
static bool AddQ(Instq *q, int id)
Definition: bloaty/third_party/re2/re2/onepass.cc:355
re2::kIndexShift
static const int kIndexShift
Definition: bloaty/third_party/re2/re2/onepass.cc:168
stacksize
static size_t stacksize(upb_pbdecoder *d, size_t entries)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:6485
cond
static uv_cond_t cond
Definition: threadpool.c:33
grpc_core::fail
Poll< absl::StatusOr< std::tuple< T... > > > fail()
Definition: try_join_test.cc:45
re2::kEmptyAllFlags
@ kEmptyAllFlags
Definition: bloaty/third_party/re2/re2/prog.h:49
nstack
int nstack
Definition: abseil-cpp/absl/synchronization/internal/graphcycles.cc:287
re2::StringPrintf
std::string StringPrintf(const char *format,...)
Definition: bloaty/third_party/re2/util/strutil.cc:140
re2::Prog::inst
Inst * inst(int id)
Definition: bloaty/third_party/re2/re2/prog.h:199
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
re2::Prog::kAnchored
@ kAnchored
Definition: bloaty/third_party/re2/re2/prog.h:177
re2::Prog::Inst::last
int last()
Definition: bloaty/third_party/re2/re2/prog.h:83
re2::InstCond::cond
uint32_t cond
Definition: bloaty/third_party/re2/re2/onepass.cc:366
stack
NodeStack stack
Definition: cord_rep_btree.cc:356
re2::Prog::size
int size()
Definition: bloaty/third_party/re2/re2/prog.h:204
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
re2::kCapMask
static const uint32_t kCapMask
Definition: bloaty/third_party/re2/re2/onepass.cc:178
re2::IndexToNode
static OneState * IndexToNode(uint8_t *nodes, int statesize, int nodeindex)
Definition: bloaty/third_party/re2/re2/onepass.cc:209
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
stdint.h
re2::Prog::bytemap
const uint8_t * bytemap()
Definition: bloaty/third_party/re2/re2/prog.h:219
re2::Prog::Inst::opcode
InstOp opcode()
Definition: bloaty/third_party/re2/re2/prog.h:82
grpc_core::Loop
promise_detail::Loop< F > Loop(F f)
Definition: loop.h:130
re2::Prog::IsOnePass
bool IsOnePass()
Definition: bloaty/third_party/re2/re2/onepass.cc:384
re2::Prog::kMaxOnePassCapture
static const int kMaxOnePassCapture
Definition: bloaty/third_party/re2/re2/prog.h:322
re2::Prog::Inst::foldcase
int foldcase()
Definition: bloaty/third_party/re2/re2/prog.h:89
re2::kImpossible
static const uint32_t kImpossible
Definition: bloaty/third_party/re2/re2/onepass.cc:180
re2::kInstNop
@ kInstNop
Definition: bloaty/third_party/re2/re2/prog.h:36
re2::kInstMatch
@ kInstMatch
Definition: bloaty/third_party/re2/re2/prog.h:35
re2::kMaxCap
static const int kMaxCap
Definition: bloaty/third_party/re2/re2/onepass.cc:175
re2::kInstAltMatch
@ kInstAltMatch
Definition: bloaty/third_party/re2/re2/prog.h:31
re2::Prog::bytemap_
uint8_t bytemap_[256]
Definition: bloaty/third_party/re2/re2/prog.h:420
re2::Rune
signed int Rune
Definition: bloaty/third_party/re2/util/utf.h:25
re2::SparseSetT::iterator
int * iterator
Definition: bloaty/third_party/re2/util/sparse_set.h:75
re2::Prog::anchor_start
bool anchor_start()
Definition: bloaty/third_party/re2/re2/prog.h:214
re2::Prog::Inst::out
int out()
Definition: bloaty/third_party/re2/re2/prog.h:84
re2::InstCond::id
int id
Definition: bloaty/third_party/re2/re2/onepass.cc:365
re2::ExtraDebug
static const bool ExtraDebug
Definition: bloaty/third_party/re2/re2/dfa.cc:71
re2::kRealMaxCap
static const int kRealMaxCap
Definition: bloaty/third_party/re2/re2/onepass.cc:171
re2::OneState
Definition: bloaty/third_party/re2/re2/onepass.cc:146
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
re2::Prog::bytemap_range_
int bytemap_range_
Definition: bloaty/third_party/re2/re2/prog.h:404
re2::Prog::kFirstMatch
@ kFirstMatch
Definition: bloaty/third_party/re2/re2/prog.h:193
re2::Prog::Inst::lo
int lo()
Definition: bloaty/third_party/re2/re2/prog.h:87
re2::kMatchWins
static const uint32_t kMatchWins
Definition: bloaty/third_party/re2/re2/onepass.cc:177
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
re2::kRealCapShift
static const int kRealCapShift
Definition: bloaty/third_party/re2/re2/onepass.cc:170
re2::Prog::dfa_mem_
int64_t dfa_mem_
Definition: bloaty/third_party/re2/re2/prog.h:416
DCHECK
#define DCHECK(condition)
Definition: bloaty/third_party/re2/util/logging.h:19
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
re2::Prog::onepass_nodes_
PODArray< uint8_t > onepass_nodes_
Definition: bloaty/third_party/re2/re2/prog.h:414
re2::StringPiece
Definition: bloaty/third_party/re2/re2/stringpiece.h:39
re2::PODArray
Definition: bloaty/third_party/re2/util/pod_array.h:14
re2::OnePass_Checks
void OnePass_Checks()
Definition: bloaty/third_party/re2/re2/onepass.cc:184
re2::kInstByteRange
@ kInstByteRange
Definition: bloaty/third_party/re2/re2/prog.h:32
re2::Prog::EmptyFlags
static uint32_t EmptyFlags(const StringPiece &context, const char *p)
Definition: bloaty/third_party/re2/re2/prog.cc:287
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
re2::Prog::start
int start()
Definition: bloaty/third_party/re2/re2/prog.h:200
id
uint32_t id
Definition: flow_control_fuzzer.cc:70
re2::Prog::Dump
std::string Dump()
Definition: bloaty/third_party/re2/re2/prog.cc:157


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:35