18const auto All_Chars = fe::Bitset(256,
true);
21fe::Bitset gather_chars(
const Def* regex) {
22 auto res = fe::Bitset();
23 for (
auto arg : detail::flatten_in_arg<regex::disj>(regex)) {
25 res |= All_Chars - gather_chars(
not_->arg());
31 &&
"as per normalizer, if we're in a 'not' argument, we must only have disjs, nots and ranges!");
35 for (std::uint16_t c = lb;
c <= ub; ++
c)
42struct Regex2NfaConverter {
44 : nfa_(std::make_unique<automaton::NFA>()) {}
46 void add_range_transitions(automaton::NFANode* from, automaton::NFANode* to, std::uint16_t lb, std::uint16_t ub) {
47 for (
auto i = lb; i <= ub; ++i)
51 void add_range_transitions(automaton::NFANode* from, automaton::NFANode* to,
const Def* lit0,
const Def* lit1) {
52 auto lb = lit0->as<
Lit>()->
get();
53 auto ub = lit1->as<
Lit>()->
get();
54 add_range_transitions(from, to, lb, ub);
58 convert(
const Def* regex, automaton::NFANode* start, automaton::NFANode* end, automaton::NFANode* error =
nullptr) {
60 auto middle = nfa_->add_state();
61 convert(
conj->arg(2, 0), start, middle, error);
62 convert(
conj->arg(2, 1), middle, end, error);
64 add_range_transitions(start, end, 0_u16, 255);
66 add_range_transitions(start, end,
range->arg(2, 0),
range->arg(2, 1));
67 if (error) add_range_transitions(start, error, 0, 255);
69 auto first = nfa_->add_state();
73 for (
auto c : All_Chars - gather_chars(
not_->arg()))
74 first->add_transition(end, std::uint16_t(c));
76 auto first = nfa_->add_state();
77 auto error = nfa_->add_state();
78 error->set_erroring(
true);
82 convert(
neg->arg(), first, error, end);
85 convert(
disj->arg(2, 0), start, end, error);
86 convert(
disj->arg(2, 1), start, end, error);
89 convert(opt->arg(), start, end);
91 auto m1 = nfa_->add_state();
92 auto m2 = nfa_->add_state();
97 convert(
star->arg(), m1, m2);
99 auto m0 = nfa_->add_state();
100 auto m1 = nfa_->add_state();
101 auto m2 = nfa_->add_state();
102 convert(
plus->arg(), start, m0, error);
107 convert(
plus->arg(), m1, m2);
113 void convert(
const Def* regex) {
114 auto start = nfa_->add_state();
115 nfa_->set_start(start);
116 auto end = nfa_->add_state();
118 convert(regex, start, end);
121 std::unique_ptr<automaton::NFA> nfa() {
return std::move(nfa_); }
124 std::unique_ptr<automaton::NFA> nfa_;
130 Regex2NfaConverter converter;
131 converter.convert(
regex);
132 return converter.nfa();
void set_accepting(bool accepting)
void add_transition(const NFANode *to, std::uint16_t c)
static auto isa(const Def *def)
static T as(const Def *def)
std::unique_ptr< automaton::NFA > regex2nfa(const Def *regex)
automaton::NFA * regex2nfa(const mim::Def *regex)
You can fe::dl::get this function.