Track and iterate only over set range in GrammarSymbolSet

FIX: Iterate over all elements when combining sets
This commit is contained in:
Charles Baker 2023-06-02 21:33:29 +12:00 • committed by Charles Baker
parent b72f97e34d
commit b0a6fb6b24
3 changed files with 38 additions and 9 deletions

View file

@ -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) )
{

View file

@ -6,8 +6,13 @@
#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;
@ -15,17 +20,23 @@ 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())
{
}
@ -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;
}
@ -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;
@ -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;
}
}
@ -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];
@ -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_ );
}

View file

@ -12,6 +12,8 @@ class GrammarSymbol;
class GrammarSymbolSet
{
std::vector<size_t> set_;
size_t minimum_;
size_t maximum_;
public:
GrammarSymbolSet( size_t symbols );
@ -20,10 +22,11 @@ public:
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 );
};
}