Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
NFA.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <automaton/FSM/NFA.h>
9#include <core/stringApi.hpp>
10
12
14
15namespace core {
16
17template<class SymbolType, class StateType >
18struct stringApi < automaton::NFA < SymbolType, StateType > > {
20 static bool first ( ext::istream & input );
21 static void compose ( ext::ostream & output, const automaton::NFA < SymbolType, StateType > & automaton );
22private:
23 static void parseTransition(ext::istream& input, ext::set<StateType>& states, const ext::vector<SymbolType>& symbols, StateType*& initialState, ext::set<StateType>& finalStates, ext::set<ext::tuple<StateType, SymbolType, StateType>>& transitionFunction);
24 static void composeTransitionsFromState(ext::ostream& output, const automaton::NFA < SymbolType, StateType > & automaton, const StateType & from);
25};
26
27template<class SymbolType, class StateType >
29 automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next(input);
30
33 }
34
36 throw exception::CommonException("Unrecognised NFA token." + ext::to_string ( static_cast < int > ( token.type ) ) );
37 }
39
44 symbols.push_back(symbol);
45
47 }
48
49 StateType* initialState = nullptr;
50 ext::set < StateType> finalStates;
53
57 break;
59 continue;
60 else
62
63 parseTransition(input, states, symbols, initialState, finalStates, transitionFunction);
65 }
66
68 throw exception::CommonException("Extra data after the automaton.");
69
70 if(initialState == nullptr) throw exception::CommonException("No initial state recognised.");
71
72 automaton::NFA < > res(*initialState);
73 delete initialState;
74
75 res.setInputAlphabet(ext::set < SymbolType>(symbols.begin(), symbols.end()));
76 res.setStates(states);
77 res.setFinalStates(finalStates);
78 for(const ext::tuple < StateType, SymbolType, StateType> & transition : transitionFunction) {
79 res.addTransition(std::get<0>(transition), std::get<1>(transition), std::get<2>(transition));
80 }
81
82 return res;
83}
84
85template<class SymbolType, class StateType >
87 bool initial = false;
88 bool final = false;
89
91
93 states.insert(from);
94 if(initial) {
95 if(initialState != nullptr)
96 throw exception::CommonException("Multiple initial states are not available for NFA type");
97 initialState = new StateType ( from );
98 }
99 if(final)
100 finalStates.insert(from);
101
102 automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next(input);
103 typename ext::vector < SymbolType >::const_iterator iter = symbols.begin();
104
106 if(iter == symbols.end())
107 throw exception::CommonException("Invalid line format");
108
111 do {
113 states.insert(to);
114 transitionFunction.insert(ext::make_tuple(from, *iter, to));
115
118 } while(true);
119 } else {
121 }
122 ++iter;
123 }
125
126 if(iter != symbols.end())
127 throw exception::CommonException("Invalid line format");
128}
129
130template<class SymbolType, class StateType >
133}
134
135template<class SymbolType, class StateType >
137 output << "NFA";
138 for(const auto& symbol : automaton.getInputAlphabet()) {
139 output << " ";
141 }
142
143 output << std::endl;
144
145 for(const auto& state : automaton.getStates()) {
146 if(automaton.getInitialState() == state) {
147 output << ">";
148 }
149 if(automaton.getFinalStates().find(state) != automaton.getFinalStates().end()) {
150 output << "<";
151 }
153
154 composeTransitionsFromState(output, automaton, state);
155
156 output << std::endl;
157 }
158}
159
160template < class SymbolType, class StateType >
162 for(const SymbolType& inputSymbol : automaton.getInputAlphabet()) {
163 const auto toStates = automaton.getTransitions ( ).equal_range ( ext::tie ( from, inputSymbol ) );
164 if ( toStates.empty ( ) ) {
165 output << " -";
166 } else {
167 bool sign = false;
168 for(const auto & transition : toStates ) {
169 output << (sign ? "|" : " ");
170 core::stringApi<StateType>::compose(output, transition.second);
171 sign = true;
172 }
173 }
174 }
175}
176
177} /* namespace core */
178
static Token next(ext::istream &input)
Definition: AutomatonFromStringLexer.cpp:12
Nondeterministic finite automaton. Accepts regular languages.
Definition: NFA.h:66
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
static Token peek(ext::istream &input)
Definition: lexer.hpp:53
static void putback(ext::istream &input, const Token &token)
Definition: lexer.hpp:61
Definition: istream.h:32
Definition: ostream.h:14
Definition: set.hpp:44
Class extending the tuple class from the standard library. Original reason is to allow printing of th...
Definition: tuple.hpp:42
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: vector.hpp:125
typename std::vector< T, Alloc >::const_iterator const_iterator
The type of constant values iterator.
Definition: vector.hpp:67
auto end() &
Inherited behavior of end for non-const instance.
Definition: vector.hpp:155
typename T::StateType StateType
Definition: ToGrammarLeftRG.h:64
typename T::SymbolType SymbolType
Definition: ReachableStates.h:176
return res
Definition: MinimizeByPartitioning.h:145
Definition: ToGrammar.h:31
Definition: normalize.hpp:10
constexpr tuple< Elements &... > tie(Elements &... args) noexcept
Helper of extended tuple of references construction. The tuple is constructed to reffer to values in ...
Definition: tuple.hpp:218
std::string to_string(const T &value)
To string method designated for objects that can be casted to string.
Definition: string.hpp:131
constexpr auto make_tuple(Elements &&... args)
Helper of extended tuple construction. The tuple is constructed from values pack, types are deduced.
Definition: tuple.hpp:203
static void initialFinalState(ext::istream &input, bool &rightArrow, bool &leftArrow)
Definition: AutomatonFromStringParserCommon.cpp:10
Definition: stringApi.hpp:26