mirror of
https://github.com/cwbaker/lalr.git
synced 2026-09-26 16:33:18 +03:00
Use a vector of active GrammarStates to track new states
The previous algorithm would loop through all states but only process those that didn't have their processed flag set. Much faster to only iterate through those states that haven't been processed.
This commit is contained in:
parent
ebe173cb12
commit
9d90804ae2
4 changed files with 30 additions and 58 deletions
|
|
@ -326,7 +326,7 @@ void GrammarGenerator::closure( const std::shared_ptr<GrammarState>& state )
|
|||
// @return
|
||||
// The goto state generated when accepting \e symbol from \e state.
|
||||
*/
|
||||
std::shared_ptr<GrammarState> GrammarGenerator::goto_( const std::shared_ptr<GrammarState>& state, const GrammarSymbol& symbol )
|
||||
std::shared_ptr<GrammarState> GrammarGenerator::goto_( const GrammarState* state, const GrammarSymbol& symbol )
|
||||
{
|
||||
LALR_ASSERT( state );
|
||||
|
||||
|
|
@ -853,38 +853,39 @@ void GrammarGenerator::generate_states( const GrammarSymbol* start_symbol, const
|
|||
closure( start_state );
|
||||
states_.insert( start_state );
|
||||
start_state_ = start_state.get();
|
||||
|
||||
int added = 1;
|
||||
{
|
||||
while ( added > 0 )
|
||||
{
|
||||
added = 0;
|
||||
for ( set<shared_ptr<GrammarState>, GrammarStateLess>::const_iterator i = states_.begin(); i != states_.end(); ++i )
|
||||
{
|
||||
const shared_ptr<GrammarState>& state = *i;
|
||||
LALR_ASSERT( state );
|
||||
|
||||
if ( !state->processed() )
|
||||
{
|
||||
vector<GrammarState*> next_states;
|
||||
vector<GrammarState*> states;
|
||||
states.push_back( start_state_ );
|
||||
|
||||
while ( !states.empty() )
|
||||
{
|
||||
for ( GrammarState* state : states )
|
||||
{
|
||||
for ( vector<unique_ptr<GrammarSymbol>>::const_iterator j = symbols.begin(); j != symbols.end(); ++j )
|
||||
{
|
||||
state->set_processed( true );
|
||||
for ( vector<unique_ptr<GrammarSymbol>>::const_iterator j = symbols.begin(); j != symbols.end(); ++j )
|
||||
GrammarSymbol* symbol = j->get();
|
||||
LALR_ASSERT( symbol );
|
||||
if ( symbol != end_symbol )
|
||||
{
|
||||
GrammarSymbol* symbol = j->get();
|
||||
LALR_ASSERT( symbol );
|
||||
if ( symbol != end_symbol )
|
||||
std::shared_ptr<GrammarState> goto_state = goto_( state, *symbol );
|
||||
if ( goto_state )
|
||||
{
|
||||
std::shared_ptr<GrammarState> goto_state = goto_( state, *symbol );
|
||||
if ( goto_state )
|
||||
LALR_ASSERT( !goto_state->items().empty() );
|
||||
std::shared_ptr<GrammarState> actual_goto_state = *states_.insert( goto_state ).first;
|
||||
if ( goto_state == actual_goto_state )
|
||||
{
|
||||
LALR_ASSERT( !goto_state->items().empty() );
|
||||
std::shared_ptr<GrammarState> actual_goto_state = *states_.insert( goto_state ).first;
|
||||
added += goto_state == actual_goto_state ? 1 : 0;
|
||||
state->add_shift_transition( shift_transition(symbol, actual_goto_state.get()) );
|
||||
next_states.push_back( goto_state.get() );
|
||||
}
|
||||
state->add_shift_transition( shift_transition(symbol, actual_goto_state.get()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states.clear();
|
||||
next_states.swap( states );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ private:
|
|||
GrammarTransition* reduce_transition( const GrammarSymbol* symbol, const GrammarProduction* production );
|
||||
GrammarSymbolSet spontaneous_lookaheads( const GrammarItem& item ) const;
|
||||
void closure( const std::shared_ptr<GrammarState>& state );
|
||||
std::shared_ptr<GrammarState> goto_( const std::shared_ptr<GrammarState>& state, const GrammarSymbol& symbol );
|
||||
std::shared_ptr<GrammarState> goto_( const GrammarState* state, const GrammarSymbol& symbol );
|
||||
void replace_references_to_symbol( GrammarSymbol* to_symbol, GrammarSymbol* with_symbol );
|
||||
void check_for_undefined_symbol_errors();
|
||||
void check_for_unreferenced_symbol_errors();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ GrammarState::GrammarState()
|
|||
: items_()
|
||||
, transitions_by_symbol_index_()
|
||||
, transitions_()
|
||||
, processed_( false )
|
||||
, index_( INVALID_INDEX )
|
||||
{
|
||||
}
|
||||
|
|
@ -31,13 +30,11 @@ GrammarState::GrammarState( GrammarState&& state )
|
|||
: items_()
|
||||
, transitions_by_symbol_index_()
|
||||
, transitions_()
|
||||
, processed_( false )
|
||||
, index_( INVALID_INDEX )
|
||||
{
|
||||
std::swap( items_, state.items_ );
|
||||
std::swap( transitions_by_symbol_index_, state.transitions_by_symbol_index_ );
|
||||
std::swap( transitions_, state.transitions_ );
|
||||
std::swap( processed_, state.processed_ );
|
||||
std::swap( index_, state.index_ );
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +42,6 @@ GrammarState::GrammarState( const GrammarState& state )
|
|||
: items_( state.items_ )
|
||||
, transitions_by_symbol_index_( state.transitions_by_symbol_index_ )
|
||||
, transitions_( state.transitions_ )
|
||||
, processed_( state.processed_ )
|
||||
, index_( state.index_ )
|
||||
{
|
||||
}
|
||||
|
|
@ -76,10 +72,10 @@ GrammarItem* GrammarState::find_item( GrammarProduction* production, int positio
|
|||
// @return
|
||||
// The items.
|
||||
*/
|
||||
// const std::set<GrammarItem>& GrammarState::items() const
|
||||
// {
|
||||
// return items_;
|
||||
// }
|
||||
const std::set<GrammarItem>& GrammarState::items() const
|
||||
{
|
||||
return items_;
|
||||
}
|
||||
|
||||
/**
|
||||
// Find a transition on \e symbol from this state.
|
||||
|
|
@ -127,17 +123,6 @@ int GrammarState::count_valid_transitions() const
|
|||
return valid_transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
// Has this state been processed?
|
||||
//
|
||||
// @return
|
||||
// True if this state has been processed otherwise false.
|
||||
*/
|
||||
bool GrammarState::processed() const
|
||||
{
|
||||
return processed_;
|
||||
}
|
||||
|
||||
/**
|
||||
// Get the index of this state.
|
||||
//
|
||||
|
|
@ -247,17 +232,6 @@ GrammarTransition* GrammarState::find_transition_by_symbol( const GrammarSymbol*
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
// Set this state as having been processed.
|
||||
//
|
||||
// @param processed
|
||||
// True to mark this state as processed or false to mark it as not processed.
|
||||
*/
|
||||
void GrammarState::set_processed( bool processed )
|
||||
{
|
||||
processed_ = processed;
|
||||
}
|
||||
|
||||
/**
|
||||
// Set the index of this state.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ class GrammarState
|
|||
std::set<GrammarItem> items_; ///< The items that define the positions within the grammar that this state represents.
|
||||
std::vector<GrammarTransition*> transitions_by_symbol_index_; ///< Transitions from this state by symbol index.
|
||||
std::vector<GrammarTransition*> transitions_; ///< Transitions from this state.
|
||||
bool processed_; ///< True if this state has been processed during state machine generation otherwise false.
|
||||
int index_; ///< The index of this state.
|
||||
|
||||
public:
|
||||
|
|
@ -30,12 +29,11 @@ public:
|
|||
GrammarState( const GrammarState& state );
|
||||
|
||||
GrammarItem* find_item( GrammarProduction* production, int position ) const;
|
||||
const std::set<GrammarItem>& items() const { return items_; }
|
||||
const std::set<GrammarItem>& items() const;
|
||||
const GrammarTransition* find_transition_by_symbol( const GrammarSymbol* symbol ) const;
|
||||
const std::vector<GrammarTransition*>& transitions() const;
|
||||
int count_valid_transitions() const;
|
||||
std::string label() const;
|
||||
bool processed() const;
|
||||
int index() const;
|
||||
bool operator<( const GrammarState& state ) const;
|
||||
|
||||
|
|
@ -43,7 +41,6 @@ public:
|
|||
void add_shift_transition( GrammarTransition* transition );
|
||||
void add_reduce_transition( GrammarTransition* transition );
|
||||
GrammarTransition* find_transition_by_symbol( const GrammarSymbol* symbol );
|
||||
void set_processed( bool processed );
|
||||
void set_index( int index );
|
||||
|
||||
static const int INVALID_INDEX = -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue