Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
Follow.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <ext/algorithm>
9#include <ext/iterator>
10
11#include <alib/vector>
12#include <alib/set>
13#include <alib/variant>
14
16
17#include <grammar/Grammar.h>
18
19#include "First.h"
20
21namespace grammar {
22
23namespace parsing {
24
25class Follow {
26 template < class T, class TerminalSymbolType, class NonterminalSymbolType >
27 static void follow ( const T & grammar, ext::map < NonterminalSymbolType, ext::set < ext::vector < TerminalSymbolType > > > & followSet );
28
29public:
30 template < class T, class TerminalSymbolType = typename grammar::TerminalSymbolTypeOfGrammar < T >, class NonterminalSymbolType = typename grammar::NonterminalSymbolTypeOfGrammar < T > >
32
33 template < class T, class NonterminalSymbolType, class TerminalSymbolType = typename grammar::TerminalSymbolTypeOfGrammar < T > >
34 static ext::set < ext::vector < TerminalSymbolType > > follow ( const T & grammar, const NonterminalSymbolType & nt );
35};
36
37template < class T, class TerminalSymbolType, class NonterminalSymbolType >
38void Follow::follow ( const T & grammar, ext::map < NonterminalSymbolType, ext::set < ext::vector < TerminalSymbolType > > > & followSet ) {
39 auto rawRules = grammar::RawRules::getRawRules ( grammar );
40 for ( const std::pair < const NonterminalSymbolType, ext::set < ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > > > > & rule : rawRules ) {
41 const NonterminalSymbolType & X = rule.first;
42
44 // every nt in rhs is Y
45 for ( typename ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); ++ it ) {
47
48 if ( ! grammar.getNonterminalAlphabet ( ).count ( Y ) )
49 continue;
50
52
53 if ( firstBeta.count ( ext::vector < TerminalSymbolType > ( ) ) ) {
54 firstBeta.erase ( ext::vector < TerminalSymbolType > ( ) );
55 followSet [ Y.template get < TerminalSymbolType > ( ) ].insert ( followSet[X].begin ( ), followSet[X].end ( ) );
56 }
57
58 followSet [ Y.template get < TerminalSymbolType > ( ) ].insert ( firstBeta.begin ( ), firstBeta.end ( ) );
59 }
60
61 }
62}
63
64template < class T, class TerminalSymbolType, class NonterminalSymbolType >
66 /*
67 * 1. Follow(S) = { \varepsilon }
68 * Follow(A) = {} forall A \in N, A \neq S
69 * 2. Forall p \in P:
70 * if p == X -> \alpha Y \beta
71 * Follow(Y) = Follow(Y) \cup (First(\beta) \setminus { \varepsilon})
72 * if p == X -> \alpha Y \beta \wedge \varepsilon \in First(\beta)
73 * Follow(Y) = Follow(Y) \cup Follow(X)
74 * 3. goto 2 if any follow set was changed in prev step.
75 */
76
78
79 for ( const NonterminalSymbolType & symb : grammar.getNonterminalAlphabet ( ) )
80 followSet1[symb];
81
82 followSet1[grammar.getInitialSymbol ( )] = { ext::vector < TerminalSymbolType > ( ) };
83
85
86 do {
87 follow ( grammar, followSet2 );
88
89 if ( followSet1 == followSet2 )
90 break;
91
92 followSet1 = followSet2;
93 } while ( true );
94
95 return followSet1;
96}
97
98template < class T, class NonterminalSymbolType, class TerminalSymbolType >
99ext::set < ext::vector < TerminalSymbolType > > Follow::follow ( const T & grammar, const NonterminalSymbolType & nt ) {
100 if ( ! grammar.getNonterminalAlphabet ( ).count ( nt ) )
101 throw exception::CommonException ( "Follow: Given symbol is not nonterminal." );
102
103 return follow ( grammar )[nt];
104}
105
106} /* namespace parsing */
107
108} /* namespace grammar */
109
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Definition: set.hpp:44
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: set.hpp:99
auto end() &
Inherited behavior of end for non-const instance.
Definition: set.hpp:129
Implementation of the variant class allowing to store any type of those listed in the template parame...
Definition: variant.hpp:98
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
static ext::map< NonterminalSymbolType, ext::set< ext::vector< ext::variant< TerminalSymbolType, NonterminalSymbolType > > > > getRawRules(const LG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: RawRules.h:92
Definition: Follow.h:25
auto begin(Container &&cont) -> decltype(std::forward(cont).begin())
Definition: iterator.hpp:900
Definition: ToAutomaton.h:24
void end()
Definition: measurements.cpp:19