MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
dfa.h
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <concepts>
5#include <cstdint>
6
7#include <map>
8#include <set>
9
10#include "automaton/automaton.h"
11
12namespace automaton {
13
14class DFANode {
15public:
16 struct Lt {
17 constexpr bool operator()(const DFANode* n, const DFANode* m) const noexcept { return n->id() < m->id(); }
18 };
19
20 DFANode(int id)
21 : id_(id) {}
22
23 constexpr int id() const noexcept { return id_; }
24 void add_transition(const DFANode* to, std::uint16_t c);
25 const DFANode* get_transition(std::uint16_t c) const;
26
27 void for_transitions(std::invocable<const DFANode*> auto f, std::uint16_t c) const {
28 if (erroring_) return;
29 if (auto it = transitions_.find(c); it != transitions_.end()) f(it->second);
30 }
31
32 void for_transitions(std::invocable<std::uint16_t, const DFANode*> auto f) const {
33 if (erroring_) return;
34 for (auto& [c, to] : transitions_)
35 f(c, to);
36 }
37
38 bool is_accepting() const noexcept { return accepting_; }
39 void set_accepting(bool accepting) noexcept {
40 assert(!(accepting && erroring_) && "state cannot be accepting and erroring");
41 accepting_ = accepting;
42 }
43
44 bool is_erroring() const noexcept { return erroring_; }
45 void set_erroring(bool erroring) noexcept {
46 assert(!(accepting_ && erroring) && "state cannot be accepting and erroring");
47 erroring_ = erroring;
48 }
49
50 void print(std::ostream& os) const;
51
52private:
53 int id_;
54 // ordered map keeps for_transitions() iteration in char order - and hence deterministic
55 std::map<std::uint16_t, const DFANode*> transitions_;
56 bool accepting_ = false;
57 bool erroring_ = false;
58};
59
60extern template class AutomatonBase<DFANode>;
61
63public:
64 DFA() = default;
65 DFA(const DFA&) = delete;
66 DFA& operator=(const DFA&) = delete;
67};
68
69template<class To>
70using DFAMap = std::map<const DFANode*, To, DFANode::Lt>;
71using DFASet = std::set<const DFANode*, DFANode::Lt>;
72
73} // namespace automaton
void for_transitions(std::invocable< const DFANode * > auto f, std::uint16_t c) const
Definition dfa.h:27
void set_erroring(bool erroring) noexcept
Definition dfa.h:45
void for_transitions(std::invocable< std::uint16_t, const DFANode * > auto f) const
Definition dfa.h:32
void print(std::ostream &os) const
Definition dfa.cpp:19
DFANode(int id)
Definition dfa.h:20
bool is_accepting() const noexcept
Definition dfa.h:38
const DFANode * get_transition(std::uint16_t c) const
Definition dfa.cpp:11
void add_transition(const DFANode *to, std::uint16_t c)
Definition dfa.cpp:9
constexpr int id() const noexcept
Definition dfa.h:23
bool is_erroring() const noexcept
Definition dfa.h:44
void set_accepting(bool accepting) noexcept
Definition dfa.h:39
DFA & operator=(const DFA &)=delete
DFA()=default
DFA(const DFA &)=delete
std::set< const DFANode *, DFANode::Lt > DFASet
Definition dfa.h:71
std::map< const DFANode *, To, DFANode::Lt > DFAMap
Definition dfa.h:70
constexpr bool operator()(const DFANode *n, const DFANode *m) const noexcept
Definition dfa.h:17