diff --git a/src/lalr/GrammarGenerator.cpp b/src/lalr/GrammarGenerator.cpp index 69256f6..9e64370 100644 --- a/src/lalr/GrammarGenerator.cpp +++ b/src/lalr/GrammarGenerator.cpp @@ -150,18 +150,19 @@ std::string GrammarGenerator::label_item( const GrammarItem& item ) const LALR_ASSERT( item.index() >= 0 && item.index() < int(lookaheads_.size()) ); const GrammarSymbolSet& lookaheads = lookaheads_[item.index()].lookaheads(); - if ( !lookaheads.empty() ) + const char* delimiter = " {"; + for ( int i = 0; i < int(symbols_.size()); ++i ) { - const char* delimiter = " {"; - for ( const GrammarSymbol* lookahead : lookaheads ) + if ( lookaheads.contains(i) ) { - LALR_ASSERT( lookahead ); + const GrammarSymbol* symbol = symbols_[i].get(); + LALR_ASSERT( symbol ); label += delimiter; delimiter = ", "; - label += lookahead->lexeme(); + label += symbol->lexeme(); } - label += "}"; } + label += "}"; return label; } @@ -255,7 +256,7 @@ GrammarTransition* GrammarGenerator::reduce_transition( const GrammarSymbol* sym */ GrammarSymbolSet GrammarGenerator::spontaneous_lookaheads( const GrammarItem& item ) const { - GrammarSymbolSet lookaheads; + GrammarSymbolSet lookaheads(symbols_.size()); const GrammarProduction* production = productions_[item.production()].get(); LALR_ASSERT( production ); @@ -703,20 +704,21 @@ void GrammarGenerator::calculate_reachable_productions_for_symbol( const Grammar */ void GrammarGenerator::generate_spontaneous_lookaheads() { - lookaheads_.clear(); + const size_t symbols = symbols_.size(); + lookaheads_.clear(); for ( const shared_ptr& state : states_ ) { for ( const GrammarItem& item : state->items() ) { int index = int(lookaheads_.size()); item.set_index( index ); - lookaheads_.emplace_back( const_cast(&item) ); + lookaheads_.emplace_back( const_cast(&item), symbols ); ++index; } } { - GrammarSymbolSet lookaheads; + GrammarSymbolSet lookaheads{ symbols }; lookaheads.insert( end_symbol_ ); GrammarItem* start_item = start_state_->find_item( start_symbol_->productions().front(), 0 ); LALR_ASSERT( start_item ); @@ -946,7 +948,7 @@ void GrammarGenerator::generate_reduce_transitions() { GrammarState* state = i->get(); LALR_ASSERT( state ); - + for ( set::const_iterator item = state->items().begin(); item != state->items().end(); ++item ) { const GrammarProduction* production = productions_[item->production()].get(); @@ -954,11 +956,14 @@ void GrammarGenerator::generate_reduce_transitions() if ( item->position() >= production->length() ) { const GrammarSymbolSet& lookaheads = lookaheads_[item->index()].lookaheads(); - for ( vector::const_iterator j = lookaheads.begin(); j != lookaheads.end(); ++j ) + for ( int index = 0; index < int(symbols_.size()); ++index ) { - const GrammarSymbol* symbol = *j; - LALR_ASSERT( symbol ); - generate_reduce_transition( state, symbol, production ); + if ( lookaheads.contains(index) ) + { + const GrammarSymbol* symbol = symbols_[index].get(); + LALR_ASSERT( symbol ); + generate_reduce_transition( state, symbol, production ); + } } } } diff --git a/src/lalr/GrammarLookahead.cpp b/src/lalr/GrammarLookahead.cpp index 02113a8..500dd13 100644 --- a/src/lalr/GrammarLookahead.cpp +++ b/src/lalr/GrammarLookahead.cpp @@ -6,26 +6,24 @@ #include "GrammarLookahead.hpp" #include "GrammarItem.hpp" #include "assert.hpp" +#include using std::vector; using namespace lalr; -GrammarLookahead::GrammarLookahead( GrammarItem* item ) +GrammarLookahead::GrammarLookahead( GrammarItem* item, size_t symbols ) : item_( item ) , propagate_to_() -, lookaheads_{} +, lookaheads_{ symbols } { LALR_ASSERT( item_ ); } GrammarLookahead::GrammarLookahead( GrammarLookahead&& item ) -: item_( nullptr ) -, propagate_to_() -, lookaheads_() +: item_{ std::exchange(item.item_, nullptr) } +, propagate_to_{ std::move(item.propagate_to_) } +, lookaheads_{ std::move(item.lookaheads_) } { - std::swap( item_, item.item_ ); - std::swap( propagate_to_, item.propagate_to_ ); - std::swap( lookaheads_, item.lookaheads_ ); } GrammarItem* GrammarLookahead::item() const diff --git a/src/lalr/GrammarLookahead.hpp b/src/lalr/GrammarLookahead.hpp index 89082c8..d67f3f2 100644 --- a/src/lalr/GrammarLookahead.hpp +++ b/src/lalr/GrammarLookahead.hpp @@ -15,7 +15,7 @@ class GrammarLookahead GrammarSymbolSet lookaheads_; public: - GrammarLookahead( GrammarItem* item ); + GrammarLookahead( GrammarItem* item, size_t symbols ); GrammarLookahead( GrammarLookahead&& item ); GrammarItem* item() const; diff --git a/src/lalr/GrammarSymbol.cpp b/src/lalr/GrammarSymbol.cpp index 689cba8..52efc8d 100644 --- a/src/lalr/GrammarSymbol.cpp +++ b/src/lalr/GrammarSymbol.cpp @@ -25,8 +25,8 @@ GrammarSymbol::GrammarSymbol( const std::string& lexeme ) , index_( -1 ) , nullable_( false ) , referenced_in_precedence_directive_( false ) -, first_() -, follow_() +, first_{0} +, follow_{0} , productions_() { } diff --git a/src/lalr/GrammarSymbolSet.cpp b/src/lalr/GrammarSymbolSet.cpp index ac4992f..78d32bc 100644 --- a/src/lalr/GrammarSymbolSet.cpp +++ b/src/lalr/GrammarSymbolSet.cpp @@ -10,23 +10,19 @@ using std::vector; using namespace lalr; -GrammarSymbolSet::GrammarSymbolSet() +GrammarSymbolSet::GrammarSymbolSet( size_t symbols ) : set_() -, symbols_() { + set_.resize( symbols / 8 ); } GrammarSymbolSet::GrammarSymbolSet( GrammarSymbolSet&& set ) -: set_() -, symbols_() +: set_( std::move(set.set_) ) { - std::swap( set_, set.set_ ); - std::swap( symbols_, set.symbols_ ); } GrammarSymbolSet::GrammarSymbolSet( const GrammarSymbolSet& set ) : set_( set.set_ ) -, symbols_( set.symbols_ ) { } @@ -35,7 +31,6 @@ GrammarSymbolSet& GrammarSymbolSet::operator=( GrammarSymbolSet&& set ) if ( this != &set ) { std::swap( set_, set.set_ ); - std::swap( symbols_, set.symbols_ ); } return *this; } @@ -45,34 +40,19 @@ GrammarSymbolSet& GrammarSymbolSet::operator=( const GrammarSymbolSet& set ) if ( this != &set ) { set_ = set.set_; - symbols_ = set.symbols_; } return *this; } -size_t GrammarSymbolSet::empty() const +bool GrammarSymbolSet::contains( int symbol_index ) const { - return symbols_.empty(); -} - -size_t GrammarSymbolSet::size() const -{ - return symbols_.size(); -} - -std::vector::const_iterator GrammarSymbolSet::begin() const -{ - return symbols_.begin(); -} - -std::vector::const_iterator GrammarSymbolSet::end() const -{ - return symbols_.end(); -} - -const std::vector& GrammarSymbolSet::symbols() const -{ - return symbols_; + size_t index = symbol_index / 8; + if ( index < set_.size() ) + { + unsigned char mask = 1 << (symbol_index % 8); + return (set_[index] & mask) != 0; + } + return false; } bool GrammarSymbolSet::insert( const GrammarSymbol* symbol ) @@ -88,7 +68,7 @@ bool GrammarSymbolSet::insert( const GrammarSymbol* symbol ) if ( !(set_[index] & mask) ) { set_[index] |= mask; - symbols_.push_back( symbol ); + // symbols_.push_back( symbol ); return true; } } @@ -97,12 +77,21 @@ bool GrammarSymbolSet::insert( const GrammarSymbol* symbol ) int GrammarSymbolSet::insert( const GrammarSymbolSet& set ) { - int added = 0; - const vector& symbols = set.symbols_; - for ( const GrammarSymbol* symbol : symbols ) + if ( set_.size() < set.set_.size() ) { - LALR_ASSERT( symbol ); - added += insert( symbol ) ? 1 : 0; + set_.insert( set_.end(), set.set_.size() - set_.size(), 0 ); + } + + int added = 0; + for ( size_t i = 0; i < set.set_.size(); ++i ) + { + unsigned char mask = set_[i]; + unsigned char new_mask = mask | set.set_[i]; + if ( mask != new_mask ) + { + set_[i] = new_mask; + ++added; + } } return added; } @@ -110,5 +99,4 @@ int GrammarSymbolSet::insert( const GrammarSymbolSet& set ) void GrammarSymbolSet::swap( GrammarSymbolSet&& set ) { std::swap( set_, set.set_ ); - std::swap( symbols_, set.symbols_ ); } diff --git a/src/lalr/GrammarSymbolSet.hpp b/src/lalr/GrammarSymbolSet.hpp index 732a371..fd9444e 100644 --- a/src/lalr/GrammarSymbolSet.hpp +++ b/src/lalr/GrammarSymbolSet.hpp @@ -12,20 +12,15 @@ class GrammarSymbol; class GrammarSymbolSet { std::vector set_; - std::vector symbols_; public: - GrammarSymbolSet(); + GrammarSymbolSet( size_t symbols ); GrammarSymbolSet( GrammarSymbolSet&& set ); GrammarSymbolSet( const GrammarSymbolSet& set ); GrammarSymbolSet& operator=( GrammarSymbolSet&& set ); GrammarSymbolSet& operator=( const GrammarSymbolSet& set ); - size_t empty() const; - size_t size() const; - std::vector::const_iterator begin() const; - std::vector::const_iterator end() const; - const std::vector& symbols() const; + bool contains( int symbol_index ) const; bool insert( const GrammarSymbol* symbol ); int insert( const GrammarSymbolSet& set ); void swap( GrammarSymbolSet&& set );