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 <cstdint>
5
6#include <map>
7#include <set>
8
10
11namespace automaton {
12
13class DFANode {
14public:
15 struct Lt {
16 constexpr bool operator()(const DFANode* n, const DFANode* m) const noexcept { return n->id() < m->id(); }
17 };
18
19 DFANode(int id)
20 : id_(id) {}
21
22 constexpr int id() const noexcept { return id_; }
23 void add_transition(const DFANode* to, std::uint16_t c);
24 const DFANode* get_transition(std::uint16_t c) const;
25
26 // F: void(const DFANode*)
27 template<class F>
28 void for_transitions(F&& f, std::uint16_t c) const {
29 if (erroring_) return;
30 if (auto it = transitions_.find(c); it != transitions_.end()) f(it->second);
31 }
32
33 // F: void(std::uint16_t, const DFANode*)
34 template<class F>
35 void for_transitions(F&& f) const {
36 if (erroring_) return;
37 for (auto& [c, to] : transitions_)
38 f(c, to);
39 }
40
41 bool is_accepting() const noexcept { return accepting_; }
42 void set_accepting(bool accepting) noexcept {
43 assert(!(accepting && erroring_) && "state cannot be accepting and erroring");
44 accepting_ = accepting;
45 }
46
47 bool is_erroring() const noexcept { return erroring_; }
48 void set_erroring(bool erroring) noexcept {
49 assert(!(accepting_ && erroring) && "state cannot be accepting and erroring");
50 erroring_ = erroring;
51 }
52
53 friend std::ostream& operator<<(std::ostream& os, const DFANode& node);
54
55private:
56 int id_;
57 // ordered map keeps for_transitions() iteration in char order - and hence deterministic
58 std::map<std::uint16_t, const DFANode*> transitions_;
59 bool accepting_ = false;
60 bool erroring_ = false;
61};
62
63extern template class AutomatonBase<DFANode>;
64
66public:
67 DFA() = default;
68 DFA(const DFA&) = delete;
69 DFA& operator=(const DFA&) = delete;
70
71 enum SpecialTransitons : std::uint16_t {};
72};
73
74template<class To>
75using DFAMap = std::map<const DFANode*, To, DFANode::Lt>;
76using DFASet = std::set<const DFANode*, DFANode::Lt>;
77
78} // namespace automaton
void set_erroring(bool erroring) noexcept
Definition dfa.h:48
friend std::ostream & operator<<(std::ostream &os, const DFANode &node)
Definition dfa.cpp:19
DFANode(int id)
Definition dfa.h:19
void for_transitions(F &&f) const
Definition dfa.h:35
bool is_accepting() const noexcept
Definition dfa.h:41
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:22
bool is_erroring() const noexcept
Definition dfa.h:47
void set_accepting(bool accepting) noexcept
Definition dfa.h:42
void for_transitions(F &&f, std::uint16_t c) const
Definition dfa.h:28
SpecialTransitons
Definition dfa.h:71
DFA & operator=(const DFA &)=delete
DFA()=default
DFA(const DFA &)=delete
std::set< const DFANode *, DFANode::Lt > DFASet
Definition dfa.h:76
std::map< const DFANode *, To, DFANode::Lt > DFAMap
Definition dfa.h:75
constexpr bool operator()(const DFANode *n, const DFANode *m) const noexcept
Definition dfa.h:16