32 #include "util/test.h"
33 #include "util/logging.h"
34 #include "util/strutil.h"
36 #include "re2/testing/regexp_generator.h"
42 static const char *
ops[] = {
55 const std::vector<std::string>& atoms,
56 const std::vector<std::string>&
ops)
57 : maxatoms_(maxatoms), maxops_(maxops), atoms_(atoms), ops_(
ops) {
67 void RegexpGenerator::Generate() {
68 std::vector<std::string> postfix;
69 GeneratePostfix(&postfix, 0, 0, 0);
73 void RegexpGenerator::GenerateRandom(
int32_t seed,
int n) {
76 for (
int i = 0;
i <
n;
i++) {
77 std::vector<std::string> postfix;
78 GenerateRandomPostfix(&postfix, 0, 0, 0);
84 const char *
p = s.c_str();
86 while ((
p = strstr(
p,
"%s")) != NULL) {
106 void RegexpGenerator::GeneratePostfix(std::vector<std::string>*
post,
107 int nstk,
int ops,
int atoms) {
114 if (
ops + nstk - 1 > maxops_)
118 if (atoms < maxatoms_) {
119 for (
size_t i = 0;
i < atoms_.size();
i++) {
120 post->push_back(atoms_[
i]);
121 GeneratePostfix(
post, nstk + 1,
ops, atoms + 1);
128 for (
size_t i = 0;
i < ops_.size();
i++) {
133 GeneratePostfix(
post, nstk -
nargs + 1,
ops + 1, atoms);
142 bool RegexpGenerator::GenerateRandomPostfix(std::vector<std::string>*
post,
143 int nstk,
int ops,
int atoms) {
144 std::uniform_int_distribution<int> random_stop(0, maxatoms_ - atoms);
145 std::uniform_int_distribution<int> random_bit(0, 1);
146 std::uniform_int_distribution<int> random_ops_index(
147 0,
static_cast<int>(ops_.size()) - 1);
148 std::uniform_int_distribution<int> random_atoms_index(
149 0,
static_cast<int>(atoms_.size()) - 1);
153 if (nstk == 1 && random_stop(
rng_) == 0) {
161 if (
ops + nstk - 1 > maxops_)
165 if (
ops < maxops_ && random_bit(
rng_) == 0) {
170 bool ret = GenerateRandomPostfix(
post, nstk -
nargs + 1,
179 if (atoms < maxatoms_ && random_bit(
rng_) == 0) {
180 post->push_back(atoms_[random_atoms_index(
rng_)]);
181 bool ret = GenerateRandomPostfix(
post, nstk + 1,
ops, atoms + 1);
192 void RegexpGenerator::RunPostfix(
const std::vector<std::string>&
post) {
193 std::stack<std::string> regexps;
194 for (
size_t i = 0;
i <
post.size();
i++) {
199 regexps.push(
post[
i]);
220 if (regexps.size() != 1) {
222 printf(
"Bad regexp program:\n");
223 for (
size_t i = 0;
i <
post.size();
i++) {
226 printf(
"Stack after running program:\n");
227 while (!regexps.empty()) {
231 LOG(
FATAL) <<
"Bad regexp program.";
234 HandleRegexp(regexps.top());
235 HandleRegexp(
"^(?:" + regexps.top() +
")$");
236 HandleRegexp(
"^(?:" + regexps.top() +
")");
237 HandleRegexp(
"(?:" + regexps.top() +
")$");
241 std::vector<std::string>
Explode(
const StringPiece& s) {
242 std::vector<std::string>
v;
244 for (
const char *q =
s.data(); q <
s.data() +
s.size(); ) {
256 std::vector<std::string>
Split(
const StringPiece&
sep,
const StringPiece& s) {
257 std::vector<std::string>
v;
262 const char *
p =
s.data();
263 for (
const char *q =
s.data(); q +
sep.size() <=
s.data() +
s.size(); q++) {
264 if (StringPiece(q,
sep.size()) ==
sep) {
271 if (
p <
s.data() +
s.size())