Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
FormalRTE.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <ext/memory>
9#include <ext/utility>
10
14#include <core/stringApi.hpp>
15
17
18namespace core {
19
20template < class SymbolType >
21struct stringApi < rte::FormalRTEStructure < SymbolType > > {
23 static bool first ( ext::istream & input );
24 static void compose ( ext::ostream & output, const rte::FormalRTEStructure < SymbolType > & rte );
25private:
28
31
34 static rte::FormalRTESymbolSubst < SymbolType > substitutionSymbol ( ext::istream & input );
36
37 enum class Priority {
38 ALTERNATION,
39 CONCATENATION,
40 FACTOR
41 };
42
43 class Formal {
44 public:
51 };
52
53 class FormalReplace {
54 public:
55 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTEAlternation < SymbolType > & alternation, ext::set < common::ranked_symbol < SymbolType > > & constants);
56 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTESubstitution < SymbolType > & substitution, ext::set < common::ranked_symbol < SymbolType > > & constants);
57 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTEIteration < SymbolType > & iteration, ext::set < common::ranked_symbol < SymbolType > > & constants);
58 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTESymbolAlphabet < SymbolType > & symbol, ext::set < common::ranked_symbol < SymbolType > > & constants);
59 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTESymbolSubst < SymbolType > & epsilon, ext::set < common::ranked_symbol < SymbolType > > & constants);
60 static std::optional < rte::FormalRTESymbolSubst < SymbolType > > visit( rte::FormalRTEEmpty < SymbolType > & empty, ext::set < common::ranked_symbol < SymbolType > > & constants);
61 };
62};
63
64template < class SymbolType >
66 rte::FormalRTEStructure < SymbolType > res ( alternation ( input ) );
67 ext::set < common::ranked_symbol < SymbolType > > constants = res.getStructure ( ).computeMinimalAlphabets ( ).second;
68 rte::FormalRTEElement < SymbolType > & elem = res.getStructure ( );
69 elem.template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
70 return res;
71}
72
73template < class SymbolType >
75 return alternationCont(input, substitution(input));
76}
77
78template < class SymbolType >
79ext::ptr_value < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::alternationCont(ext::istream & input, ext::ptr_value < rte::FormalRTEElement < SymbolType > > left) {
80 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next(input);
83 return alternationCont ( input, std::move ( res ) );
84 } else {
86 return left;
87 }
88}
89
90template < class SymbolType >
91ext::ptr_value < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::substitution(ext::istream & input) {
92 return substitutionCont(input, factor(input));
93}
94
95template < class SymbolType >
96ext::ptr_value < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::substitutionCont(ext::istream & input, ext::ptr_value < rte::FormalRTEElement < SymbolType > > left) {
97 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next(input);
98 if ( token.type == rte::RTEFromStringLexer::TokenType::DOT ) {
99 rte::FormalRTESymbolSubst < SymbolType > symbol = substitutionSymbol ( input );
100 ext::ptr_value < rte::FormalRTEElement < SymbolType > > res ( rte::FormalRTESubstitution < SymbolType > ( std::move ( left ), factor ( input ), std::move ( symbol ) ) );
101 return substitutionCont ( input, std::move ( res ) );
102 } else {
104 return left;
105 }
106}
107template < class SymbolType >
108rte::FormalRTESymbolSubst < SymbolType > stringApi < rte::FormalRTEStructure < SymbolType > >::substitutionSymbol ( ext::istream & input ) {
110
111 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next ( input );
113 throw exception::CommonException ( "Missing rank." );
114
115 unsigned rank = ext::from_string < unsigned > ( token.value );
116
117 if ( rank != 0 )
118 throw exception::CommonException ( "Substitution symbol must have zero rank." );
119
121}
122
123template < class SymbolType >
124ext::ptr_value < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::factor(ext::istream & input) {
125 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next(input);
128 token = rte::RTEFromStringLexer::next(input);
129 if(token.type != rte::RTEFromStringLexer::TokenType::RPAR) throw exception::CommonException("Expected RPAR");
130 return star(input, std::move ( base ) );
131 } else if(token.type == rte::RTEFromStringLexer::TokenType::EMPTY) {
133 } else if(token.type == rte::RTEFromStringLexer::TokenType::ERROR) {
135
137
138 token = rte::RTEFromStringLexer::next ( input );
140 throw exception::CommonException ( "Missing rank." );
141
142 unsigned rank = ext::from_string < unsigned > ( token.value );
143
144 ext::ptr_vector < rte::FormalRTEElement < SymbolType > > children = arguments ( input );
145
147 return star ( input, std::move ( res ) );
148 } else {
149 throw exception::CommonException("Unrecognised token at factor rule");
150 }
151}
152
153template < class SymbolType >
154ext::ptr_value < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::star(ext::istream & input, rte::FormalRTEElement < SymbolType > && elem) {
155 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next(input);
157 rte::FormalRTESymbolSubst < SymbolType > symbol = substitutionSymbol ( input );
158 rte::FormalRTEIteration < SymbolType > iter ( std::move ( elem ), std::move ( symbol ) );
159 return star ( input, std::move ( iter ) );
160 } else {
162 return ext::ptr_value < rte::FormalRTEElement < SymbolType > > ( std::move ( elem ) );
163 }
164}
165
166template < class SymbolType >
167ext::ptr_vector < rte::FormalRTEElement < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::arguments ( ext::istream & input ) {
168 rte::RTEFromStringLexer::Token token = rte::RTEFromStringLexer::next(input);
169 if ( token.type != rte::RTEFromStringLexer::TokenType::LPAR ) {
170 rte::RTEFromStringLexer::putback ( input, token );
171 return { };
172 }
173
174 token = rte::RTEFromStringLexer::next(input);
176 return { };
177
179 rte::RTEFromStringLexer::putback ( input, token );
180 do {
181 res.push_back ( static_cast < rte::FormalRTEElement < SymbolType > && > ( alternation ( input ) ) );
182 token = rte::RTEFromStringLexer::next ( input );
183 } while ( token.type == rte::RTEFromStringLexer::TokenType::COMMA );
184
186 throw exception::CommonException("Expected RPAR");
187
188 return res;
189}
190
191template < class SymbolType >
192std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTEAlternation < SymbolType > & alternation, ext::set < common::ranked_symbol < SymbolType > > & constants) {
193 std::optional < rte::FormalRTESymbolSubst < SymbolType > > left = alternation.getLeftElement ( ).template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
194 if ( left )
195 alternation.setLeftElement ( std::move ( left.value ( ) ) );
196
197 std::optional < rte::FormalRTESymbolSubst < SymbolType > > right = alternation.getRightElement ( ).template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
198 if ( right )
199 alternation.setRightElement ( std::move ( right.value ( ) ) );
200
201 return std::nullopt;
202}
203
204template < class SymbolType >
205std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTESubstitution < SymbolType > & substitution, ext::set < common::ranked_symbol < SymbolType > > & constants) {
206 std::optional < rte::FormalRTESymbolSubst < SymbolType > > left = substitution.getLeftElement ( ).template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
207 if ( left )
208 substitution.setLeftElement ( std::move ( left.value ( ) ) );
209
210 std::optional < rte::FormalRTESymbolSubst < SymbolType > > right = substitution.getRightElement ( ).template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
211 if ( right )
212 substitution.setRightElement ( std::move ( right.value ( ) ) );
213
214 return std::nullopt;
215}
216
217template < class SymbolType >
218std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTEIteration < SymbolType > & iteration, ext::set < common::ranked_symbol < SymbolType > > & constants) {
219 std::optional < rte::FormalRTESymbolSubst < SymbolType > > element = iteration.getElement ( ).template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
220 if ( element )
221 iteration.setElement ( std::move ( element.value ( ) ) );
222
223 return std::nullopt;
224}
225
226template < class SymbolType >
227std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTESymbolAlphabet < SymbolType > & symbol, ext::set < common::ranked_symbol < SymbolType > > & constants) {
228 if ( constants.count ( symbol.getSymbol ( ) ) )
230
231 for ( unsigned i = 0; i < symbol.getElements ( ).size ( ); ++ i ) {
233 std::optional < rte::FormalRTESymbolSubst < SymbolType > > res = elem.template accept < std::optional < rte::FormalRTESymbolSubst < SymbolType > >, stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace > ( constants );
234 if ( res )
235 symbol.setElement ( i, std::move ( res.value ( ) ) );
236 }
237
238 return std::nullopt;
239}
240
241template < class SymbolType >
242std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTESymbolSubst < SymbolType > &, ext::set < common::ranked_symbol < SymbolType > > & ) {
243 return std::nullopt;
244}
245
246template < class SymbolType >
247std::optional < rte::FormalRTESymbolSubst < SymbolType > > stringApi < rte::FormalRTEStructure < SymbolType > >::FormalReplace::visit( rte::FormalRTEEmpty < SymbolType > &, ext::set < common::ranked_symbol < SymbolType > > & ) {
248 return std::nullopt;
249}
250
251template < class SymbolType >
253 return true;
254}
255
256template < class SymbolType >
258 Priority tmp = Priority::ALTERNATION;
260 rte.getStructure ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( out );
261}
262
263template < class SymbolType >
265 Priority outerPriorityMinimum = std::get < 0 > ( output );
266 if ( outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR ) std::get < 1 > ( output ) << '(';
267
268 std::get < 0 > ( output ) = Priority::ALTERNATION;
269 alternation.getLeftElement ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
270 std::get < 1 > ( output ) << '+';
271 alternation.getRightElement ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
272
273 if ( outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR ) std::get < 1 > ( output ) << ')';
274}
275
276template < class SymbolType >
277void stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit( const rte::FormalRTESubstitution < SymbolType > & substitution, ext::tuple < Priority &, ext::ostream & > & output ) {
278 Priority outerPriorityMinimum = std::get < 0 > ( output );
279 if ( outerPriorityMinimum == Priority::FACTOR ) std::get < 1 > ( output ) << '(';
280
281 std::get < 0 > ( output ) = Priority::CONCATENATION;
282 substitution.getLeftElement ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
283 std::get < 1 > ( output ) << '.';
284 stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit ( substitution.getSubstitutionSymbol ( ), output );
285 std::get < 1 > ( output ) << ' ';
286 std::get < 0 > ( output ) = Priority::CONCATENATION;
287 substitution.getRightElement ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
288
289 if ( outerPriorityMinimum == Priority::FACTOR ) std::get < 1 > ( output ) << ')';
290}
291
292template < class SymbolType >
293void stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit( const rte::FormalRTEIteration < SymbolType > & iteration, ext::tuple < Priority &, ext::ostream & > & output ) {
294 std::get < 0 > ( output ) = Priority::FACTOR;
295 iteration.getElement ( ).template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
296 std::get < 1 > ( output ) << "*";
297 stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit ( iteration.getSubstitutionSymbol ( ), output );
298}
299
300template < class SymbolType >
301void stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit( const rte::FormalRTESymbolAlphabet < SymbolType > & symbol, ext::tuple < Priority &, ext::ostream & > & output ) {
302 core::stringApi < SymbolType >::compose ( std::get < 1 > ( output ), symbol.getSymbol ( ).getSymbol ( ) );
303
304 std::get < 1 > ( output ) << " " << ext::to_string ( symbol.getSymbol ( ).getRank ( ) );
305
306 if ( symbol.getElements ( ).empty ( ) )
307 return;
308
309 std::get < 1 > ( output ) << " ( ";
310
311 bool first = true;
312 for ( const rte::FormalRTEElement < SymbolType > & c : symbol.getElements ( ) ) {
313 if ( first )
314 first = false;
315 else
316 std::get < 1 > ( output ) << ", ";
317
318 std::get < 0 > ( output ) = Priority::ALTERNATION;
319 c.template accept < void, stringApi < rte::FormalRTEStructure < SymbolType > >::Formal > ( output );
320 }
321
322 std::get < 1 > ( output ) << ")";
323}
324
325template < class SymbolType >
326void stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit( const rte::FormalRTESymbolSubst < SymbolType > & symbol, ext::tuple < Priority &, ext::ostream & > & output ) {
327 core::stringApi < SymbolType >::compose ( std::get < 1 > ( output ), symbol.getSymbol ( ).getSymbol ( ) );
328
329 std::get < 1 > ( output ) << " " << ext::to_string ( symbol.getSymbol ( ).getRank ( ) );
330}
331
332template < class SymbolType >
333void stringApi < rte::FormalRTEStructure < SymbolType > >::Formal::visit( const rte::FormalRTEEmpty < SymbolType > &, ext::tuple < Priority &, ext::ostream & > & output ) {
334 std::get < 1 > ( output ) << "#0";
335}
336
337template < class SymbolType >
338struct stringApi < rte::FormalRTE < SymbolType > > {
339 static rte::FormalRTE < SymbolType > parse ( ext::istream & input );
340 static bool first ( ext::istream & input );
341 static void compose ( ext::ostream & output, const rte::FormalRTE < SymbolType > & rte );
342};
343
344template < class SymbolType >
347}
348
349template < class SymbolType >
352}
353
354template < class SymbolType >
356 core::stringApi < rte::FormalRTEStructure < SymbolType > >::compose ( output, rte.getRTE ( ) );
357}
358
359} /* namespace core */
360
Definition: ranked_symbol.hpp:20
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
static void putback(ext::istream &input, const Token &token)
Definition: lexer.hpp:61
Definition: istream.h:32
Definition: ostream.h:14
Class representing wrapper of dynamically allocated object behaving like rvalue reference.
Definition: ptr_value.hpp:40
Implementation of vector storing dynamicaly allocated instances of given type. The class mimicks the ...
Definition: ptr_vector.hpp:44
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
Represents the alternation operator in the regular tree expression. The node must have exactly two ch...
Definition: FormalRTEAlternation.h:44
const FormalRTEElement< SymbolType > & getRightElement() const
Definition: FormalRTEAlternation.h:220
const FormalRTEElement< SymbolType > & getLeftElement() const
Definition: FormalRTEAlternation.h:215
void setLeftElement(FormalRTEElement< SymbolType > &&element)
Definition: FormalRTEAlternation.h:240
void setRightElement(FormalRTEElement< SymbolType > &&element)
Definition: FormalRTEAlternation.h:250
Definition: FormalRTEElement.h:54
Represents the empty expression in the regular tree expression. The node can't have any children.
Definition: FormalRTEEmpty.h:40
Represents the iteration operator in the regular tree expression. The node has exactly one child.
Definition: FormalRTEIteration.h:45
const FormalRTEElement< SymbolType > & getElement() const
Definition: FormalRTEIteration.h:215
const FormalRTESymbolSubst< SymbolType > & getSubstitutionSymbol() const
Definition: FormalRTEIteration.h:225
void setElement(const FormalRTEElement< SymbolType > &element)
Definition: FormalRTEIteration.h:235
Represents unbounded regular expression structure. Regular expression is stored as a tree of Unbounde...
Definition: FormalRTEStructure.h:41
Represents the concatenation operator in the regular tree expression. The node must have exactly two ...
Definition: FormalRTESubstitution.h:44
void setRightElement(const FormalRTEElement< SymbolType > &element)
Definition: FormalRTESubstitution.h:284
const FormalRTESymbolSubst< SymbolType > & getSubstitutionSymbol() const
Definition: FormalRTESubstitution.h:254
const FormalRTEElement< SymbolType > & getLeftElement() const
Definition: FormalRTESubstitution.h:244
const FormalRTEElement< SymbolType > & getRightElement() const
Definition: FormalRTESubstitution.h:249
void setLeftElement(const FormalRTEElement< SymbolType > &element)
Definition: FormalRTESubstitution.h:274
Represents the terminal symbol in the regular tree expression. The number of children must be the sam...
Definition: FormalRTESymbolAlphabet.h:44
void setElement(size_t index, const FormalRTEElement< SymbolType > &element)
Definition: FormalRTESymbolAlphabet.h:227
const ext::ptr_vector< FormalRTEElement< SymbolType > > & getElements() const
Definition: FormalRTESymbolAlphabet.h:207
const FormalRTEElement< SymbolType > & getElement(size_t index) const
Definition: FormalRTESymbolAlphabet.h:217
Represents the substitution symbol in the regular tree expression. The node can't have any children.
Definition: FormalRTESymbolSubst.h:43
const common::ranked_symbol< SymbolType > & getSymbol() const &
Definition: FormalRTESymbol.h:71
Formal regular tree expression represents regular tree expression. It describes regular tree language...
Definition: FormalRTE.h:71
static Token next(ext::istream &input)
Definition: RTEFromStringLexer.cpp:10
int i
Definition: AllEpsilonClosure.h:118
typename T::SymbolType SymbolType
Definition: ReachableStates.h:176
return res
Definition: MinimizeByPartitioning.h:145
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 visit(Visitor &&vis, Variants &&... vars)
Definition: variant.hpp:42
Definition: ToFTAGlushkov.h:22
Definition: stringApi.hpp:26