/** // Recursively calculate nullable for this node. */ void RegexNode::calculate_nullable() { for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i ) { RegexNode* node = i->get(); SWEET_ASSERT( node ); node->calculate_nullable(); } switch ( type_ ) { case LEXER_NODE_NULL: nullable_ = true; break; case LEXER_NODE_CAT: SWEET_ASSERT( nodes_.size() == 2 ); nullable_ = nodes_[0]->is_nullable() && nodes_[1]->is_nullable(); break; case LEXER_NODE_OR: SWEET_ASSERT( nodes_.size() == 2 ); nullable_ = nodes_[0]->is_nullable() || nodes_[1]->is_nullable(); break; case LEXER_NODE_STAR: case LEXER_NODE_OPTIONAL: nullable_ = true; break; case LEXER_NODE_PLUS: SWEET_ASSERT( nodes_.size() == 1 ); nullable_ = nodes_[0]->is_nullable(); break; case LEXER_NODE_SYMBOL: nullable_ = begin_character_ == INVALID_BEGIN_CHARACTER && end_character_ == INVALID_END_CHARACTER; break; case LEXER_NODE_ACTION: nullable_ = false; break; default: SWEET_ASSERT( false ); nullable_ = false; break; } }
/** // Recursively calculate the last positions at this node. */ void RegexNode::calculate_last_positions() { for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i ) { RegexNode* node = i->get(); SWEET_ASSERT( node ); node->calculate_last_positions(); } switch ( type_ ) { case LEXER_NODE_NULL: break; case LEXER_NODE_CAT: { SWEET_ASSERT( nodes_.size() == 2 ); last_positions_.insert( nodes_[1]->last_positions_.begin(), nodes_[1]->last_positions_.end() ); if ( nodes_[1]->is_nullable() ) { last_positions_.insert( nodes_[0]->last_positions_.begin(), nodes_[0]->last_positions_.end() ); } break; } case LEXER_NODE_OR: SWEET_ASSERT( nodes_.size() == 2 ); last_positions_.insert( nodes_[0]->last_positions_.begin(), nodes_[0]->last_positions_.end() ); last_positions_.insert( nodes_[1]->last_positions_.begin(), nodes_[1]->last_positions_.end() ); break; case LEXER_NODE_STAR: case LEXER_NODE_PLUS: case LEXER_NODE_OPTIONAL: SWEET_ASSERT( nodes_.size() == 1 ); last_positions_.insert( nodes_[0]->last_positions_.begin(), nodes_[0]->last_positions_.end() ); break; case LEXER_NODE_SYMBOL: case LEXER_NODE_ACTION: last_positions_.insert( this ); break; default: SWEET_ASSERT( false ); break; } }
/** // Print the RegexNodes \e nodes. // // @param nodes // The RegexNodes to print. // // @param level // The recursion level to use when identing lines. */ void RegexSyntaxTree::print_nodes( const vector<std::shared_ptr<RegexNode> >& nodes, int level ) const { for ( vector<std::shared_ptr<RegexNode> >::const_iterator i = nodes.begin(); i != nodes.end(); ++i ) { static const char* LEXER_NODE_TYPES [LEXER_NODE_COUNT] = { "LEXER_NODE_NULL", "LEXER_NODE_CAT", "LEXER_NODE_OR", "LEXER_NODE_STAR", "LEXER_NODE_PLUS", "LEXER_NODE_OPTIONAL", "LEXER_NODE_SYMBOL", "LEXER_NODE_ACTION" }; RegexNode* node = i->get(); LALR_ASSERT( node != NULL ); for ( int i = 0; i < level; ++i ) { printf( " " ); } printf( "%d, %s, %s, [%d, %d), nullable=%s", node->get_index(), LEXER_NODE_TYPES[node->get_type()], node->get_lexeme(), node->get_begin_character(), node->get_end_character(), node->is_nullable() ? "true" : "false" ); printf( ", first={" ); print_positions( node->get_first_positions() ); printf( "}, last={" ); print_positions( node->get_last_positions() ); printf( "}, follow={" ); print_positions( node->get_follow_positions() ); printf( "}\n" ); if ( !node->get_nodes().empty() ) { print_nodes( node->get_nodes(), level + 1 ); } } }
/** // Recursively calculate the follow positions at this node. */ void RegexNode::calculate_follow_positions() { for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i ) { RegexNode* node = i->get(); SWEET_ASSERT( node ); node->calculate_follow_positions(); } switch ( type_ ) { case LEXER_NODE_NULL: break; case LEXER_NODE_CAT: { SWEET_ASSERT( nodes_.size() == 2 ); const std::set<RegexNode*, RegexNodeLess>& last_positions = nodes_[0]->last_positions_; const std::set<RegexNode*, RegexNodeLess>& first_positions = nodes_[1]->first_positions_; for ( std::set<RegexNode*, RegexNodeLess>::const_iterator i = last_positions.begin(); i != last_positions.end(); ++i ) { RegexNode* node = *i; SWEET_ASSERT( node ); if ( node->get_type() == LEXER_NODE_SYMBOL || node->get_type() == LEXER_NODE_ACTION ) { node->follow_positions_.insert( first_positions.begin(), first_positions.end() ); } } break; } case LEXER_NODE_STAR: case LEXER_NODE_PLUS: { SWEET_ASSERT( nodes_.size() == 1 ); const std::set<RegexNode*, RegexNodeLess>& last_positions = last_positions_; const std::set<RegexNode*, RegexNodeLess>& first_positions = first_positions_; for ( std::set<RegexNode*, RegexNodeLess>::const_iterator i = last_positions.begin(); i != last_positions.end(); ++i ) { RegexNode* node = *i; SWEET_ASSERT( node ); if ( node->get_type() == LEXER_NODE_SYMBOL || node->get_type() == LEXER_NODE_ACTION ) { node->follow_positions_.insert( first_positions.begin(), first_positions.end() ); } } break; } case LEXER_NODE_OR: case LEXER_NODE_OPTIONAL: case LEXER_NODE_SYMBOL: case LEXER_NODE_ACTION: break; default: SWEET_ASSERT( false ); break; } }