diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h index d34f59db1d55854b962e09a454928b56cae17cd6..6e39409400dd98b8dbbe854350e64008cd68fa84 100644 --- a/alib2data/src/grammar/Regular/LeftLG.h +++ b/alib2data/src/grammar/Regular/LeftLG.h @@ -1,6 +1,22 @@ /* * LeftLG.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Nov 17, 2013 * Author: Jan Travnicek */ @@ -28,105 +44,331 @@ namespace grammar { -/** - * Left linear grammar in chomsky normal form. Type 3 in Chomsky hierarchy. Produces regular languages. - */ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; +/** + * \brief + * Left linear grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy. Generates regular languages. + + * \details + * Definition is similar to all common definitions of 'relaxed' regular grammars. + * G = (N, T, P, S), + * N (NonterminalAlphabet) = nonempty finite set of nonterminal symbols, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let grammar do much though, + * P = set of production rules of the form A -> aB or A -> a, where A, B \in N and a \in T*, + * S (InitialSymbol) = initial nonterminal symbol, + * + * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + */ template < class SymbolType > class LeftLG final : public GrammarBase, public std::Components < LeftLG < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { + /** + * Rules as mapping from nonterminal symbol on the left hand side to set of either sequence of terminal symbols or doublets of sequence of terminal symbols and nonterminal symbol. + */ std::map < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > > rules; public: + /** + * \brief Creates a new instance of Left linear grammar with a concrete initial symbol. + * + * \param initialSymbol the initial symbol of the grammar + */ explicit LeftLG ( SymbolType initialSymbol ); + /** + * \brief Creates a new instance of Left linear grammar with a concrete nonterminal, terminal alphabet and initial symbol. + * + * \param nonTerminalSymbols the initial nonterminal alphabet + * \param terminalSymbols the initial terminal alphabet + * \param initialSymbol the initial symbol of the grammar + */ explicit LeftLG ( std::set < SymbolType > nonTerminalSymbols, std::set < SymbolType > terminalSymbols, SymbolType initialSymbol ); - virtual GrammarBase * clone ( ) const; - - virtual GrammarBase * plunder ( ) &&; - + /** + * @copydoc grammar::GrammarBase::clone() + */ + virtual GrammarBase * clone ( ) const override; + + /** + * @copydoc grammar::GrammarBase::plunder() + */ + virtual GrammarBase * plunder ( ) && override; + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> aB or A -> a, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > rightHandSide ); + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> a, where A \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ); + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> aB, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::pair < SymbolType, std::vector < SymbolType > > rightHandSide ); + /** + * \brief Add new rules of a grammar. + * + * \details The rules are in form of A -> aB | bC | ... | a | b | ..., where A, B, C ... \in N and a, b ... \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide a set of right hand sides of the rule + */ void addRules ( SymbolType leftHandSide, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > rightHandSide ); + /** + * Get rules of the grammar. + * + * \returns rules of the grammar + */ const std::map < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > > & getRules ( ) const; + /** + * Remove a rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > & rightHandSide ); + + /** + * Remove a rule of a grammar in form of A -> a, where A \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide ); + + /** + * Remove a rule of a grammar in form of A -> aB, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::pair < SymbolType, std::vector < SymbolType > > & rightHandSide ); + /** + * Add a new rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRawRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ); + /** + * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. + * + * \returns rules of the grammar + */ std::map < SymbolType, std::set < std::vector < SymbolType > > > getRawRules ( ) const; + /** + * Remove a rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRawRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide ); + /** + * Getter of initial symbol. + * + * \returns the initial symbol of the grammar + */ const SymbolType & getInitialSymbol ( ) const { return this->template accessElement < InitialSymbol > ( ).get ( ); } + /** + * Setter of initial symbol. + * + * \param symbol new initial symbol of the grammar + * + * \returns true of the initial symbol was indeed changed + */ bool setInitialSymbol ( SymbolType symbol ) { return this->template accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) ); } + /** + * Getter of nonterminal alphabet. + * + * \returns the nonterminal alphabet of the grammar + */ const std::set < SymbolType > & getNonterminalAlphabet ( ) const { return this->template accessComponent < NonterminalAlphabet > ( ).get ( ); } + /** + * Adder of nonterminal symbol. + * + * \param symbol the new symbol to be added to nonterminal alphabet + * + * \returns true if the symbol was indeed added + */ bool addNonterminalSymbol ( SymbolType symbol ) { return this->template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Setter of nonterminal alphabet. + * + * \param symbols completely new nonterminal alphabet + */ void setNonterminalAlphabet ( std::set < SymbolType > symbols ) { this->template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Getter of terminal alphabet. + * + * \returns the terminal alphabet of the grammar + */ const std::set < SymbolType > & getTerminalAlphabet ( ) const { return this->template accessComponent < TerminalAlphabet > ( ).get ( ); } + /** + * Adder of terminal symbol. + * + * \param symbol the new symbol tuo be added to nonterminal alphabet + * + * \returns true if the symbol was indeed added + */ bool addTerminalSymbol ( SymbolType symbol ) { return this->template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Setter of terminal alphabet. + * + * \param symbol completely new nontemrinal alphabet + */ void setTerminalAlphabet ( std::set < SymbolType > symbols ) { this->template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) ); } - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return std::type_index ( typeid ( * this ) ) - std::type_index ( typeid ( other ) ); } - virtual int compare ( const LeftLG & other ) const; - - virtual void operator >>( std::ostream & os ) const; - - virtual explicit operator std::string ( ) const; - + /** + * Actual compare method + * + * \param other the other instance + * + * \returns actual relation between two by type same grammar instances + */ + int compare ( const LeftLG & other ) const; + + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; + + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "LeftLG"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the grammar + */ static LeftLG parse ( std::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual rules of the grammar from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params grammar the grammar to add the rule to + */ static void parseRule ( std::deque < sax::Token >::iterator & input, LeftLG & grammar ); - void compose ( std::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out sink for new xml tokens representing the grammar + */ + void compose ( std::deque < sax::Token > & out ) const override; + + /** + * Helper for composing rules of the grammar to a sequence of xml tokens. + * + * \param out sink for xml tokens representing the rules of the grammar + */ void composeRules ( std::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized grammar. + */ typedef LeftLG < > normalized_type; - virtual GrammarBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols. + * + * \returns new instance of the grammar with default template parameters or unmodified instance if the template parameters were already default ones + */ + virtual GrammarBase * normalize ( ) && override { if ( typeid ( LeftLG < > ) == typeid ( LeftLG < SymbolType > ) ) return this; @@ -389,9 +631,22 @@ alib::ObjectBase* LeftLG < SymbolType >::inc() && { namespace std { +/** + * Helper class specifying constraints for the grammar's internal terminal alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the grammar. + */ template < class SymbolType > class ComponentConstraint< grammar::LeftLG < SymbolType >, SymbolType, grammar::TerminalAlphabet > { public: + /** + * Returns true if the terminal symbol is still used in some rule of the grammar. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const grammar::LeftLG < SymbolType > & grammar, const SymbolType & symbol ) { for ( const std::pair < const SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > > & rule : grammar.getRules ( ) ) { for ( const std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > & rhsTmp : rule.second ) @@ -412,19 +667,45 @@ public: return false; } + /** + * Returns true as all terminal symbols are possibly available to be terminal symbols. + * + * \returns true + */ static bool available ( const grammar::LeftLG < SymbolType > &, const SymbolType & ) { return true; } + /** + * Throws runtime exception if the symbol requested to be terminal symbol is already in nonterminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet + */ static void valid ( const grammar::LeftLG < SymbolType > & grammar, const SymbolType & symbol ) { if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); } }; +/** + * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. + * + * \tparam SymbolType used for the nonterminal alphabet of the grammar. + */ template < class SymbolType > class ComponentConstraint< grammar::LeftLG < SymbolType >, SymbolType, grammar::NonterminalAlphabet > { public: + /** + * Returns true if the nonterminal symbol is still used in some rule of the grammar or if it is the initial symbol of the grammar. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const grammar::LeftLG < SymbolType > & grammar, const SymbolType & symbol ) { for ( const std::pair < const SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > > & rule : grammar.getRules ( ) ) { if ( rule.first == symbol ) @@ -446,23 +727,52 @@ public: return false; } + /** + * Returns true as all terminal symbols are possibly available to be nonterminal symbols. + * + * \returns true + */ static bool available ( const grammar::LeftLG < SymbolType > &, const SymbolType & ) { return true; } + /** + * Throws runtime exception if the symbol requested to be nonterminal symbol is already in terminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet + */ static void valid ( const grammar::LeftLG < SymbolType > & grammar, const SymbolType & symbol ) { if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); } }; +/** + * Helper class specifying constraints for the grammar's internal initial symbol component. + * + * \tparam SymbolType used for the initial symbol of the grammar. + */ template < class SymbolType > class ElementConstraint< grammar::LeftLG < SymbolType >, SymbolType, grammar::InitialSymbol > { public: + /** + * Returns true if the symbol requested to be initial is available in nonterminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the tested symbol is in nonterminal alphabet + */ static bool available ( const grammar::LeftLG < SymbolType > & grammar, const SymbolType & symbol ) { return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); } + /** + * All symbols are valid as initial symbols. + */ static void valid ( const grammar::LeftLG < SymbolType > &, const SymbolType & ) { } }; diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h index ccf501d5e67163022abd1a7f5b8802a1973983b7..ac2f6712ee8ae2ce02afc562d5d722587fd25fab 100644 --- a/alib2data/src/grammar/Regular/LeftRG.h +++ b/alib2data/src/grammar/Regular/LeftRG.h @@ -69,7 +69,7 @@ class InitialSymbol; template < class SymbolType > class LeftRG final : public GrammarBase, public std::Components < LeftRG < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { /** - * Transition function as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of terminal symbol and nonterminal symbol. + * Rules as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of terminal symbol and nonterminal symbol. */ std::map < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > rules; @@ -80,14 +80,14 @@ class LeftRG final : public GrammarBase, public std::Components < LeftRG < Symbo public: /** - * \brief Creates a new instance of Left regular grammar with concrete initial symbol. + * \brief Creates a new instance of Left regular grammar with a concrete initial symbol. * * \param initialSymbol the initial symbol of the grammar */ explicit LeftRG ( SymbolType initialSymbol ); /** - * \brief Creates a new instance of Left regular grammar with concrete nonterminal, terminal alphabet and initial symbol. + * \brief Creates a new instance of Left regular grammar with a concrete nonterminal, terminal alphabet and initial symbol. * * \param nonTerminalSymbols the initial nonterminal alphabet * \param terminalSymbols the initial terminal alphabet @@ -305,7 +305,7 @@ public: bool getGeneratesEpsilon ( ) const; /** - * @copydoc alib::CommonBase<ObjectBase>::normalize() + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) */ virtual int compare ( const ObjectBase & other ) const override { if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); @@ -382,7 +382,7 @@ public: virtual alib::ObjectBase * inc ( ) && override; /** - * Type of normalized type. + * Type of normalized grammar. */ typedef LeftRG < > normalized_type; @@ -683,7 +683,7 @@ namespace std { /** * Helper class specifying constraints for the grammar's internal terminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the terminal alphabet of the grammar. */ template < class SymbolType > class ComponentConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::TerminalAlphabet > { @@ -731,7 +731,7 @@ public: /** * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the nonterminal alphabet of the grammar. */ template < class SymbolType > class ComponentConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::NonterminalAlphabet > { @@ -762,7 +762,7 @@ public: } /** - * Returns true as all terminal symbols are possibly available to be terminal symbols. +- * Returns true as all terminal symbols are possibly available to be nonterminal symbols. * * \returns true */ @@ -787,7 +787,7 @@ public: /** * Helper class specifying constraints for the grammar's internal initial symbol component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the initial symbol of the grammar. */ template < class SymbolType > class ElementConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::InitialSymbol > { diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h index 9dd71dc52e790d6cb854d0717576b52c60aa965b..a6dcb8dbae37769cff918493ee542543e0c90a15 100644 --- a/alib2data/src/grammar/Regular/RightLG.h +++ b/alib2data/src/grammar/Regular/RightLG.h @@ -1,6 +1,22 @@ /* * RightLG.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Nov 17, 2013 * Author: Jan Travnicek */ @@ -28,105 +44,331 @@ namespace grammar { -/** - * Right linear grammar in chomsky normal form. Type 3 in Chomsky hierarchy. Produces regular languages. - */ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; +/** + * \brief + * Right linear grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy. Generates regular languages. + + * \details + * Definition is similar to all common definitions of 'relaxed' regular grammars. + * G = (N, T, P, S), + * N (NonterminalAlphabet) = nonempty finite set of nonterminal symbols, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let grammar do much though, + * P = set of production rules of the form A -> Ba or A -> a, where A, B \in N and a \in T*, + * S (InitialSymbol) = initial nonterminal symbol, + * + * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + */ template < class SymbolType > class RightLG final : public GrammarBase, public std::Components < RightLG < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { + /** + * Rules as mapping from nonterminal symbol on the left hand side to set of either sequence of terminal symbols or doublets of sequence of nonterminal symbol and terminal symbols. + */ std::map < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > > rules; public: + /** + * \brief Creates a new instance of Right linear grammar with a concrete initial symbol. + * + * \param initialSymbol the initial symbol of the grammar + */ explicit RightLG ( SymbolType initialSymbol ); + /** + * \brief Creates a new instance of Right linear grammar with a concrete nonterminal, terminal alphabet and initial symbol. + * + * \param nonTerminalSymbols the initial nonterminal alphabet + * \param terminalSymbols the initial terminal alphabet + * \param initialSymbol the initial symbol of the grammar + */ explicit RightLG ( std::set < SymbolType > nonTerminalSymbols, std::set < SymbolType > terminalSymbols, SymbolType initialSymbol ); - virtual GrammarBase * clone ( ) const; - - virtual GrammarBase * plunder ( ) &&; - + /** + * @copydoc grammar::GrammarBase::clone() + */ + virtual GrammarBase * clone ( ) const override; + + /** + * @copydoc grammar::GrammarBase::plunder() + */ + virtual GrammarBase * plunder ( ) && override; + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> Ba or A -> a, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > rightHandSide ); + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> a, where A \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ); + + /** + * \brief Add a new rule of a grammar. + * + * \details The rule is in a form of A -> Ba, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRule ( SymbolType leftHandSide, std::pair < std::vector < SymbolType >, SymbolType > rightHandSide ); + /** + * \brief Add new rules of a grammar. + * + * \details The rules are in form of A -> Ba | Cb | ... | a | b | ..., where A, B, C ... \in N and a, b ... \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide a set of right hand sides of the rule + */ void addRules ( SymbolType leftHandSide, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > rightHandSide ); + /** + * Get rules of the grammar. + * + * \returns rules of the grammar + */ const std::map < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > > & getRules ( ) const; + /** + * Remove a rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > & rightHandSide ); + + /** + * Remove a rule of a grammar in form of A -> a, where A \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide ); + + /** + * Remove a rule of a grammar in form of A -> Ba, where A, B \in N and a \in T*. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRule ( const SymbolType & leftHandSide, const std::pair < std::vector < SymbolType >, SymbolType > & rightHandSide ); + /** + * Add a new rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. + * + * \param leftHandSide the left hand side of the rule + * \param rightHandSide the right hand side of the rule + * + * \returns true if the rule was indeed added, false othervise + */ bool addRawRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ); + /** + * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. + * + * \returns rules of the grammar + */ std::map < SymbolType, std::set < std::vector < SymbolType > > > getRawRules ( ) const; + /** + * Remove a rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide + * + * \returns true if the rule was indeed removed, false othervise + */ bool removeRawRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide ); + /** + * Getter of initial symbol. + * + * \returns the initial symbol of the grammar + */ const SymbolType & getInitialSymbol ( ) const { return this->template accessElement < InitialSymbol > ( ).get ( ); } + /** + * Setter of initial symbol. + * + * \param symbol new initial symbol of the grammar + * + * \returns true of the initial symbol was indeed changed + */ bool setInitialSymbol ( SymbolType symbol ) { return this->template accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) ); } + /** + * Getter of nonterminal alphabet. + * + * \returns the nonterminal alphabet of the grammar + */ const std::set < SymbolType > & getNonterminalAlphabet ( ) const { return this->template accessComponent < NonterminalAlphabet > ( ).get ( ); } + /** + * Adder of nonterminal symbol. + * + * \param symbol the new symbol to be added to nonterminal alphabet + * + * \returns true if the symbol was indeed added + */ bool addNonterminalSymbol ( SymbolType symbol ) { return this->template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Setter of nonterminal alphabet. + * + * \param symbols completely new nonterminal alphabet + */ void setNonterminalAlphabet ( std::set < SymbolType > symbols ) { this->template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Getter of terminal alphabet. + * + * \returns the terminal alphabet of the grammar + */ const std::set < SymbolType > & getTerminalAlphabet ( ) const { return this->template accessComponent < TerminalAlphabet > ( ).get ( ); } + /** + * Adder of terminal symbol. + * + * \param symbol the new symbol tuo be added to nonterminal alphabet + * + * \returns true if the symbol was indeed added + */ bool addTerminalSymbol ( SymbolType symbol ) { return this->template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Setter of terminal alphabet. + * + * \param symbol completely new nontemrinal alphabet + */ void setTerminalAlphabet ( std::set < SymbolType > symbols ) { this->template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) ); } - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return std::type_index ( typeid ( * this ) ) - std::type_index ( typeid ( other ) ); } - virtual int compare ( const RightLG & other ) const; - - virtual void operator >>( std::ostream & os ) const; - - virtual explicit operator std::string ( ) const; - + /** + * Actual compare method + * + * \param other the other instance + * + * \returns actual relation between two by type same grammar instances + */ + int compare ( const RightLG & other ) const; + + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; + + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "RightLG"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the grammar + */ static RightLG parse ( std::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual rules of the grammar from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params grammar the grammar to add the rule to + */ static void parseRule ( std::deque < sax::Token >::iterator & input, RightLG & grammar ); - void compose ( std::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out sink for new xml tokens representing the grammar + */ + void compose ( std::deque < sax::Token > & out ) const override; + + /** + * Helper for composing rules of the grammar to a sequence of xml tokens. + * + * \param out sink for xml tokens representing the rules of the grammar + */ void composeRules ( std::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized grammar. + */ typedef RightLG < > normalized_type; - virtual GrammarBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols. + * + * \returns new instance of the grammar with default template parameters or unmodified instance if the template parameters were already default ones + */ + virtual GrammarBase * normalize ( ) && override { if ( typeid ( RightLG < > ) == typeid ( RightLG < SymbolType > ) ) return this; @@ -386,9 +628,22 @@ alib::ObjectBase* RightLG < SymbolType >::inc() && { namespace std { +/** + * Helper class specifying constraints for the grammar's internal terminal alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the grammar. + */ template < class SymbolType > class ComponentConstraint< grammar::RightLG < SymbolType >, SymbolType, grammar::TerminalAlphabet > { public: + /** + * Returns true if the terminal symbol is still used in some rule of the grammar. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const grammar::RightLG < SymbolType > & grammar, const SymbolType & symbol ) { for ( const std::pair < const SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > > & rule : grammar.getRules ( ) ) { for ( const std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > & rhsTmp : rule.second ) @@ -409,19 +664,45 @@ public: return false; } + /** + * Returns true as all terminal symbols are possibly available to be terminal symbols. + * + * \returns true + */ static bool available ( const grammar::RightLG < SymbolType > &, const SymbolType & ) { return true; } + /** + * Throws runtime exception if the symbol requested to be terminal symbol is already in nonterminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet + */ static void valid ( const grammar::RightLG < SymbolType > & grammar, const SymbolType & symbol ) { if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); } }; +/** + * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. + * + * \tparam SymbolType used for the nonterminal alphabet of the grammar. + */ template < class SymbolType > class ComponentConstraint< grammar::RightLG < SymbolType >, SymbolType, grammar::NonterminalAlphabet > { public: + /** + * Returns true if the nonterminal symbol is still used in some rule of the grammar or if it is the initial symbol of the grammar. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const grammar::RightLG < SymbolType > & grammar, const SymbolType & symbol ) { for ( const std::pair < const SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > > & rule : grammar.getRules ( ) ) { if ( rule.first == symbol ) @@ -443,23 +724,52 @@ public: return false; } + /** + * Returns true as all terminal symbols are possibly available to be nonterminal symbols. + * + * \returns true + */ static bool available ( const grammar::RightLG < SymbolType > &, const SymbolType & ) { return true; } + /** + * Throws runtime exception if the symbol requested to be nonterminal symbol is already in terminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet + */ static void valid ( const grammar::RightLG < SymbolType > & grammar, const SymbolType & symbol ) { if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); } }; +/** + * Helper class specifying constraints for the grammar's internal initial symbol component. + * + * \tparam SymbolType used for the initial symbol of the grammar. + */ template < class SymbolType > class ElementConstraint< grammar::RightLG < SymbolType >, SymbolType, grammar::InitialSymbol > { public: + /** + * Returns true if the symbol requested to be initial is available in nonterminal alphabet. + * + * \param grammar the tested grammar + * \param symbol the tested symbol + * + * \returns true if the tested symbol is in nonterminal alphabet + */ static bool available ( const grammar::RightLG < SymbolType > & grammar, const SymbolType & symbol ) { return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); } + /** + * All symbols are valid as initial symbols. + */ static void valid ( const grammar::RightLG < SymbolType > &, const SymbolType & ) { } }; diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h index 06f3540ae72acd75ac1dda5e75bb4141402492d6..3dae1b25e4eefced3cbd09e16655d6e1b331ed6c 100644 --- a/alib2data/src/grammar/Regular/RightRG.h +++ b/alib2data/src/grammar/Regular/RightRG.h @@ -69,7 +69,7 @@ class InitialSymbol; template < class SymbolType > class RightRG final : public GrammarBase, public std::Components < RightRG < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { /** - * Transition function as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of nonterminal symbol and terminal symbol. + * Rules function as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of nonterminal symbol and terminal symbol. */ std::map < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > rules; @@ -80,14 +80,14 @@ class RightRG final : public GrammarBase, public std::Components < RightRG < Sym public: /** - * \brief Creates a new instance of Right regular grammar with concrete initial symbol. + * \brief Creates a new instance of Right regular grammar with a concrete initial symbol. * * \param initialSymbol the initial symbol of the grammar */ explicit RightRG ( SymbolType initialSymbol ); /** - * \brief Creates a new instance of Right regular grammar with concrete nonterminal, terminal alphabet and initial symbol. + * \brief Creates a new instance of Right regular grammar with a concrete nonterminal, terminal alphabet and initial symbol. * * \param nonTerminalSymbols the initial nonterminal alphabet * \param terminalSymbols the initial terminal alphabet @@ -305,7 +305,7 @@ public: bool getGeneratesEpsilon ( ) const; /** - * @copydoc alib::CommonBase<ObjectBase>::normalize() + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) */ virtual int compare ( const ObjectBase & other ) const override { if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); @@ -382,7 +382,7 @@ public: virtual alib::ObjectBase * inc ( ) && override; /** - * Type of normalized type. + * Type of normalized grammar. */ typedef RightRG < > normalized_type; @@ -680,7 +680,7 @@ namespace std { /** * Helper class specifying constraints for the grammar's internal terminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the terminal alphabet of the grammar. */ template < class SymbolType > class ComponentConstraint< grammar::RightRG < SymbolType >, SymbolType, grammar::TerminalAlphabet > { @@ -728,7 +728,7 @@ public: /** * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the nonterminal alphabet of the grammar. */ template < class SymbolType > class ComponentConstraint< grammar::RightRG < SymbolType >, SymbolType, grammar::NonterminalAlphabet > { @@ -759,7 +759,7 @@ public: } /** - * Returns true as all terminal symbols are possibly available to be terminal symbols. + * Returns true as all terminal symbols are possibly available to be nonterminal symbols. * * \returns true */ @@ -784,7 +784,7 @@ public: /** * Helper class specifying constraints for the grammar's internal initial symbol component. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam SymbolType used for the initial symbol of the grammar. */ template < class SymbolType > class ElementConstraint< grammar::RightRG < SymbolType >, SymbolType, grammar::InitialSymbol > {