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<
// Node type (should be an enum)
typename NodeType ,
// Location type
typename LocationType ,
// Data storage size
size_t InPlaceSize = sizeof( void* )
> class T_SyntaxTree
{
public:
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
= T_VariantExt< InPlaceSize >::StorageSize;
@ -59,6 +62,8 @@ template<
E_Node type;
// Index of the parent node
uint32_t parent;
// Location of the node
T_Location location;
// Indices of the node's children
T_AutoArray< uint32_t , 8 > children;
// Extra data storage
@ -113,6 +118,9 @@ template<
template< typename D >
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
@ -128,6 +136,9 @@ template<
template< typename D >
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
@ -137,8 +148,9 @@ template<
T_Node root( ) const noexcept;
};
template< typename T , size_t S >
void swap( T_SyntaxTree< T , S >& lhs , T_SyntaxTree< T , S >& rhs ) noexcept;
template< typename T , typename L , size_t S >
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 =============================================================*/
template< typename T , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Self const& tree ,
const uint32_t node ) noexcept
: tree{ tree } , node{ node }
@ -19,34 +19,34 @@ T_SyntaxTree< T , S >::T_Node::T_Node(
// EMPTY
}
template< typename T , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Node const& other ) noexcept
: tree{ other.tree } , node{ other.node }
{
// EMPTY
}
template< typename T , size_t S >
T_SyntaxTree< T , S >::T_Node::T_Node(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_Node::T_Node(
T_Node&& other ) noexcept
: T_Node( other )
{
// EMPTY
}
template< typename T , size_t S >
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
T_SyntaxTree< T , S >::T_Node const& other ) noexcept
template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
T_SyntaxTree< T , L , S >::T_Node const& other ) noexcept
{
assert( &other.tree == &tree );
node = other.node;
return *this;
}
template< typename T , size_t S >
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
T_SyntaxTree< T , S >::T_Node&& other ) noexcept
template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
T_SyntaxTree< T , L , S >::T_Node&& other ) noexcept
{
assert( &other.tree == &tree );
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 >
T_SyntaxTree< T , S >::T_Node_::T_Node_(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
const T nodeType ,
const uint32_t parent ) noexcept
: type{ nodeType } , parent{ parent }
: type{ nodeType } , parent{ parent } , location{ }
{
// EMPTY
}
template< typename T , size_t S >
T_SyntaxTree< T , S >::T_Node_::T_Node_(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
T_Node_&& other ) noexcept
: type{ other.type } , parent{ other.parent } ,
location{ other.location } ,
children{ std::move( other.children ) } ,
data{ std::move( other.data ) }
{
// EMPTY
}
template< typename T , size_t S >
typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operator =(
template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , L , S >::T_Node_& T_SyntaxTree< T , L , S >::T_Node_::operator =(
T_Node_&& other ) noexcept
{
type = other.type;
parent = other.parent;
location = other.location;
children = std::move( other.children );
data = std::move( other.data );
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 >
T_SyntaxTree< T , S >::T_SyntaxTree(
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_SyntaxTree(
const T rootType ) noexcept
: nodes_( 64 )
{
@ -97,17 +99,17 @@ T_SyntaxTree< T , S >::T_SyntaxTree(
/*----------------------------------------------------------------------------*/
template< typename T , size_t S >
T_SyntaxTree< T , S >::T_SyntaxTree(
T_SyntaxTree< T , S >&& other ) noexcept
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >::T_SyntaxTree(
T_SyntaxTree< T , L , S >&& other ) noexcept
: nodes_{ std::move( other.nodes_ ) }
{
// EMPTY
}
template< typename T , size_t S >
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
T_SyntaxTree< T , S >&& other ) noexcept
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::operator =(
T_SyntaxTree< T , L , S >&& other ) noexcept
{
nodes_ = std::move( other.nodes_ );
return *this;
@ -115,64 +117,71 @@ T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
/*----------------------------------------------------------------------------*/
template< typename T , size_t S >
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::swap(
T_SyntaxTree< T , S >& other ) noexcept
template< typename T , typename L , size_t S >
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::swap(
T_SyntaxTree< T , L , S >& other ) noexcept
{
using std::swap;
swap( nodes_ , other.nodes_ );
return *this;
}
template< typename T , size_t S >
void swap( T_SyntaxTree< T , S >& lhs ,
T_SyntaxTree< T , S >& rhs ) noexcept
template< typename T , typename L , size_t S >
void swap( T_SyntaxTree< T , L , S >& lhs ,
T_SyntaxTree< T , L , S >& rhs ) noexcept
{
lhs.swap( rhs );
}
/*----------------------------------------------------------------------------*/
template< typename T , size_t S >
T T_SyntaxTree< T , S >::typeOf(
template< typename T , typename L , size_t S >
T T_SyntaxTree< T , L , S >::typeOf(
const uint32_t node ) const noexcept
{
return nodes_[ node ].type;
}
template< typename T , size_t S >
uint32_t T_SyntaxTree< T , S >::parentOf(
template< typename T , typename L , size_t S >
uint32_t T_SyntaxTree< T , L , S >::parentOf(
const uint32_t node ) const noexcept
{
return nodes_[ node ].parent;
}
template< typename T , size_t S >
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , S >::childrenOf(
template< typename T , typename L , size_t S >
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , L , S >::childrenOf(
const uint32_t node ) const noexcept
{
return nodes_[ node ].children;
}
template< typename T , size_t S >
bool T_SyntaxTree< T , S >::hasData(
template< typename T , typename L , size_t S >
bool T_SyntaxTree< T , L , S >::hasData(
const uint32_t node ) const noexcept
{
return bool( nodes_[ node ].data );
}
template< typename T , size_t S >
template< typename T , typename L , size_t S >
template< typename D >
D const& T_SyntaxTree< T , S >::dataOf(
D const& T_SyntaxTree< T , L , S >::dataOf(
const uint32_t node ) const
{
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 >
uint32_t T_SyntaxTree< T , S >::addChild(
template< typename T , typename L , size_t S >
uint32_t T_SyntaxTree< T , L , S >::addChild(
const uint32_t parent ,
const E_Node type ) noexcept
{
@ -183,9 +192,9 @@ uint32_t T_SyntaxTree< T , S >::addChild(
return idx;
}
template< typename T , size_t S >
template< typename T , typename L , size_t S >
template< typename D , typename ... ArgTypes >
D& T_SyntaxTree< T , S >::newData(
D& T_SyntaxTree< T , L , S >::newData(
const uint32_t node ,
ArgTypes&& ... args )
{
@ -194,18 +203,25 @@ D& T_SyntaxTree< T , S >::newData(
return data.template value< D >( );
}
template< typename T , size_t S >
template< typename T , typename L , size_t S >
template< typename D >
D& T_SyntaxTree< T , S >::dataOf(
D& T_SyntaxTree< T , L , S >::dataOf(
const uint32_t node )
{
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 >
typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) const noexcept
template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , L , S >::T_Visitor T_SyntaxTree< T , L , S >::visitor( ) const noexcept
{
return T_Visitor{
[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 >
typename T_SyntaxTree< T , S >::T_Node T_SyntaxTree< T , S >::root( ) const noexcept
template< typename T , typename L , size_t S >
typename T_SyntaxTree< T , L , S >::T_Node T_SyntaxTree< T , L , S >::root( ) const noexcept
{
return T_Node{ *this , 0 };
}

View file

@ -10,6 +10,7 @@ class SyntaxTreeTest : public CppUnit::TestFixture
CPPUNIT_TEST( testUpdateData );
CPPUNIT_TEST( testAddChildren );
CPPUNIT_TEST( testVisit );
CPPUNIT_TEST( testLocation );
CPPUNIT_TEST_SUITE_END( );
public:
@ -18,6 +19,7 @@ public:
void testUpdateData( );
void testAddChildren( );
void testVisit( );
void testLocation( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
@ -30,7 +32,7 @@ enum class E_TestNode_
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( !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 ) );
}