filtered_re2.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 2009 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#include <string>
6#include "util/util.h"
7#include "re2/filtered_re2.h"
8#include "re2/prefilter.h"
9#include "re2/prefilter_tree.h"
10
11namespace re2 {
12
13FilteredRE2::FilteredRE2()
14    : compiled_(false),
15      prefilter_tree_(new PrefilterTree()) {
16}
17
18FilteredRE2::~FilteredRE2() {
19  for (int i = 0; i < re2_vec_.size(); i++)
20    delete re2_vec_[i];
21  delete prefilter_tree_;
22}
23
24RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern,
25                                const RE2::Options& options, int* id) {
26  RE2* re = new RE2(pattern, options);
27  RE2::ErrorCode code = re->error_code();
28
29  if (!re->ok()) {
30    if (options.log_errors()) {
31      LOG(ERROR) << "Couldn't compile regular expression, skipping: "
32                 << re << " due to error " << re->error();
33    }
34    delete re;
35  } else {
36    *id = re2_vec_.size();
37    re2_vec_.push_back(re);
38  }
39
40  return code;
41}
42
43void FilteredRE2::Compile(vector<string>* atoms) {
44  if (compiled_ || re2_vec_.size() == 0) {
45    LOG(INFO) << "C: " << compiled_ << " S:" << re2_vec_.size();
46    return;
47  }
48
49  for (int i = 0; i < re2_vec_.size(); i++) {
50    Prefilter* prefilter = Prefilter::FromRE2(re2_vec_[i]);
51    prefilter_tree_->Add(prefilter);
52  }
53  atoms->clear();
54  prefilter_tree_->Compile(atoms);
55  compiled_ = true;
56}
57
58int FilteredRE2::SlowFirstMatch(const StringPiece& text) const {
59  for (int i = 0; i < re2_vec_.size(); i++)
60    if (RE2::PartialMatch(text, *re2_vec_[i]))
61      return i;
62  return -1;
63}
64
65int FilteredRE2::FirstMatch(const StringPiece& text,
66                            const vector<int>& atoms) const {
67  if (!compiled_) {
68    LOG(DFATAL) << "FirstMatch called before Compile";
69    return -1;
70  }
71  vector<int> regexps;
72  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
73  for (int i = 0; i < regexps.size(); i++)
74    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
75      return regexps[i];
76  return -1;
77}
78
79bool FilteredRE2::AllMatches(
80    const StringPiece& text,
81    const vector<int>& atoms,
82    vector<int>* matching_regexps) const {
83  matching_regexps->clear();
84  vector<int> regexps;
85  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
86  for (int i = 0; i < regexps.size(); i++)
87    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
88      matching_regexps->push_back(regexps[i]);
89  return !matching_regexps->empty();
90}
91
92void FilteredRE2::RegexpsGivenStrings(const vector<int>& matched_atoms,
93                                      vector<int>* passed_regexps) {
94  prefilter_tree_->RegexpsGivenStrings(matched_atoms, passed_regexps);
95}
96
97
98void FilteredRE2::PrintPrefilter(int regexpid) {
99  prefilter_tree_->PrintPrefilter(regexpid);
100}
101
102}  // namespace re2
103