SyntaxTree - Location field

This commit is contained in:
Emmanuel BENOîT 2018-03-31 22:38:26 +02:00
parent b659f2f237
commit 6f52668540
3 changed files with 95 additions and 57 deletions

View file

@ -23,13 +23,16 @@ namespace ebcl {
template< template<
// Node type (should be an enum) // Node type (should be an enum)
typename NodeType , typename NodeType ,
// Location type
typename LocationType ,
// Data storage size // Data storage size
size_t InPlaceSize = sizeof( void* ) size_t InPlaceSize = sizeof( void* )
> class T_SyntaxTree > class T_SyntaxTree
{ {
public: public:
using E_Node = NodeType; using E_Node = NodeType;
using T_Self = T_SyntaxTree< NodeType , InPlaceSize >; using T_Location = LocationType;
using T_Self = T_SyntaxTree< NodeType , LocationType , InPlaceSize >;
static constexpr size_t StorageSize static constexpr size_t StorageSize
= T_VariantExt< InPlaceSize >::StorageSize; = T_VariantExt< InPlaceSize >::StorageSize;
@ -59,6 +62,8 @@ template<
E_Node type; E_Node type;
// Index of the parent node // Index of the parent node
uint32_t parent; uint32_t parent;
// Location of the node
T_Location location;
// Indices of the node's children // Indices of the node's children
T_AutoArray< uint32_t , 8 > children; T_AutoArray< uint32_t , 8 > children;
// Extra data storage // Extra data storage
@ -113,6 +118,9 @@ template<
template< typename D > template< typename D >
D const& dataOf( uint32_t node ) const; D const& dataOf( uint32_t node ) const;
// Access a node's location
T_Location const& locationOf( uint32_t node ) const noexcept;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Add a new child, return its index // Add a new child, return its index
@ -128,6 +136,9 @@ template<
template< typename D > template< typename D >
D& dataOf( uint32_t node ); D& dataOf( uint32_t node );
// Access a node's location
T_Location& locationOf( uint32_t node ) noexcept;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Return a visitor suitable for this syntax tree // Return a visitor suitable for this syntax tree
@ -137,8 +148,9 @@ template<
T_Node root( ) const noexcept; T_Node root( ) const noexcept;
}; };
template< typename T , size_t S > template< typename T , typename L , size_t S >
void swap( T_SyntaxTree< T , S >& lhs , T_SyntaxTree< T , S >& rhs ) noexcept; void swap( T_SyntaxTree< T , L , S >& lhs ,
T_SyntaxTree< T , L , S >& rhs ) noexcept;
} }

View file

@ -10,8 +10,8 @@ namespace ebcl {
/*= T_SyntaxTree =============================================================*/ /*= T_SyntaxTree =============================================================*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node( T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Self const& tree , T_Self const& tree ,
const uint32_t node ) noexcept const uint32_t node ) noexcept
: tree{ tree } , node{ node } : tree{ tree } , node{ node }
@ -19,34 +19,34 @@ T_SyntaxTree< T , S >::T_Node::T_Node(
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node( T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Node const& other ) noexcept T_Node const& other ) noexcept
: tree{ other.tree } , node{ other.node } : tree{ other.tree } , node{ other.node }
{ {
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node( T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Node&& other ) noexcept T_Node&& other ) noexcept
: T_Node( other ) : T_Node( other )
{ {
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =( typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
T_SyntaxTree< T , S >::T_Node const& other ) noexcept T_SyntaxTree< T , L , S >::T_Node const& other ) noexcept
{ {
assert( &other.tree == &tree ); assert( &other.tree == &tree );
node = other.node; node = other.node;
return *this; return *this;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =( typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
T_SyntaxTree< T , S >::T_Node&& other ) noexcept T_SyntaxTree< T , L , S >::T_Node&& other ) noexcept
{ {
assert( &other.tree == &tree ); assert( &other.tree == &tree );
node = other.node; node = other.node;
@ -55,31 +55,33 @@ typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_Node_::T_Node_( T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
const T nodeType , const T nodeType ,
const uint32_t parent ) noexcept const uint32_t parent ) noexcept
: type{ nodeType } , parent{ parent } : type{ nodeType } , parent{ parent } , location{ }
{ {
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_Node_::T_Node_( T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
T_Node_&& other ) noexcept T_Node_&& other ) noexcept
: type{ other.type } , parent{ other.parent } , : type{ other.type } , parent{ other.parent } ,
location{ other.location } ,
children{ std::move( other.children ) } , children{ std::move( other.children ) } ,
data{ std::move( other.data ) } data{ std::move( other.data ) }
{ {
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operator =( typename T_SyntaxTree< T , L , S >::T_Node_& T_SyntaxTree< T , L , S >::T_Node_::operator =(
T_Node_&& other ) noexcept T_Node_&& other ) noexcept
{ {
type = other.type; type = other.type;
parent = other.parent; parent = other.parent;
location = other.location;
children = std::move( other.children ); children = std::move( other.children );
data = std::move( other.data ); data = std::move( other.data );
return *this; return *this;
@ -87,8 +89,8 @@ typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operato
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_SyntaxTree( T_SyntaxTree< T , L , S >::T_SyntaxTree(
const T rootType ) noexcept const T rootType ) noexcept
: nodes_( 64 ) : nodes_( 64 )
{ {
@ -97,17 +99,17 @@ T_SyntaxTree< T , S >::T_SyntaxTree(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >::T_SyntaxTree( T_SyntaxTree< T , L , S >::T_SyntaxTree(
T_SyntaxTree< T , S >&& other ) noexcept T_SyntaxTree< T , L , S >&& other ) noexcept
: nodes_{ std::move( other.nodes_ ) } : nodes_{ std::move( other.nodes_ ) }
{ {
// EMPTY // EMPTY
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =( T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::operator =(
T_SyntaxTree< T , S >&& other ) noexcept T_SyntaxTree< T , L , S >&& other ) noexcept
{ {
nodes_ = std::move( other.nodes_ ); nodes_ = std::move( other.nodes_ );
return *this; return *this;
@ -115,64 +117,71 @@ T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::swap( T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::swap(
T_SyntaxTree< T , S >& other ) noexcept T_SyntaxTree< T , L , S >& other ) noexcept
{ {
using std::swap; using std::swap;
swap( nodes_ , other.nodes_ ); swap( nodes_ , other.nodes_ );
return *this; return *this;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
void swap( T_SyntaxTree< T , S >& lhs , void swap( T_SyntaxTree< T , L , S >& lhs ,
T_SyntaxTree< T , S >& rhs ) noexcept T_SyntaxTree< T , L , S >& rhs ) noexcept
{ {
lhs.swap( rhs ); lhs.swap( rhs );
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
T T_SyntaxTree< T , S >::typeOf( T T_SyntaxTree< T , L , S >::typeOf(
const uint32_t node ) const noexcept const uint32_t node ) const noexcept
{ {
return nodes_[ node ].type; return nodes_[ node ].type;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
uint32_t T_SyntaxTree< T , S >::parentOf( uint32_t T_SyntaxTree< T , L , S >::parentOf(
const uint32_t node ) const noexcept const uint32_t node ) const noexcept
{ {
return nodes_[ node ].parent; return nodes_[ node ].parent;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , S >::childrenOf( T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , L , S >::childrenOf(
const uint32_t node ) const noexcept const uint32_t node ) const noexcept
{ {
return nodes_[ node ].children; return nodes_[ node ].children;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
bool T_SyntaxTree< T , S >::hasData( bool T_SyntaxTree< T , L , S >::hasData(
const uint32_t node ) const noexcept const uint32_t node ) const noexcept
{ {
return bool( nodes_[ node ].data ); return bool( nodes_[ node ].data );
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
template< typename D > template< typename D >
D const& T_SyntaxTree< T , S >::dataOf( D const& T_SyntaxTree< T , L , S >::dataOf(
const uint32_t node ) const const uint32_t node ) const
{ {
return nodes_[ node ].data.template value< D >( ); return nodes_[ node ].data.template value< D >( );
} }
template< typename T , typename L , size_t S >
L const& T_SyntaxTree< T , L , S >::locationOf(
const uint32_t node ) const noexcept
{
return nodes_[ node ].location;
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
uint32_t T_SyntaxTree< T , S >::addChild( uint32_t T_SyntaxTree< T , L , S >::addChild(
const uint32_t parent , const uint32_t parent ,
const E_Node type ) noexcept const E_Node type ) noexcept
{ {
@ -183,9 +192,9 @@ uint32_t T_SyntaxTree< T , S >::addChild(
return idx; return idx;
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
template< typename D , typename ... ArgTypes > template< typename D , typename ... ArgTypes >
D& T_SyntaxTree< T , S >::newData( D& T_SyntaxTree< T , L , S >::newData(
const uint32_t node , const uint32_t node ,
ArgTypes&& ... args ) ArgTypes&& ... args )
{ {
@ -194,18 +203,25 @@ D& T_SyntaxTree< T , S >::newData(
return data.template value< D >( ); return data.template value< D >( );
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
template< typename D > template< typename D >
D& T_SyntaxTree< T , S >::dataOf( D& T_SyntaxTree< T , L , S >::dataOf(
const uint32_t node ) const uint32_t node )
{ {
return nodes_[ node ].data.template value< D >( ); return nodes_[ node ].data.template value< D >( );
} }
template< typename T , typename L , size_t S >
L& T_SyntaxTree< T , L , S >::locationOf(
const uint32_t node ) noexcept
{
return nodes_[ node ].location;
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
template< typename T , size_t S > template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) const noexcept typename T_SyntaxTree< T , L , S >::T_Visitor T_SyntaxTree< T , L , S >::visitor( ) const noexcept
{ {
return T_Visitor{ return T_Visitor{
[this]( T_Node node , uint32_t child ) -> T_Optional< T_Node > { [this]( T_Node node , uint32_t child ) -> T_Optional< T_Node > {
@ -218,8 +234,8 @@ typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) cons
}; };
} }
template< typename T , size_t S > template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , S >::T_Node T_SyntaxTree< T , S >::root( ) const noexcept typename T_SyntaxTree< T , L , S >::T_Node T_SyntaxTree< T , L , S >::root( ) const noexcept
{ {
return T_Node{ *this , 0 }; return T_Node{ *this , 0 };
} }

View file

@ -10,6 +10,7 @@ class SyntaxTreeTest : public CppUnit::TestFixture
CPPUNIT_TEST( testUpdateData ); CPPUNIT_TEST( testUpdateData );
CPPUNIT_TEST( testAddChildren ); CPPUNIT_TEST( testAddChildren );
CPPUNIT_TEST( testVisit ); CPPUNIT_TEST( testVisit );
CPPUNIT_TEST( testLocation );
CPPUNIT_TEST_SUITE_END( ); CPPUNIT_TEST_SUITE_END( );
public: public:
@ -18,6 +19,7 @@ public:
void testUpdateData( ); void testUpdateData( );
void testAddChildren( ); void testAddChildren( );
void testVisit( ); void testVisit( );
void testLocation( );
}; };
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest ); CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
@ -30,7 +32,7 @@ enum class E_TestNode_
VALUE VALUE
}; };
using T_Test_ = T_SyntaxTree< E_TestNode_ >; using T_Test_ = T_SyntaxTree< E_TestNode_ , uint32_t >;
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -139,3 +141,11 @@ void SyntaxTreeTest::testVisit( )
CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) ); CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) );
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) ); CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) );
} }
void SyntaxTreeTest::testLocation( )
{
T_Test_ st{ E_TestNode_::ROOT };
CPPUNIT_ASSERT_EQUAL( 0u , st.locationOf( 0 ) );
st.locationOf( 0 ) = 123;
CPPUNIT_ASSERT_EQUAL( 123u , st.locationOf( 0 ) );
}