Skip to content

Commit

Permalink
Track and iterate only over set range in GrammarSymbolSet
Browse files Browse the repository at this point in the history
FIX: Iterate over all elements when combining sets
  • Loading branch information
Charles Baker authored and cwbaker committed Jun 2, 2023
1 parent b72f97e commit b0a6fb6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
4 changes: 3 additions & 1 deletion src/lalr/GrammarGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,9 @@ void GrammarGenerator::generate_reduce_transitions()
if ( item->position() >= production->length() )
{
const GrammarSymbolSet& lookaheads = lookaheads_[item->index()].lookaheads();
for ( int index = 0; index < int(symbols_.size()); ++index )
int start = lookaheads.minimum_index();
int finish = lookaheads.maximum_index();
for ( int index = start; index < finish; ++index )
{
if ( lookaheads.contains(index) )
{
Expand Down
38 changes: 31 additions & 7 deletions src/lalr/GrammarSymbolSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,37 @@
#include "GrammarSymbolSet.hpp"
#include "GrammarSymbol.hpp"
#include "assert.hpp"
#include <algorithm>
#include <limits>

using std::min;
using std::max;
using std::vector;
using std::numeric_limits;
using namespace lalr;

static const size_t ONE = 1;
static const size_t BITS_PER_ELEMENT = sizeof(size_t) * 8;

GrammarSymbolSet::GrammarSymbolSet( size_t symbols )
: set_()
, minimum_(numeric_limits<size_t>::max())
, maximum_(numeric_limits<size_t>::min())
{
set_.resize( symbols / BITS_PER_ELEMENT );
}

GrammarSymbolSet::GrammarSymbolSet( GrammarSymbolSet&& set )
: set_( std::move(set.set_) )
, minimum_(numeric_limits<size_t>::max())
, maximum_(numeric_limits<size_t>::min())
{
}

GrammarSymbolSet::GrammarSymbolSet( const GrammarSymbolSet& set )
: set_( set.set_ )
, minimum_(numeric_limits<size_t>::max())
, maximum_(numeric_limits<size_t>::min())
{
}

Expand All @@ -34,6 +45,8 @@ GrammarSymbolSet& GrammarSymbolSet::operator=( GrammarSymbolSet&& set )
if ( this != &set )
{
std::swap( set_, set.set_ );
std::swap( minimum_, set.minimum_ );
std::swap( maximum_, set.maximum_ );
}
return *this;
}
Expand All @@ -43,14 +56,26 @@ GrammarSymbolSet& GrammarSymbolSet::operator=( const GrammarSymbolSet& set )
if ( this != &set )
{
set_ = set.set_;
minimum_ = set.minimum_;
maximum_ = set.maximum_;
}
return *this;
}

int GrammarSymbolSet::minimum_index() const
{
return int(minimum_ * BITS_PER_ELEMENT);
}

int GrammarSymbolSet::maximum_index() const
{
return int((maximum_ + 1) * BITS_PER_ELEMENT);
}

bool GrammarSymbolSet::contains( int symbol_index ) const
{
size_t index = symbol_index / BITS_PER_ELEMENT;
if ( index < set_.size() )
if ( index >= minimum_ && index <= maximum_ )
{
size_t mask = ONE << (symbol_index % BITS_PER_ELEMENT);
return (set_[index] & mask) != 0;
Expand All @@ -71,6 +96,8 @@ bool GrammarSymbolSet::insert( const GrammarSymbol* symbol )
if ( !(set_[index] & mask) )
{
set_[index] |= mask;
minimum_ = min( minimum_, index );
maximum_ = max( maximum_, index );
return true;
}
}
Expand All @@ -85,7 +112,7 @@ int GrammarSymbolSet::insert( const GrammarSymbolSet& set )
}

int added = 0;
for ( size_t i = 0; i < set.set_.size(); ++i )
for ( size_t i = set.minimum_; i < set.maximum_ + 1; ++i )
{
size_t mask = set_[i];
size_t new_mask = mask | set.set_[i];
Expand All @@ -95,10 +122,7 @@ int GrammarSymbolSet::insert( const GrammarSymbolSet& set )
++added;
}
}
minimum_ = min( minimum_, set.minimum_ );
maximum_ = min( maximum_, set.maximum_ );
return added;
}

void GrammarSymbolSet::swap( GrammarSymbolSet&& set )
{
std::swap( set_, set.set_ );
}
5 changes: 4 additions & 1 deletion src/lalr/GrammarSymbolSet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class GrammarSymbol;
class GrammarSymbolSet
{
std::vector<size_t> set_;
size_t minimum_;
size_t maximum_;

public:
GrammarSymbolSet( size_t symbols );
Expand All @@ -20,10 +22,11 @@ class GrammarSymbolSet
GrammarSymbolSet& operator=( GrammarSymbolSet&& set );
GrammarSymbolSet& operator=( const GrammarSymbolSet& set );

int minimum_index() const;
int maximum_index() const;
bool contains( int symbol_index ) const;
bool insert( const GrammarSymbol* symbol );
int insert( const GrammarSymbolSet& set );
void swap( GrammarSymbolSet&& set );
};

}

0 comments on commit b0a6fb6

Please sign in to comment.