From b0a6fb6b2414dde90f7bf10e2e30afab78bf567a Mon Sep 17 00:00:00 2001 From: Charles Baker Date: Fri, 2 Jun 2023 21:33:29 +1200 Subject: [PATCH] Track and iterate only over set range in GrammarSymbolSet FIX: Iterate over all elements when combining sets --- src/lalr/GrammarGenerator.cpp | 4 +++- src/lalr/GrammarSymbolSet.cpp | 38 ++++++++++++++++++++++++++++------- src/lalr/GrammarSymbolSet.hpp | 5 ++++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/lalr/GrammarGenerator.cpp b/src/lalr/GrammarGenerator.cpp index 9e64370..b730ade 100644 --- a/src/lalr/GrammarGenerator.cpp +++ b/src/lalr/GrammarGenerator.cpp @@ -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) ) { diff --git a/src/lalr/GrammarSymbolSet.cpp b/src/lalr/GrammarSymbolSet.cpp index 90e83bf..d4a4cc3 100644 --- a/src/lalr/GrammarSymbolSet.cpp +++ b/src/lalr/GrammarSymbolSet.cpp @@ -6,8 +6,13 @@ #include "GrammarSymbolSet.hpp" #include "GrammarSymbol.hpp" #include "assert.hpp" +#include +#include +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::max()) +, maximum_(numeric_limits::min()) { set_.resize( symbols / BITS_PER_ELEMENT ); } GrammarSymbolSet::GrammarSymbolSet( GrammarSymbolSet&& set ) : set_( std::move(set.set_) ) +, minimum_(numeric_limits::max()) +, maximum_(numeric_limits::min()) { } GrammarSymbolSet::GrammarSymbolSet( const GrammarSymbolSet& set ) : set_( set.set_ ) +, minimum_(numeric_limits::max()) +, maximum_(numeric_limits::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_ ); -} diff --git a/src/lalr/GrammarSymbolSet.hpp b/src/lalr/GrammarSymbolSet.hpp index 098dc0d..03f2b48 100644 --- a/src/lalr/GrammarSymbolSet.hpp +++ b/src/lalr/GrammarSymbolSet.hpp @@ -12,6 +12,8 @@ class GrammarSymbol; class GrammarSymbolSet { std::vector 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 ); }; }