15 #ifndef RAPIDJSON_INTERNAL_REGEX_H_
16 #define RAPIDJSON_INTERNAL_REGEX_H_
18 #include "../allocators.h"
19 #include "../stream.h"
24 RAPIDJSON_DIAG_OFF(padded)
25 RAPIDJSON_DIAG_OFF(switch-enum)
26 RAPIDJSON_DIAG_OFF(implicit-fallthrough)
31 RAPIDJSON_DIAG_OFF(effc++)
36 RAPIDJSON_DIAG_OFF(4512)
39 #ifndef RAPIDJSON_REGEX_VERBOSE
40 #define RAPIDJSON_REGEX_VERBOSE 0
84 template <
typename Encoding,
typename Allocator = CrtAllocator>
87 typedef typename Encoding::Ch
Ch;
106 template <
typename InputStream>
116 template <
typename InputStream>
160 template <
typename SourceStream>
184 return states_.template Bottom<State>()[index];
189 return states_.template Bottom<State>()[index];
194 return ranges_.template Bottom<Range>()[index];
199 return ranges_.template Bottom<Range>()[index];
202 template <
typename InputStream>
209 *atomCountStack.template Push<unsigned>() = 0;
212 while (ds.
Peek() != 0) {
213 switch (codepoint = ds.
Take()) {
223 while (!operatorStack.
Empty() && *operatorStack.template Top<Operator>() <
kAlternation)
224 if (!
Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
226 *operatorStack.template Push<Operator>() =
kAlternation;
227 *atomCountStack.template Top<unsigned>() = 0;
232 *atomCountStack.template Push<unsigned>() = 0;
237 if (!
Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
239 if (operatorStack.
Empty())
241 operatorStack.template Pop<Operator>(1);
242 atomCountStack.template Pop<unsigned>(1);
267 if (ds.
Peek() ==
',') {
269 if (ds.
Peek() ==
'}')
295 *operandStack.template Push<Frag>() =
Frag(s, s, s);
311 while (!operatorStack.
Empty())
312 if (!
Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
317 Frag*
e = operandStack.template Pop<Frag>(1);
321 #if RAPIDJSON_REGEX_VERBOSE
322 printf(
"root: %d\n",
root_);
325 printf(
"[%2d] out: %2d out1: %2d c: '%c'\n", i, s.
out, s.
out1, (
char)s.
codepoint);
351 *operandStack.template Push<Frag>() =
Frag(s, s, s);
355 if (*atomCountStack.template Top<unsigned>())
357 (*atomCountStack.template Top<unsigned>())++;
380 Frag e2 = *operandStack.template Pop<Frag>(1);
381 Frag e1 = *operandStack.template Pop<Frag>(1);
383 *operandStack.template Push<Frag>() =
Frag(e1.start, e2.
out,
Min(e1.minIndex, e2.
minIndex));
389 Frag e2 = *operandStack.template Pop<Frag>(1);
390 Frag e1 = *operandStack.template Pop<Frag>(1);
399 Frag e = *operandStack.template Pop<Frag>(1);
408 Frag e = *operandStack.template Pop<Frag>(1);
411 *operandStack.template Push<Frag>() =
Frag(s, s, e.
minIndex);
419 Frag e = *operandStack.template Pop<Frag>(1);
440 for (
unsigned i = 0; i < m - 1; i++)
442 for (
unsigned i = 0; i < m - 1; i++)
448 for (
unsigned i = 0; i < n - 1; i++)
456 for (
unsigned i = n; i < m - 1; i++)
458 for (
unsigned i = n; i <
m; i++)
462 for (
unsigned i = 0; i < n - 1; i++)
471 const Frag src = *operandStack.template Top<Frag>();
481 *operandStack.template Push<Frag>() =
Frag(src.
start + count, src.
out + count, src.
minIndex + count);
485 template <
typename InputStream>
488 if (ds.
Peek() <
'0' || ds.
Peek() >
'9')
490 while (ds.
Peek() >=
'0' && ds.
Peek() <=
'9') {
491 if (r >= 429496729 && ds.
Peek() >
'5')
493 r = r * 10 + (ds.
Take() -
'0');
499 template <
typename InputStream>
507 while ((codepoint = ds.
Take()) != 0) {
510 if (codepoint ==
'^') {
531 if (ds.
Peek() ==
'b') {
542 if (codepoint ==
'-') {
577 template <
typename InputStream>
580 switch (codepoint = ds.
Take()) {
595 *escapedCodepoint = codepoint;
return true;
596 case 'f': *escapedCodepoint = 0x000C;
return true;
597 case 'n': *escapedCodepoint = 0x000A;
return true;
598 case 'r': *escapedCodepoint = 0x000D;
return true;
599 case 't': *escapedCodepoint = 0x0009;
return true;
600 case 'v': *escapedCodepoint = 0x000B;
return true;
606 template <
typename InputStream>
618 while (!current->
Empty() && (codepoint = ds.
Take()) != 0) {
622 for (
const SizeType*
s = current->template Bottom<SizeType>();
s != current->template End<SizeType>(); ++
s) {
629 if (!anchorEnd && matched)
654 else if (!(
stateSet_[index >> 5] & (1 << (index & 31)))) {
655 stateSet_[index >> 5] |= (1 << (index & 31));
656 *l.template PushUnsafe<SizeType>() = index;
701 #endif // RAPIDJSON_INTERNAL_REGEX_H_