27#include <ext/algorithm>
32#include <alib/variant>
46class TerminalAlphabet;
47class NonterminalAlphabet;
69template <
class TerminalSymbolType = DefaultSymbolType,
class NonterminalSymbolType = DefaultSymbolType >
70class LeftRG final :
public core::Components < LeftRG < TerminalSymbolType, NonterminalSymbolType >, ext::set < TerminalSymbolType >, component::Set, TerminalAlphabet, ext::set < NonterminalSymbolType >, component::Set, NonterminalAlphabet, NonterminalSymbolType, component::Value, InitialSymbol > {
79 bool generatesEpsilon;
87 explicit LeftRG ( NonterminalSymbolType initialSymbol );
152 bool removeRule (
const NonterminalSymbolType & leftHandSide,
const TerminalSymbolType & rightHandSide );
170 return this->
template accessComponent < InitialSymbol > ( ).get ( );
179 return std::move ( this->
template accessComponent < InitialSymbol > ( ).
get ( ) );
190 return this->
template accessComponent < InitialSymbol > ( ).set ( std::move ( symbol ) );
199 return this->
template accessComponent < NonterminalAlphabet > ( ).get ( );
208 return std::move ( this->
template accessComponent < NonterminalAlphabet > ( ).
get ( ) );
219 return this->
template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) );
228 this->
template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) );
237 return this->
template accessComponent < TerminalAlphabet > ( ).get ( );
246 return std::move ( this->
template accessComponent < TerminalAlphabet > ( ).
get ( ) );
257 return this->
template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) );
266 this->
template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) );
314 return out <<
"(LeftRG"
318 <<
" rules = " << instance.
getRules ( )
324template <
class TerminalSymbolType,
class NonterminalSymbolType >
328template <
class TerminalSymbolType,
class NonterminalSymbolType >
329LeftRG < TerminalSymbolType, NonterminalSymbolType >::LeftRG (
ext::set < NonterminalSymbolType > nonterminalAlphabet,
ext::set < TerminalSymbolType > terminalAlphabet, NonterminalSymbolType initialSymbol ) :
core::Components <
LeftRG,
ext::set < TerminalSymbolType >, component::Set, TerminalAlphabet,
ext::set < NonterminalSymbolType >, component::Set, NonterminalAlphabet, NonterminalSymbolType, component::Value, InitialSymbol > ( std::move ( terminalAlphabet), std::move ( nonterminalAlphabet ), std::move ( initialSymbol ) ), generatesEpsilon (
false ) {
332template <
class TerminalSymbolType,
class NonterminalSymbolType >
334 if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
337 if ( rightHandSide.template is < TerminalSymbolType > ( ) ) {
338 const TerminalSymbolType & rhs = rightHandSide.template get < TerminalSymbolType > ( );
340 if ( !getTerminalAlphabet ( ).count ( rhs ) )
345 if ( !getNonterminalAlphabet ( ).count ( rhs.first ) || !getTerminalAlphabet ( ).count ( rhs.second ) )
346 throw GrammarException (
"Rule must rewrite to terminal symbol followed by nonterminal symbol" );
349 return rules [ std::move ( leftHandSide ) ].insert ( std::move ( rightHandSide ) ).second;
352template <
class TerminalSymbolType,
class NonterminalSymbolType >
354 if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
358 if ( element.template is < NonterminalSymbolType > ( ) ) {
359 const TerminalSymbolType & rhs = element.template get < TerminalSymbolType > ( );
361 if ( ! getTerminalAlphabet ( ).count ( rhs ) )
367 if ( ! getNonterminalAlphabet ( ).count ( rhs.first ) || ! getTerminalAlphabet ( ).count ( rhs.second ) )
368 throw GrammarException (
"Rule must rewrite to terminal symbol followed by nonterminal symbol" );
375template <
class TerminalSymbolType,
class NonterminalSymbolType >
380template <
class TerminalSymbolType,
class NonterminalSymbolType >
382 return std::move ( rules );
385template <
class TerminalSymbolType,
class NonterminalSymbolType >
387 return rules[leftHandSide].erase ( rightHandSide );
390template <
class TerminalSymbolType,
class NonterminalSymbolType >
394 return removeRule ( leftHandSide, rhs );
397template <
class TerminalSymbolType,
class NonterminalSymbolType >
401 return removeRule ( leftHandSide, rhs );
404template <
class TerminalSymbolType,
class NonterminalSymbolType >
406 generatesEpsilon = genEps;
409template <
class TerminalSymbolType,
class NonterminalSymbolType >
411 return generatesEpsilon;
424template <
class TerminalSymbolType,
class NonterminalSymbolType >
425class SetConstraint<
grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, TerminalSymbolType, grammar::TerminalAlphabet > {
465 if (
grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count (
ext::poly_comp ( symbol ) ) )
476template <
class TerminalSymbolType,
class NonterminalSymbolType >
477class SetConstraint<
grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::NonterminalAlphabet > {
489 if ( rule.first == symbol )
498 return grammar.template accessComponent < grammar::InitialSymbol > ( ).get ( ) == symbol;
522 if (
grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count (
ext::poly_comp ( symbol ) ) )
533template <
class TerminalSymbolType,
class NonterminalSymbolType >
534class ElementConstraint<
grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::InitialSymbol > {
545 return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol );
563template <
class TerminalSymbolType,
class NonterminalSymbolType >
570 grammar::LeftRG < > res ( std::move ( nonterminals ), std::move ( terminals ), std::move ( initialSymbol ) );
580 res.addRules ( std::move ( lhs ), std::move ( rhs ) );
583 res.setGeneratesEpsilon ( value.getGeneratesEpsilon ( ) );
static ext::set< DefaultSymbolType > normalizeAlphabet(ext::set< SymbolType > &&symbols)
Definition: SymbolNormalize.h:50
static DefaultSymbolType normalizeSymbol(SymbolType &&symbol)
Definition: SymbolNormalize.h:68
Definition: components.hpp:181
static void valid(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &, const NonterminalSymbolType &)
Definition: LeftRG.h:554
static bool available(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar, const NonterminalSymbolType &symbol)
Definition: LeftRG.h:544
Definition: components.hpp:25
static bool used(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar, const NonterminalSymbolType &symbol)
Definition: LeftRG.h:487
static void valid(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar, const NonterminalSymbolType &symbol)
Definition: LeftRG.h:521
static bool available(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &, const NonterminalSymbolType &)
Definition: LeftRG.h:509
static void valid(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar, const TerminalSymbolType &symbol)
Definition: LeftRG.h:464
static bool used(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar, const TerminalSymbolType &symbol)
Definition: LeftRG.h:435
static bool available(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &, const TerminalSymbolType &)
Definition: LeftRG.h:452
Definition: setComponents.hpp:26
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Implementation of the variant class allowing to store any type of those listed in the template parame...
Definition: variant.hpp:98
Definition: GrammarException.h:15
static ext::pair< DefaultSymbolType, ext::vector< DefaultSymbolType > > normalizeRHS(ext::pair< FirstSymbolType, ext::vector< SecondSymbolType > > &&symbol)
Definition: GrammarNormalize.h:40
Left regular grammar in Chomsky hierarchy or type 3 in Chomsky hierarchy. Generates regular languages...
Definition: LeftRG.h:70
bool setInitialSymbol(NonterminalSymbolType symbol)
Definition: LeftRG.h:189
const ext::set< TerminalSymbolType > & getTerminalAlphabet() const &
Definition: LeftRG.h:236
ext::set< TerminalSymbolType > && getTerminalAlphabet() &&
Definition: LeftRG.h:245
void setNonterminalAlphabet(ext::set< NonterminalSymbolType > symbols)
Definition: LeftRG.h:227
friend ext::ostream & operator<<(ext::ostream &out, const LeftRG &instance)
Definition: LeftRG.h:313
ext::set< NonterminalSymbolType > && getNonterminalAlphabet() &&
Definition: LeftRG.h:207
auto operator<=>(const LeftRG &other) const
Definition: LeftRG.h:290
const ext::map< NonterminalSymbolType, ext::set< ext::variant< TerminalSymbolType, ext::pair< NonterminalSymbolType, TerminalSymbolType > > > > & getRules() const &
Definition: LeftRG.h:376
LeftRG(NonterminalSymbolType initialSymbol)
Creates a new instance of Left regular grammar with a concrete initial symbol.
Definition: LeftRG.h:325
bool getGeneratesEpsilon() const
Definition: LeftRG.h:410
NonterminalSymbolType && getInitialSymbol() &&
Definition: LeftRG.h:178
void setTerminalAlphabet(ext::set< TerminalSymbolType > symbols)
Definition: LeftRG.h:265
const NonterminalSymbolType & getInitialSymbol() const &
Definition: LeftRG.h:169
bool operator==(const LeftRG &other) const
Definition: LeftRG.h:301
bool addTerminalSymbol(TerminalSymbolType symbol)
Definition: LeftRG.h:256
bool removeRule(const NonterminalSymbolType &leftHandSide, const ext::variant< TerminalSymbolType, ext::pair< NonterminalSymbolType, TerminalSymbolType > > &rightHandSide)
Definition: LeftRG.h:386
void setGeneratesEpsilon(bool genEps)
Definition: LeftRG.h:405
bool addNonterminalSymbol(NonterminalSymbolType symbol)
Definition: LeftRG.h:218
const ext::set< NonterminalSymbolType > & getNonterminalAlphabet() const &
Definition: LeftRG.h:198
void addRules(NonterminalSymbolType leftHandSide, ext::set< ext::variant< TerminalSymbolType, ext::pair< NonterminalSymbolType, TerminalSymbolType > > > rightHandSide)
Add new rules of a grammar.
Definition: LeftRG.h:353
bool addRule(NonterminalSymbolType leftHandSide, ext::variant< TerminalSymbolType, ext::pair< NonterminalSymbolType, TerminalSymbolType > > rightHandSide)
Add a new rule of a grammar.
Definition: LeftRG.h:333
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
reference_mover< T > make_mover(T ¶m)
Move adaptor construction function specialized to lvalue reference parameter.
Definition: iterator.hpp:468
std::string to_string(const T &value)
To string method designated for objects that can be casted to string.
Definition: string.hpp:131
PolyComp< T > poly_comp(const T &inst)
Definition: functional.hpp:60
auto begin(Container &&cont) -> decltype(std::forward(cont).begin())
Definition: iterator.hpp:900
Definition: ToAutomaton.h:24
void end()
Definition: measurements.cpp:19
auto & get(ext::ptr_array< Type, N > &tpl)
Specialisation of get function for pointer arrays.
Definition: ptr_array.hpp:693
static grammar::LeftRG< > eval(grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &&value)
Definition: LeftRG.h:565
Definition: normalize.hpp:13