Skip to content
Snippets Groups Projects
Commit c5e564a3 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

redesign ranges

parent 87e22170
No related branches found
No related tags found
No related merge requests found
...@@ -91,7 +91,7 @@ automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automa ...@@ -91,7 +91,7 @@ automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automa
   
ext::vector < SymbolType > path { symbol }; ext::vector < SymbolType > path { symbol };
   
ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > transitions; ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > transitions;
// only 1 child and nonfinal // only 1 child and nonfinal
while((transitions = automaton.getTransitionsFromState(q)).size() == 1 && automaton.getFinalStates().count(q) == 0) { while((transitions = automaton.getTransitionsFromState(q)).size() == 1 && automaton.getFinalStates().count(q) == 0) {
const std::pair<ext::pair<StateType, SymbolType>, StateType>& transition = * transitions.begin(); const std::pair<ext::pair<StateType, SymbolType>, StateType>& transition = * transitions.begin();
......
...@@ -31,7 +31,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG < > originalGrammar ...@@ -31,7 +31,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG < > originalGrammar
automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar ); automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) { for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) {
LR0Items items = static_cast < const label::LR0ItemsLabel & > ( state . getData ( ) ) . getItems ( ); LR0Items items = static_cast < const label::LR0ItemsLabel & > ( state . getData ( ) ) . getItems ( );
ext::range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); ext::iterator_range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state );
ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) ); ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) );
for ( const LR0Items::value_type & nonterminalItems : items ) { for ( const LR0Items::value_type & nonterminalItems : items ) {
DefaultSymbolType leftHandSide = nonterminalItems.first; DefaultSymbolType leftHandSide = nonterminalItems.first;
...@@ -73,7 +73,7 @@ LRGotoTable SLR1ParseTable::getGotoTable ( grammar::CFG < > originalGrammar ) { ...@@ -73,7 +73,7 @@ LRGotoTable SLR1ParseTable::getGotoTable ( grammar::CFG < > originalGrammar ) {
grammar::CFG < > augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar ); grammar::CFG < > augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar );
automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar ); automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) { for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) {
ext::range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); ext::iterator_range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state );
ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) ); ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) );
for ( const DefaultSymbolType & nonterminal : augmentedGrammar.getNonterminalAlphabet ( ) ) { for ( const DefaultSymbolType & nonterminal : augmentedGrammar.getNonterminalAlphabet ( ) ) {
ext::map < ext::pair<DefaultStateType, DefaultSymbolType >, DefaultStateType >::iterator transitionIterator = transitionsFromCurrentState.find ( { state, nonterminal } ); ext::map < ext::pair<DefaultStateType, DefaultSymbolType >, DefaultStateType >::iterator transitionIterator = transitionsFromCurrentState.find ( { state, nonterminal } );
......
...@@ -338,7 +338,7 @@ public: ...@@ -338,7 +338,7 @@ public:
* *
* \returns a subset of the transition function of the automaton with the source state fixed * \returns a subset of the transition function of the automaton with the source state fixed
*/ */
ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState ( const StateType & from ) const; ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState ( const StateType & from ) const;
   
/** /**
* Get the transition function of the automaton, with the target state fixed in the transitions natural representation. * Get the transition function of the automaton, with the target state fixed in the transitions natural representation.
...@@ -481,14 +481,14 @@ public: ...@@ -481,14 +481,14 @@ public:
}; };
   
template<class SymbolType, class StateType > template<class SymbolType, class StateType >
ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const { ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const {
if ( !getStates ( ).count ( from ) ) if ( !getStates ( ).count ( from ) )
throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" ); throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" );
   
auto lower = transitions.lower_bound ( Compar < SymbolType, StateType > ( from ) ); auto lower = transitions.lower_bound ( Compar < SymbolType, StateType > ( from ) );
auto upper = transitions.upper_bound ( Compar < SymbolType, StateType > ( from ) ); auto upper = transitions.upper_bound ( Compar < SymbolType, StateType > ( from ) );
   
return ext::make_range ( lower, upper ); return ext::make_iterator_range ( lower, upper );
} }
   
template<class SymbolType, class StateType > template<class SymbolType, class StateType >
......
/* /*
* range.hpp as proposed http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html by Jeffrey Yasskin <jyasskin@google.com> * iterator_range.hpp as proposed http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html by Jeffrey Yasskin <jyasskin@google.com>
* *
* Created on: May 28, 2015 * Created on: May 28, 2015
* Author: Jan Travnicek * Author: Jan Travnicek
...@@ -9,18 +9,18 @@ ...@@ -9,18 +9,18 @@
#define __RANGE_HPP_ #define __RANGE_HPP_
   
#include <utility> #include <utility>
#include <iterator> #include "iterator.hpp"
   
namespace ext { namespace ext {
   
/** /**
* \brief * \brief
* Implementation of range, i.e. pair of iterators. The class provides most notably begin and end methods to allow the class be used in foreach context. * Implementation of iterator_range, i.e. pair of iterators. The class provides most notably begin and end methods to allow the class be used in foreach context.
* *
* \tparam Iterator the type of wrapped pair of iterators * \tparam Iterator the type of wrapped pair of iterators
*/ */
template<typename Iterator> template<typename Iterator>
class range { class iterator_range {
/** /**
* \brief * \brief
* The begin iterator * The begin iterator
...@@ -65,19 +65,19 @@ public: ...@@ -65,19 +65,19 @@ public:
   
/** /**
* \brief * \brief
* Constructor of empty range. Both iterators are initialized to default (same) value. * Constructor of empty iterator_range. Both iterators are initialized to default (same) value.
*/ */
range ( ) { iterator_range ( ) {
} }
   
/** /**
* \brief * \brief
* Constructor to make range from pair of iterators * Constructor to make iterator_range from pair of iterators
* *
* \param begin the begining of the wrapped range * \param begin the begining of the wrapped iterator_range
* \param end the end of the wrapped range * \param end the end of the wrapped iterator_range
*/ */
constexpr range(Iterator begin, Iterator end) : m_begin ( begin ), m_end ( end ) { constexpr iterator_range(Iterator begin, Iterator end) : m_begin ( begin ), m_end ( end ) {
} }
   
/** /**
...@@ -102,7 +102,7 @@ public: ...@@ -102,7 +102,7 @@ public:
   
/** /**
* \brief * \brief
* Getter of the first value in the range. * Getter of the first value in the iterator_range.
* *
* \return reference to the first value * \return reference to the first value
*/ */
...@@ -112,7 +112,7 @@ public: ...@@ -112,7 +112,7 @@ public:
   
/** /**
* \brief * \brief
* Getter of the last value in the range. * Getter of the last value in the iterator_range.
* *
* \return reference to the last value * \return reference to the last value
*/ */
...@@ -132,9 +132,9 @@ public: ...@@ -132,9 +132,9 @@ public:
   
/** /**
* \brief * \brief
* Test whether the range is empty. * Test whether the iterator_range is empty.
* *
* \return true of the two iterators representing range are equal. * \return true of the two iterators representing iterator_range are equal.
*/ */
constexpr bool empty() const { constexpr bool empty() const {
return m_begin == m_end; return m_begin == m_end;
...@@ -184,82 +184,94 @@ public: ...@@ -184,82 +184,94 @@ public:
   
/** /**
* \brief * \brief
* Creates two sub ranges based on middle position. The element at the middle position is included in the second range. * Creates two sub ranges based on middle position. The element at the middle position is included in the second iterator_range.
* *
* \param index the place where to cut the range in two * \param index the place where to cut the iterator_range in two
* *
* \return two subranges * \return two subranges
*/ */
std::pair< range, range > split(difference_type index) const { std::pair< iterator_range, iterator_range > split(difference_type index) const {
return std::make_pair ( slice ( 0, index ), slice ( index, 0 ) ); return std::make_pair ( slice ( 0, index ), slice ( index, 0 ) );
} }
   
/** /**
* \brief * \brief
* Creates a subrange of the range representing interaval of values from \p start to \p stop. * Creates a subrange of the iterator_range representing interaval of values from \p start to \p stop.
* *
* If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the range. * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the iterator_range.
* If the \p start is negative, the actual cut position is calculated relative to the end of the range. * If the \p start is negative, the actual cut position is calculated relative to the end of the iterator_range.
* *
* If the \p end is positive, the actual cut position is calcuated relative to the begining of the range. * If the \p end is positive, the actual cut position is calcuated relative to the begining of the iterator_range.
* If the \p start is negative or zero, the actual cut position is calculated relative to the end of the range. * If the \p start is negative or zero, the actual cut position is calculated relative to the end of the iterator_range.
* *
* Example range ( 0, 1, 2, 3, 4, 5 ).slice ( 1, 3 ) produces range ( 1, 2 ); * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( 1, 3 ) produces iterator_range ( 1, 2 );
* Example range ( 0, 1, 2, 3, 4, 5 ).slice ( -4, -1 ) produces range ( 2, 3, 4 ); * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( -4, -1 ) produces iterator_range ( 2, 3, 4 );
* *
* \param start the begin position of the resulting subrange * \param start the begin position of the resulting subrange
* \param end the end position of the resulting subrange * \param end the end position of the resulting subrange
* *
* \return subrange of the range. * \return subrange of the iterator_range.
*/ */
range slice(difference_type start, difference_type stop) const { iterator_range slice(difference_type start, difference_type stop) const {
return range ( ( start >= 0 ? m_begin : m_end ) + start, ( stop > 0 ? m_begin : m_end ) + stop ); return iterator_range ( ( start >= 0 ? m_begin : m_end ) + start, ( stop > 0 ? m_begin : m_end ) + stop );
} }
   
/** /**
* \brief * \brief
* Creates a subrange of the range representing interaval of values from \p start to the end of the range. * Creates a subrange of the iterator_range representing interaval of values from \p start to the end of the iterator_range.
* *
* If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the range. * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the iterator_range.
* If the \p start is negative, the actual cut position is calculated relative to the end of the range. * If the \p start is negative, the actual cut position is calculated relative to the end of the iterator_range.
* *
* The call is equivalent to slice ( begin, 0 ). * The call is equivalent to slice ( begin, 0 ).
* *
* Example range ( 0, 1, 2, 3, 4, 5 ).slice ( 1 ) produces range ( 1, 2, 3, 4, 5 ); * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( 1 ) produces iterator_range ( 1, 2, 3, 4, 5 );
* Example range ( 0, 1, 2, 3, 4, 5 ).slice ( -4 ) produces range ( 2, 3, 4, 5 ); * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( -4 ) produces iterator_range ( 2, 3, 4, 5 );
* *
* \param start the begin position of the resulting subrange * \param start the begin position of the resulting subrange
* *
* \return subrange of the range. * \return subrange of the iterator_range.
*/ */
range slice(difference_type start) const { iterator_range slice(difference_type start) const {
return slice ( start, 0 ); return slice ( start, 0 );
} }
}; };
   
/** /**
* \brief * \brief
* Helper to create range from two iterators. * Helper to create iterator_range from two iterators.
* *
* \return the range instance from two iterators * \return the iterator_range instance from two iterators
*/ */
template < typename Iter > template < typename Iter >
range < Iter > make_range ( Iter begin, Iter end ) { iterator_range < Iter > make_iterator_range ( Iter begin, Iter end ) {
return range < Iter > ( begin, end ); return iterator_range < Iter > ( begin, end );
} }
   
/** /**
* \brief * Generalization of range for universaly referenced containers.
* Helper to create range from two iterators. *
* \param cont the container to call end on
* *
* \return the range instance from two iterators * \result the range over all elements of the array
*/ */
template < typename Container > template <class Container>
auto make_range ( Container && container ) { auto range ( Container && cont ) -> decltype ( std::forward < Container > ( cont ).range ( ) ) {
return make_range ( std::forward < Container > ( container ).begin ( ), std::forward < Container > ( container ).end ( ) ); return ext::make_iterator_range ( std::forward < Container > ( cont ).begin ( ), std::forward < Container > ( cont ).end ( ) );
}
/**
* Specialization of range for static array.
*
* \param arr the static array
*
* \result the range over all elements of the array
*/
template < class T, size_t N >
constexpr ext::iterator_range < T * > range ( T ( & arr ) [ N ] ) noexcept {
return ext::make_iterator_range ( begin ( arr ), end ( arr ) );
} }
   
} /* namespace ext */ } /* namespace ext */
   
#endif /* __RANGE_HPP_ */ #endif /* __RANGE_HPP_ */
...@@ -15,15 +15,15 @@ void RangeTest::tearDown ( ) { ...@@ -15,15 +15,15 @@ void RangeTest::tearDown ( ) {
void RangeTest::constructorTest ( ) { void RangeTest::constructorTest ( ) {
int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
ext::range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) ); ext::iterator_range < int * > ra1 = ext::range ( arr );
   
ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
ext::range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) );
   
CPPUNIT_ASSERT ( ( std::equal ( ra1.begin ( ), ra1.end ( ), rv1.begin ( ), rv1.end ( ) ) ) ); CPPUNIT_ASSERT ( ( std::equal ( ra1.begin ( ), ra1.end ( ), rv1.begin ( ), rv1.end ( ) ) ) );
   
auto rv2 = ext::make_range ( v1 ); auto rv2 = ext::range ( v1 );
   
CPPUNIT_ASSERT ( ( std::equal ( rv1.begin ( ), rv1.end ( ), rv2.begin ( ), rv2.end ( ) ) ) ); CPPUNIT_ASSERT ( ( std::equal ( rv1.begin ( ), rv1.end ( ), rv2.begin ( ), rv2.end ( ) ) ) );
} }
...@@ -31,19 +31,19 @@ void RangeTest::constructorTest ( ) { ...@@ -31,19 +31,19 @@ void RangeTest::constructorTest ( ) {
void RangeTest::sizeTest ( ) { void RangeTest::sizeTest ( ) {
int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
ext::range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) ); ext::iterator_range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) );
   
CPPUNIT_ASSERT ( ra1.size ( ) == 10 ); CPPUNIT_ASSERT ( ra1.size ( ) == 10 );
   
ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
ext::range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) );
   
CPPUNIT_ASSERT ( rv1.size ( ) == 10 ); CPPUNIT_ASSERT ( rv1.size ( ) == 10 );
   
ext::list < int > l1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ext::list < int > l1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
ext::range < ext::list < int >::iterator > rl1 ( l1.begin ( ), l1.end ( ) ); ext::iterator_range < ext::list < int >::iterator > rl1 ( l1.begin ( ), l1.end ( ) );
   
CPPUNIT_ASSERT ( rl1.size ( ) == 10 ); CPPUNIT_ASSERT ( rl1.size ( ) == 10 );
} }
...@@ -51,15 +51,15 @@ void RangeTest::sizeTest ( ) { ...@@ -51,15 +51,15 @@ void RangeTest::sizeTest ( ) {
void RangeTest::splitTest ( ) { void RangeTest::splitTest ( ) {
ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
auto r1 = ext::make_range ( v1 ); auto r1 = ext::range ( v1 );
   
ext::vector < int > v2 = { 0, 1, 2 }; ext::vector < int > v2 = { 0, 1, 2 };
   
auto r2 = ext::make_range ( v2 ); auto r2 = ext::range ( v2 );
   
ext::vector < int > v3 = { 3, 4, 5, 6, 7, 8, 9 }; ext::vector < int > v3 = { 3, 4, 5, 6, 7, 8, 9 };
   
auto r3 = ext::make_range ( v3 ); auto r3 = ext::range ( v3 );
   
auto splitted = r1.split ( 3 ); auto splitted = r1.split ( 3 );
   
...@@ -70,11 +70,11 @@ void RangeTest::splitTest ( ) { ...@@ -70,11 +70,11 @@ void RangeTest::splitTest ( ) {
void RangeTest::sliceTest ( ) { void RangeTest::sliceTest ( ) {
ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
auto r1 = ext::make_range ( v1 ); auto r1 = ext::range ( v1 );
   
ext::vector < int > v2 = { 4, 5, 6 }; ext::vector < int > v2 = { 4, 5, 6 };
   
auto r2 = ext::make_range ( v2 ); auto r2 = ext::range ( v2 );
   
auto sliced = r1.slice ( 4, -3 ); auto sliced = r1.slice ( 4, -3 );
   
......
...@@ -156,7 +156,7 @@ void stringApi < automaton::DFA < SymbolType, StateType > >::compose ( std::ostr ...@@ -156,7 +156,7 @@ void stringApi < automaton::DFA < SymbolType, StateType > >::compose ( std::ostr
   
template < class SymbolType, class StateType > template < class SymbolType, class StateType >
void stringApi < automaton::DFA < SymbolType, StateType > >::composeTransitionsFromState(std::ostream& output, const automaton::DFA < SymbolType, StateType > & automaton, const StateType & from) { void stringApi < automaton::DFA < SymbolType, StateType > >::composeTransitionsFromState(std::ostream& output, const automaton::DFA < SymbolType, StateType > & automaton, const StateType & from) {
ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > symbolTransitionsFromState = automaton.getTransitionsFromState(from); ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > symbolTransitionsFromState = automaton.getTransitionsFromState(from);
   
for(const SymbolType& inputSymbol : automaton.getInputAlphabet()) { for(const SymbolType& inputSymbol : automaton.getInputAlphabet()) {
if ( ! symbolTransitionsFromState.empty ( ) && symbolTransitionsFromState.front ( ).first.second == inputSymbol ) { if ( ! symbolTransitionsFromState.empty ( ) && symbolTransitionsFromState.front ( ).first.second == inputSymbol ) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment