MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
automaton.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <algorithm>
4
#include <iostream>
5
#include <list>
6
#include <map>
7
#include <set>
8
#include <vector>
9
10
#include "
automaton/range_helper.h
"
11
12
namespace
automaton
{
13
14
class
DFANode
;
15
class
NFANode
;
16
17
template
<
class
NodeType>
18
class
AutomatonBase
{
19
public
:
20
AutomatonBase
() =
default
;
21
AutomatonBase
(
const
AutomatonBase
&) =
delete
;
22
AutomatonBase
&
operator=
(
const
AutomatonBase
&) =
delete
;
23
24
NodeType*
add_state
() {
25
nodes_.emplace_back(id_++);
26
return
&nodes_.back();
27
}
28
29
void
set_start
(
const
NodeType* start) { start_ = start; }
30
31
const
NodeType*
get_start
()
const
{
return
start_; }
32
33
/// Ordered by NodeType::Lt (i.e. by id) so that iteration is deterministic.
34
std::set<const NodeType*, typename NodeType::Lt>
get_reachable_states
()
const
{
35
std::set<const NodeType*, typename NodeType::Lt> reachableStates;
36
std::vector<const NodeType*> workList;
37
workList.push_back(
get_start
());
38
while
(!workList.empty()) {
39
auto
state = workList.back();
40
workList.pop_back();
41
reachableStates.insert(state);
42
state->for_transitions([&](
auto
,
auto
to) {
43
if
(!reachableStates.contains(to)) workList.push_back(to);
44
});
45
}
46
return
reachableStates;
47
}
48
49
friend
std::ostream&
operator<<
(std::ostream& os,
const
AutomatonBase
&
automaton
) {
50
if
constexpr
(std::is_same_v<NodeType, DFANode>)
51
os <<
"digraph dfa {\n"
;
52
else
if
constexpr
(std::is_same_v<NodeType, NFANode>)
53
os <<
"digraph nfa {\n"
;
54
else
55
os <<
"digraph automaton {\n"
;
56
os <<
" start -> \""
<<
automaton
.start_->id() <<
"\";\n"
;
57
58
for
(
auto
& node :
automaton
.nodes_)
59
os << node;
60
os <<
"}\n"
;
61
return
os;
62
}
63
64
private
:
65
std::list<NodeType> nodes_;
66
const
NodeType* start_ =
nullptr
;
67
int
id_ = 0;
68
};
69
70
template
<
class
NodeType,
class
Pr
int
CharF>
71
std::ostream&
print_node
(std::ostream& os,
const
NodeType& node, PrintCharF&& print_char) {
72
if
(node.is_accepting()) os <<
" \""
<< node.id() <<
"\" [shape=doublecircle];\n"
;
73
if
(node.is_erroring()) os <<
" \""
<< node.id() <<
"\" [shape=square];\n"
;
74
75
std::map<const NodeType*, std::vector<Range>,
typename
NodeType::Lt> node2transitions;
76
node.for_transitions([&](
auto
c,
auto
to) {
77
if
(!node2transitions.contains(to))
78
node2transitions.try_emplace(to, std::vector<Range>{
79
Range
{c, c}
80
});
81
else
82
node2transitions[to].push_back({c, c});
83
});
84
85
for
(
auto
& [to, ranges] : node2transitions) {
86
std::sort(ranges.begin(), ranges.end(),
RangeCompare
{});
87
ranges =
merge_ranges
(ranges);
88
for
(
auto
& [lo, hi] : ranges) {
89
os <<
" \""
<< node.id() <<
"\" -> \""
<< to->id() <<
"\" [label=\""
90
<< std::forward<PrintCharF>(print_char)(lo);
91
if
(lo != hi) os <<
"-"
<< std::forward<PrintCharF>(print_char)(hi);
92
os <<
" ("
<< lo;
93
if
(lo != hi) os <<
"-"
<< hi;
94
os <<
")\"];\n"
;
95
}
96
}
97
98
return
os;
99
}
100
101
}
// namespace automaton
automaton::AutomatonBase::set_start
void set_start(const NodeType *start)
Definition
automaton.h:29
automaton::AutomatonBase::add_state
NodeType * add_state()
Definition
automaton.h:24
automaton::AutomatonBase::get_reachable_states
std::set< const NodeType *, typename NodeType::Lt > get_reachable_states() const
Ordered by NodeType::Lt (i.e. by id) so that iteration is deterministic.
Definition
automaton.h:34
automaton::AutomatonBase::AutomatonBase
AutomatonBase()=default
automaton::AutomatonBase::get_start
const NodeType * get_start() const
Definition
automaton.h:31
automaton::AutomatonBase::operator<<
friend std::ostream & operator<<(std::ostream &os, const AutomatonBase &automaton)
Definition
automaton.h:49
automaton::AutomatonBase::AutomatonBase
AutomatonBase(const AutomatonBase &)=delete
automaton::AutomatonBase::operator=
AutomatonBase & operator=(const AutomatonBase &)=delete
automaton::DFANode
Definition
dfa.h:13
automaton::NFANode
Definition
nfa.h:13
automaton
Definition
automaton.h:12
automaton::Range
std::pair< std::uint64_t, std::uint64_t > Range
Definition
range_helper.h:12
automaton::print_node
std::ostream & print_node(std::ostream &os, const NodeType &node, PrintCharF &&print_char)
Definition
automaton.h:71
automaton::merge_ranges
std::optional< Range > merge_ranges(Range a, Range b) noexcept
Definition
range_helper.h:18
range_helper.h
automaton::RangeCompare
Definition
range_helper.h:14
include
automaton
automaton.h
Generated by
1.18.0