Reduce memory usage by removing vector from GrammarSymbolSet

This commit is contained in:
Charles Baker 2023-05-28 15:07:25 +12:00 • committed by Charles Baker
parent c9a6a297bf
commit c7eea3b698
6 changed files with 57 additions and 71 deletions

View file

@ -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<GrammarState>& state : states_ )
{
for ( const GrammarItem& item : state->items() )
{
int index = int(lookaheads_.size());
item.set_index( index );
lookaheads_.emplace_back( const_cast<GrammarItem*>(&item) );
lookaheads_.emplace_back( const_cast<GrammarItem*>(&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<GrammarItem>::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 GrammarSymbol*>::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 );
}
}
}
}

View file

@ -6,26 +6,24 @@
#include "GrammarLookahead.hpp"
#include "GrammarItem.hpp"
#include "assert.hpp"
#include <utility>
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

View file

@ -15,7 +15,7 @@ class GrammarLookahead
GrammarSymbolSet lookaheads_;
public:
GrammarLookahead( GrammarItem* item );
GrammarLookahead( GrammarItem* item, size_t symbols );
GrammarLookahead( GrammarLookahead&& item );
GrammarItem* item() const;

View file

@ -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_()
{
}

View file

@ -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 GrammarSymbol*>::const_iterator GrammarSymbolSet::begin() const
{
return symbols_.begin();
}
std::vector<const GrammarSymbol*>::const_iterator GrammarSymbolSet::end() const
{
return symbols_.end();
}
const std::vector<const GrammarSymbol*>& 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<const GrammarSymbol*>& 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_ );
}

View file

@ -12,20 +12,15 @@ class GrammarSymbol;
class GrammarSymbolSet
{
std::vector<unsigned char> set_;
std::vector<const GrammarSymbol*> 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 GrammarSymbol*>::const_iterator begin() const;
std::vector<const GrammarSymbol*>::const_iterator end() const;
const std::vector<const GrammarSymbol*>& symbols() const;
bool contains( int symbol_index ) const;
bool insert( const GrammarSymbol* symbol );
int insert( const GrammarSymbolSet& set );
void swap( GrammarSymbolSet&& set );