Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
RecursiveNonterminal.h
Go to the documentation of this file.
1
6#pragma once
7
9
10#include <alib/set>
11#include <alib/deque>
12
14
15#include <grammar/RawRules.h>
16
17namespace grammar {
18
19namespace properties {
20
25public:
38 template < class T, class NonterminalSymbolType, class TerminalSymbolType = typename grammar::TerminalSymbolTypeOfGrammar < T > >
39 static bool isNonterminalRecursive ( const T & grammar, const NonterminalSymbolType & nonterminal );
40
41};
42
43template < class T, class NonterminalSymbolType, class TerminalSymbolType >
44bool RecursiveNonterminal::isNonterminalRecursive ( const T & grammar, const NonterminalSymbolType & nonterminal ) {
45 if ( grammar.getNonterminalAlphabet ( ).count ( nonterminal ) == 0 )
46 throw exception::CommonException ( "Nonterminal symbol \"" + ext::to_string ( nonterminal ) + "\" is not present in grammar." );
47
49 Ni.push_back ( ext::set < NonterminalSymbolType > { nonterminal } );
50 unsigned i = 1;
51
52 auto rawRules = grammar::RawRules::getRawRules ( grammar );
54
55 while ( i <= grammar.getNonterminalAlphabet ( ).size ( ) ) {
56 Ni.push_back ( ext::set < NonterminalSymbolType > { } );
57
58 for ( const NonterminalSymbolType & lhs : Ni.at ( i - 1 ) )
59 if ( rawRules.find ( lhs ) != rawRules.end ( ) )
60 for ( const ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > > & rhs : rawRules.find ( lhs )->second )
62 if ( grammar.getTerminalAlphabet ( ).count ( rhsSymbol ) )
63 break;
64
65 Ni.at ( i ).insert ( rhsSymbol.template get < NonterminalSymbolType > ( ) );
66
67 if ( ! nullable.count ( rhsSymbol.template get < NonterminalSymbolType > ( ) ) )
68 break;
69 }
70
71 if ( Ni.at ( i ).count ( nonterminal ) )
72 return true;
73
74 i += 1;
75 }
76
77 return false;
78}
79
80} /* namespace properties */
81
82} /* namespace grammar */
83
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
Class extending the deque class from the standard library. Original reason is to allow printing of th...
Definition: deque.hpp:44
Definition: set.hpp:44
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
static ext::set< NonterminalSymbolType > getNullableNonterminals(const T &grammar)
Definition: NullableNonterminals.h:44
Definition: RecursiveNonterminal.h:24
static bool isNonterminalRecursive(const T &grammar, const NonterminalSymbolType &nonterminal)
Definition: RecursiveNonterminal.h:44
int i
Definition: AllEpsilonClosure.h:118
std::string to_string(const T &value)
To string method designated for objects that can be casted to string.
Definition: string.hpp:131
Definition: ToAutomaton.h:24